关于c++ 编译器的与c编译器的区别(c++对c的扩展)
- 1.c++中所有的变量和函数必须有类型,c中的默认类型在c++编译器看来是不合法的。(
变量是内存的别名
) - 2.早期c需要为提升编译速度,会使用register关键字。该关键字作用是直接请求将局部变量存储于寄存器中 ,该关键字声明后不可取地址。
register int a=0;
但是目前c++编译器基本不使用该关键字,原因为c++编译器有自己的编译优化方式,再频繁访问时,会自动声明该关键字,当要访问地址时,该关键字又会被隐藏。 - 3.关于三目运算符,c编译器中 表达式不能做左值,表达式的结果放在寄存器中,是一个值。
而在c++中,表达式返回是一个变量本身,因此c++可以编译通过。
(a < b ? a :b ) = 30
(c中编译不过)。
那么如何让c编译器知道表达式是一个变量呢?让表达式返回一个内存空间,也就是内存首地址,也就是指针。如下:
(a < b ? &a :&b ) = 30
(c也就可以编译过了)。也就是说c++编译器帮助我们做了取地址的操作。 - 4.const关键字。
本质是看const关键字修饰的是指针,还是修饰的内存空间。包括指针常量和常量指针等等
const int a
与int const a
一样。
const int * a
:修饰的是指针指向的内存空间,内存空间不能被修改。
int * const a
:指针变量本身不可以修改。
const int * const a
都不能被修改。
c中的const是“冒牌货”,有自己的内存空间,会存在间接赋值的情况:
c++中const是只读变量编译器会放在一个符号表中,只有在取地址和声明为全局变量的时候才会分配内存空间且该空间和符号表没关系。
const int a = 10;
int * p = null;
p = (int*)&a;
*p = 20;
在c中,上述代码会对a进行间接复制(a会变成20)(通过地址)。
c++中,const是一个真正的常量,这个现象在c++编译器中,const的声明会放在一个符号表中而不是申请内存空间,当你对const int a 取地址的时候,c++编译器会单独申请一个内存空间,由p指向,而后修改p时,修改的是新分配的内存空间,和a没有关系,因此a的值不会被修改。
这里补充下c++中const分配内存的时机:
int a;
cont int b = 10;
int c
std::cout << &a << " " << &b << " " << &c << std::endl;
会发现b的内存是在 a 和c之间的,而不是 a, c ,b。可见c++编译器会先扫描,然后按顺序进行压栈。