C与C++的关系
1.C++继承了所有的C特性
2.C++在C的基础上提供了更多的语法和特性
3.C++的设计目标是运行效率与开发效率的统一
C++对C的加强
1.C++中更强调语言的“实用性”,所有的变量都可以在需要使用的时候再定义
for(int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
{
//C编译器会报错: 'for' loop initial declarations are only allowed in C99 mode
} //C++编译器不报错
}
注意:C语言中的变量都必须在作用域开始的位置定义!!
2.register关键字的变化
.register关键字请求“编译器”将局部变量存储于寄存器中
C语言中无法取得register变量地址
在C++中依然支持register关键字
C++编译器有自己的优化方式,不使用register也可能做优化
C++中可以取得register变量的地址
C++编译器发现程序中需要取register变量的地址时,register对变量的声明变的无效,变量会退化为普通变量
早期C语言编译器不会对代码进行优化,因此register变量是一个很好的补充
register int c = 0;
printf("&c = %08X\n",&c); // C编译器会报错:address of register variable 'c' requested;
//C++编译器不报错
3.C语言中重复定义多个同名的全局变量是合法的
C++中不允许定义多个同名的全局变量
C语言中多个同名全局变量最终会被链接到全局数据区的同一个地址空间上
C++直接拒绝这种二义性的做法
int g_var;
int g_var = 1; //C编译器不报错
//C++编译器报错: 'int g_var' previously declared here
4.C++编译器对const常量的处理(C语言中const声明的是只读变量,C++中const声明的是常量)
当碰见常量声明时在符号表中放入常量
编译过程中若发现使用常量则直接以符号表中的值替换
编译过程中若发现对const使用了extern或者&操作符,才会给对应的常量分配存储空间
注意:C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值,而是用符号表中的值
const int c = 0;
int* p = (int*)&c;
*p = 5;
printf("c = %d\n",c); //C编译运行输出5,C++编译运行输出0
C语言中的const变量
C语言中const变量是只读变量,有自己的存储空间
C++中的const常量
可能分配存储空间
.当const常量为全局,并且需要在其它文件中使用(extern)
.当使用&操作符取const常量的地址
const int a = 1;
const int b = 2;
int array[a + b] = {0}; //C编译器报错: variable-sized object may not be initialized,因为a,b是局部变量,其值在运行时才确定,编译过程中C编译器不会知道a,b具体的值,
//故编译器没法知道数组大小所以报错
//C++编译器不报错,发现a,b是常量,放入符号表,到这一步直接到常量表把a,b的值取出来相加
C++中的const小结
.C++中const常量类似于宏定义
const int c = 5; ≈ #define c 5
.C++中的const常量与宏定义不同
.const常量是由编译器处理的,提供类型检查和作用域检查
.宏定义由预处理器处理,单纯的文本替换
void f()
{
#define a 3
const int b = 4; //如想将a作用域在f()宏,后面加上#undef
}
void g()
{
printf("a = %d\n", a); //输出a=3,因为预处理宏定义文本替换后为printf("a = %d\n", 3);
printf("b = %d\n", b); //报错,因为b的作用域在f()中
}
5.struct类型的加强:
.C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型
.C++中的struct是一个新类型的定义声明
struct Student
{
const char* name;
int age;
};
int main(int argc, char *argv[])
{
Student s1 = {"fuck",30}; //C编译器报错:unknown type name 'Student',C编译器不认为定义了新类型,只认为上面定义了一个变量的集合
Student s2 = {"you",20}; //C++编译器不报错
...
}
6.C++中所有的变量和函数都必须有类型
C语言中的默认类型在C++中是不合法的
f(i) //C语言中等价于int f(int i),C++中报错
{
printf("i=%d\n",i);
}
g() //C语言中等价于int g(),C++中报错
{
return 5;
}
int main(int argc, char *argv[])
{
f(10);
printf("g() = %d\n",g() ); //此处g()改为g(1,2,3,4) 或g(4,6,7,...),g()中任意个参数C编译器都能通过
return 0;
} //C编译器编译运行通过
7.int f(); 与int f(void); 区别
在C语言中
int f();表示返回值为int,接受任意参数的函数
int f(void);表示返回值为int的无参函数
在C++中
int f();和int f(void);具有相同的意义,都表示返回值为int的无参函数
8.C++中的布尔类型
C++在C语言的基本类型系统之上增加了bool
C++中的bool可取的值只有true和false
理论上bool只占用一个字节,如果多个bool变量定义在一起,可能会各占一个bit,这取决于编译器的实现
Tip:true代表真值,编译器内部用1来标示
false代表非真值,编译器内部用0来标示
bool类型只有true(非0)和false(0)两个值
C++编译器会在赋值时将非0值转换为true,0值转换为false
例:
int a;
bool b = true;
printf("b = %d, sizeof(b) = %d\n",b,sizeof(b));
b = 3;
a = b;
printf("a = %d, b = %d\n",a,b);
b = -5;
a = b;
printf("a = %d, b = %d\n",a,b);
a = 10;
b = a;
printf("a = %d, b = %d\n",a,b);
b = 0;
printf("b = %d\n",b); //结果如下:
例:bool类型变量参与数学运算
bool b = false;
printf("b = %d\n",b);
b++;
printf("b = %d\n",b);
b = b + 1;
printf("b = %d\n",b); //输出如下:
9.三目运算符的升级
C语言中的三目运算符返回的是变量值,不能作为左值使用
C++中的三目运算符可直接返回变量本事,因此可以出现在程序的任何地方
int a = 1;
int b = 2;
(a < b ? a : b) = 3; //C编译器报错,C++编译器正常通过
printf("a = %d, b = %d\n", a,b); //输出:a = 3, b = 2
如果改为 (a < b ? 1 : b) = 3; 则C++编译器也会报错,因为
注意:三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用
小结
C++以C语言为基础进行了加强
.C++更强调实用性,可以在任意的地方声明变量
.C++中的register只是一个向后兼容的作用,C++编译器能够进行更好的变量优化
.C++中的const是一个真正意义上的常量,而不是只读变量
.C++更加强调类型,任意的程序元素都必须显示指明类型