C++和C语言之间存在多种不同点,这里对它们之间的不同点进行总结。
- const修饰的量
- 引用与指针
- static关键字
- new与malloc
(一) const修饰的量
a. C中const修饰的量叫常变量,不是常量,不能被修改。不是必须初始化,但是如果不初始化,之后无法赋予合适的值,因此一般进行初始化。
例:const int a=10;
int arr[a]={0}; //error a为常变量
其中常变量与普通变量的唯一区别是常变量定义以后,不能作为左值存在。
例: const int a=10;
int*p=(int *)&a;
*p=30;//true
a=10;//error,a为常变量,不能被修改,不能作为左值存在
b. C++中const修饰的量成为常量,必须初始化。(const编译规则:所有适用常量名字的地方全部替换成常量的初始值)当C++中的常量引用一个编译阶段不明确的值的时候退化成常变量。
例:int b=20;
const int a=b;//此时a为常变量,编译阶段值不明确
int arr[a]={0};//error
引用外部const定义的常量时,在const常量定义处加extern使其生成的符号为global,可供外部文件引用,因为const修饰的常量生成的符号为local,只能在本文件中可见。
(二)C++中引用与C中指针
a. C++中引用必须初始化,初始化的值必须要能取地址, 例:int &a=10;//错误,但是不分配存储空间。C中指针不声明时初始化,在初始化的时候需要分配存储空间。引用相对于指针更加安全,因为指针可指向任意一块内存,可以改变所指的对。
b. 定义引用变量开辟内存,用于存储引用的变量的地址,访问引用变量,永远访问的是他所引用的内存,但无法访问定义引用变量系统开辟的用于记录所引用内存地址的对应字节的内存,一经定义不能被更改。
c. 引用的大小根据所引用的类型确定,指针的大小由编译器位数以及操作系统位数确定
d. 指针使用时必须解引用,并且可以多级引用。
e. 在汇编语言中,定义一个指针和引用相同,将变量的地址移入eax寄存器中,再将变量的地址存放在b或者p中,保存变量的地址。
f. 指针可以指向空值。
例1: int a=10; //定义整型常量a
int &b=a; //引用变量b:取地址符号前面有类型,引用符号紧跟变量名
int *p=&a; //定义整型指针
b=20; //引用变量赋值
*p=20; //指针变量
例2:
float a=10.5;
int b1=(int)a;
int b2=(int)&a;
int b3=(int &)a;
(三)static关键字
在非类中:
a. static修饰的全局变量表示静态全局变量,已经初始化的放在 .data段 ,未初始化的放在 .bss段内,初始化的时候自动初始化为0,并且只在定义它的文件中可见,其他文件无法访问该变量。
b. static修饰的局部变量整个进程生命周期都存在,程序结束时释放。每次调用这个变量时,其初始值都是上一次调用时修改的结果。
在类中:
c. static除了用来修饰局部静态变量和外部静态变量、函数以外,还可以用来定义类的成员变量和函数。即静态数据成员和静态成员函数。其中所有对象共享数据成员或者成员函数。static关键字只能用于类内部的声明,不能用于类外部的定义。
d .static成员函数没有this形参(因为不属于某个对象),可以直接访问static数据成员,不能直接使用非static成员。
e.static成员函数不能声明为const,因为const成员函数真正的含义是不修改该成员函数所属的对象,而static成员函数不属于任何对象。static成员函数不能声明为虚函数!
f. static不是对象的组成部分,只是类的组成部分
g. C中static用来修饰局部静态变量和外部静态变量、函数
(四)动态内存的开辟C中malloc和C++中new
a. C中开辟动态内存malloc与free搭配使用,释放内存。
b. C++中new与delete同时使用,new调用malloc,相对于malloc,new除了有开辟内存的功能,还有初始化的功能对于内置类型,调用构造函数对于自定义函数。
c. delete不同于free,先进行析构,在free释放内存。
例: int *p=(int *)malloc(sizeof(int));
free(p);
int *p=new int(10);
delete p;
int *p=(int *)malloc(sizeof(int)*100);
free(p);
int *p=new int[100]; //开辟长度为100的数组
delete []p;
例:动态开辟3*4二维数组
int **p=new int *[3];
for(int i=0;i<3;++i)
{
p[i]=new int[4];
}
for(int i=0;i<3;++i)
{
delete []p[i;]
}
delete []p;
// int **p=new int[3][4]; //error 无法从“int (*)[4]”转化为“int **”