今天我们来谈讨下const分别在C和C++下的区别
C语言中的常变量的不可以定义数组。因为C中的常变量和变量唯一的区别是不能作为左值,其他性质都和变量一样。
eg:
在.C中,有三种修改const常变量值的方式:int b=20;
const int a= 10;1) int *p=&a;
*p=20;2) _asm
{mov dword[ebp-8] 14h}3) *(&b-1)=20;
C语言中可以引用外部const变量声明/定义,会生成一个global符号。链接器在连接的时候,只看g符号。而在其前加上static,就会变为local。除了外部常量,外部变量产生的符号也是g。
2 . C++中的常变量可以作为数组的下标,可以定义数组。常变量是常量。但是在某些情况下,会退化为 变量。
C++中常变量在编译阶段所有出现常量名字的地方会被常量值替换,但不会替换类似&a表达式中的a,当a是const常量时。而C中的常变量在编译阶段并不会被替换。
C++中不可以引用外部文件定义的常量,因为产生的是local符号
因为替换的时候只能在当前文件中替换。如果要能被外部引用到,在变量定义时加上一个extern,就可将其链接属性变为global.
当一个常变量的初始值为外部定义的值时,此时常量就会退换成常变量。因为编译阶段不知道初始值,链接时才知道有这个符号的定义,运行时才会赋值。那么常量的所有汇编也都会变成和变量一样。
3.const 和一级指针的结合
当const修饰一个变量名时,并不是意味着这个变量所占的内存是const,而是不能通过这个名字对其修改或泄露常量内存地址或引用。
4.const和二级指针的结合
下面这个没问题。
当const和指针结合时,若const右边无指针时,有没有const无区别。因此不能构成重载。
当对实参的值有影响时,才会构成重载。下面这个就可以构成重载。
类型转换总结:
5.引用
引用就是一个指针,无论是什么时候占四个字节。
C++中一个空类占一个字节(不同编译器不一样,有的不可以定义)
struct
{
char a;
char b;
char c;
}data;
sizeof(data)=3
6.const 和* &的结合
引用在使用时自动解引用
sizeof(p)=16 (引用了一个数组)
sizeof(p)=16
如果不好直接写引用,可以在写的时候可以先写成一个函数指针(引用数组名),然后改为引用
在这个内存地址上写一个四字节的整数10
int p=(int )0x0018ff44
*p=10;
要想定义一个引用变量,如果右边地址不可取,就弄一个常引用
int const &p=(int )0x0018ff44
*p=10;
下面的错误,是vc的一个bug,编译器检测不出泪,vs可以检测出来
相当于将int**转化为一个const int *,从引用角度来看,p和q是同一块内存,int 和const int *不能是同一块内存。所以错误
错误, p是一个const常量,由于*q=p,所以最后一句应改为
int *const*q=&p;
由于*q<->p,因此给*q赋一个整型常量的地址也就是相当于给p附一个整型常量地址,但是这样会使得整型常量地址泄露,因此修改的办法有两种防止地址泄露被修改:
1)
让*p为常量,防止它被赋值。
2)
禁止*q的改变,达到给p赋值的目的
C++11中出现了左引用和右引用。
引用占内存,四个字节,&b打印出来就是a的地址,引用地址就是所引用变量的地址,使用引用时,自动解引用。