c和c++区别 —(2)

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

void swapint(int *a,int *b)

{

int temp;

temp=*a;

*a=*b;

*b=temp;

}

使用引用机制后,以上程序的c++版本为:

1

2

3

4

5

6

7

void swapint(int &a,int &b)

{

int temp;

temp=a;

a=b;

b=temp;

}

调用该函数的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++接口

        }

};

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值