const:
1.c中const修饰的值称为常变量,c++中const定义的是常量值不允许改变
在.c文件中定义了一个const常量a,a的值为10,定义一个指针来保存a的地址,修改*p(地址里面保存的值),此时a的值会被改变,因此在c语言中const修饰的值是可以通过地址改变的
例如:在.c文件中 这样写 const int a =10;
int arr[a]; //error
在编译时要确定数组arr的大小,a的值要去a的地址里面找,但是地址中的a的值可能会被修改,因此不能确定a的值
编译器报的错误:
应输入常量表达式
不能分配常量大小为 0 的数组
“arr”: 未知的大小
这中写法在.cpp文件中就不会出错,a的大小可以确定,因为在编译的时候进行了替换,不用去地址里面找。
c++中const 定义的是常量值不允许改变(可以看成宏定义),编译时候将使用该常量的地方替换成了该常量的值。
2.c++中常量必须初始化;const 修饰的数据产生的符号是local的
.cpp文件中 const int a;a=10;
//没有初始化会报错
在fun.c 中 const int A=100;
main.c中 extern const int A; // errorfatal error LNK1120: 1 个无法解析的外部命令
分析一下无法连接有两个可能:一种是连接不存在,另一种是存在但是用不了。
const 修饰的数据在编译时产生的符号时本地的,只能在所在文件中使用,因此上面那个main.c 就无法使用fun.c中定义的A;因此就会出现上面的错误。
3.c++中的const 会退化成常变量(在编译器无法确定其值时)
列如:int c=20;
const int d=c; //d退化成常变量,在编译时不会替代,而在运行时会去地址里面取值
还有一种情况就是函数的形参如果是常量,那么在调用这个函数时也会退化成常变量
4.const 和指针
const 修饰的类型是离他最近的完整类型,const修饰的内容是属于他修饰类型的内容,const 修饰的内容不允许改变
const int a=10;
const int *p=&a;
*p=20;// error 不允许把常量的地址给非常量的指针
int b=10;
int *p1=&b;
const int *p2=&b; int const *p2=&b ;相同
int *const p3=&b; const 修饰的类型是int * ,内容p3
5.引用:相当于变量的别名
定义引用的表示方法与定义指针相似,只是用&代替了*。引用(reference)是c++对c语言的重要扩充。引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。引用的声明方法:类型标识符 &引用名=目标变量名;
(1)&在此不是求地址运算,而是起标识作用。
(2)类型标识符是指目标变量的类型。
(3)声明引用时,必须同时对其进行初始化。
(4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
int a=2,&ra=a;
a为目标原名称,ra为目标引用名。给ra赋值:ra=1; 等价于 a=1;
(5)对引用求地址,就是对目标变量求地址。&ra与&a相等。即我们常说引用名是目标变量名的一个别名。别名一词好像是说引用不占据任何内存空间。但是编译器在一般将其实现为const指针,即指向位置不可变的指针。即引用实际上与一般指针同样占用内存。
(6)不能建立引用的数组。因为数组是一个由若干个元素所组成的集合,所以无法建立一个由引用组成的集合。但是可以建立数组的引用.
例如: int& ref [3]= {2,3,5};//声明ref引用的数组错误
但是可以这样写:
const int (&ref)[3] ={2,3,5}; //gcc编译的时候加上选项 -std=c++0x
ref[0] = 35; //错误
为什么要加上const ,因为{2,3,5}此时是个字面值数组,是保存在代码段里,只读的属性,如果不加,编译错误,而且后面对ref[0]的赋值也不会成功.
需要特别强调的是引用并不产生对象的副本,仅仅是对象的同义词。因此,当下面的语句执行后:
pt1.offset(12,12);
pt1和pt2都具有(12,12)的值。
引用必须在定义时马上被初始化,因为它必须是某个东西的同义词。你不能先定义一个引用后才
初始化它。例如下面语句是非法的:
Point &pt3;
pt3=pt1;
那么既然引用只是某个东西的同义词,它有什么用途呢?
下面讨论引用的两个主要用途:作为函数参数以及从函数中返回左值。
常引用
常引用声明方式:const 类型标识符&引用名=目标变量名;
用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。
(不允许泄露常量的引用给非常量的引用)
【例】:
int a ;
const int &ra=a;
ra=1; //错误
a=1; //正确
引用参数
传统的c中,函数在调用时参数是通过值来传递的,这就是说函数的参数不具备返回值的能力。
所以在传统的c中,如果需要函数的参数具有返回值的能力,往往是通过指针来实现的。比如,实现
两整数变量值交换的c程序如下:
1 2 3 4 5 6 7 |
|
使用引用机制后,以上程序的c++版本为:
1 2 3 4 5 6 7 |
|
调用该函数的c++方法为:swapint(x,y); c++自动把x,y的地址作为参数传递给swapint函数。
引用一个不可寻址的常量
const int &c=fun(c);//编译器会产生一个临时量供我们引用,用常引用引用一个函数的返回值,说明这个临时量 为常量。
标准类型产生的临时量为常量
自定义类型产生的临时量为非常量
引用单独使用不参与类型
const单独使用不参与类型
const &结合参与类型可形成重载,
const 修饰指针,如果修饰的内内容中没有*,则const 不参与类型
6.c中引用c++
c中引用c++,可把c++的那段代码写成
extern “C” //引用c语言的规则编译下面代码
{
(c++代码)
};
在不知道c++源代码,只知道接口的情况下,也可以引用
extern "C"
{
void fun_creat()
{
c++接口
}
};