關於C/C++ const變數 const指標 以及C++ 引用變數的解析

gaopengtttt發表於2016-06-02
 關於C/C++ const變數 const指標 以及C++ 引用變數的解析
 
 首先我們知道const表示一個不能更改的值,在程式中往往使用這種屬性來保證安全,但是這種操作在C和C++中卻不同
 我測試中C++不能用MEMCPY進行更改但是C卻可以
 其中我們常見的
 const int a = 10;一個常量,不能更改其a的值
 const int *p1;一個指標但是他的返回值是const int型別
 如我們可以
 p = &a;
 int* const p;一個指標,這個指標在整個生命週期中不能指向其他位置。
 const int* const p;一個指標,這個指標在整個生命週期中不能指向其他位置,並且返回為const int型別
  我們在函式中也經常使用const
 const int* mul(const int *data,int step)
 const int *data:*data指向的值在函式中不能更改
 const int* mul:函式的返回值為一個const int型別
 
 另外C++中包含一個引用變數概念
 如
 const int a = 10;
 const int & b =a;
 這裡&不是取地址,而是他是一個引用變數,b和a完全相同,不是拷貝,而是同樣的型別同樣的指標
 如果要用CONST描述就是
 const int* const b 和 &a相似
 b指標在生命週期中不能更改。也就是說int a=5; int &b=a;那麼b就不能在引用其他變數了。而指標不加int* const的情況下是可以的
但是如果int c=10; b=c; 那麼a和引用b都會變為10,也就是說引用是一個別名,對他的複製最終會影響他指向變數的值,因為他們的記憶體
區域是一塊。
!!引用只能被初始化,並且必須初始化。

引用和指標區別
1、引用不能為空
2、new分配記憶體時只能返回給指標不能給引用
3、指標可以重新被賦值改變指標的地址,引用必須初始化初始化後不能再次改變其引用的物件。
4、當函式返回為按值後  主函式接收為引用則這個副本物件會被引用的生命週期更長然後析構,但是指標則是直接析構。
這一點過後講述

 下面是一個演示程式
 
  1 /*************************************************************************
  2   > File Name: quotevar.cpp
  3   > Author: gaopeng
  4   > Mail: gaopp_200217@163.com 
  5   > Created Time: Fri 27 May 2016 07:47:34 AM CST
  6  ************************************************************************/
  7 
  8 #include
  9 #include
 10 using namespace std;
 11 
 12 
 13 
 14 int main(void)
 15 {
 16     const int a = 10;
 17     const int & b =a;
 18     const int* const p = &a;
 19     const int *p1 = &a;
 20     cout << a <<endl;
 21     cout << b <<endl;
 22     cout << *p <<endl;
 23     cout << &a <<endl;
 24     cout << &b <<endl;
 25     cout << p  <<endl;
 26     cout << p1  <<endl;
 27 
 28     const int c = 20;
 29     p1 = &c; //true p1 is a nomarl pointer but *p1 is a const value
 30     //b = 30;    error a is const value b also is a const value
 31     //a = 30;    error a is const value
 32     //p = &c;    error p is a const pointer
 33     cout << &b  <<endl;
 34     cout << &c  <<endl;
 35     cout << p1  <<endl;
 36     // --part 2 memcpy also cant't change const int a's value
 37     int d = 10;
 38     int *e = &d;
 39     char j = 'A';
 40     void *p2;
 41     void *p3;
 42     const void *p4 = (const void *)(&j);
 43     p2 = (void *)(p);
 44     p3 = (void *)(e);
 45     if ( p2 == memcpy(p2,p4,1))
 46     {
 47         cout << "memcpy p2 is finsh!"<<endl;
 48     }
 49 
 50     if (p3 == memcpy(p3,p4,1))
 51     {
 52         cout << "memcpy p3 is finsh!"<<endl;
 53     }
 54 
 55     cout << a <<endl;
 56     cout << &a <<endl;
 57     cout << d <<endl;
 58     cout << &d <<endl;
 59     cout << p2 <<endl;
 60     cout << p3 <<endl;
 61 }  
 
 返回值為
10
10
10
0x7ffd421b4ffc
0x7ffd421b4ffc
0x7ffd421b4ffc
0x7ffd421b4ffc
0x7ffd421b4ffc
0x7ffd421b5000
0x7ffd421b5000
memcpy p2 is finsh!
memcpy p3 is finsh!
10
0x7ffd421b4ffc
65
0x7ffd421b5004
0x7ffd421b4ffc
0x7ffd421b5004
使用的g++
可以看到完全的a和b有同樣值有同樣的地址,同時const 變數memcpy不能修改他的值,而普通的變數卻可以。
但是這個結論不適用於C
使用gcc
10
10
10
0x7ffc9a13a2bc
0x7ffc9a13a2bc
0x7ffc9a13a2bc
0x7ffc9a13a2bc
0x7ffc9a13a2bc
0x7ffc9a13a2c0
0x7ffc9a13a2c0
memcpy p2 is finsh!
memcpy p3 is finsh!
65
0x7ffc9a13a2bc
65
0x7ffc9a13a2c4
0x7ffc9a13a2bc

可以看到memcpy更改了const變數的值,這應該來說是不安全,申明const就是要說明不能更改。

c程式如下:
#include
#include
#include

int main(void)
{
        const int a = 10;
        const int* const b =&a;
        const int* const p = &a;
        const int *p1 = &a;
        printf("%d\n",a);
        printf("%d\n",*b);
        printf("%d\n",*p);
        printf("%p\n",&a);
        printf("%p\n",b);
        printf("%p\n",p);
        printf("%p\n",p1);

        const int c = 20;
        p1 = &c; //true p1 is a nomarl pointer but *p1 is a const value
        //b = 30;    error a is const value b also is a const value
        //a = 30;    error a is const value
        //p = &c;    error p is a const pointer
        printf("%p\n",b);
        printf("%p\n",&c);
        printf("%p\n",p1);
        // --part 2 memcpy also cant't change const int a's value
        int d = 10;
        int *e = &d;
        char j = 'A';
        void *p2;
        void *p3;
        const void *p4 = (const void *)(&j);
        p2 = (void *)(p);
        p3 = (void *)(e);
        if ( p2 == memcpy(p2,p4,1))
        {
                printf("%s\n","memcpy p2 is finsh!");
        }

        if (p3 == memcpy(p3,p4,1))
        {
                printf("%s\n","memcpy p3 is finsh!");
        }
    
        printf("%d\n",a);
        printf("%p\n",&a);
        printf("%d\n",d);
        printf("%p\n",&d);
        printf("%p\n",p2);
        printf("%p\n",p3);
}



</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;
</endl;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2113049/,如需轉載,請註明出處,否則將追究法律責任。

相關文章