关于C/C++ const变量 const指针 以及C++ 引用变量的解析

 关于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;
上一篇:循序渐进学编程


下一篇:深入理解Docker Volume(一)