一、C与C++的关系
1. C++继承了所有的C特性;
2. C++在C的基础上提供了更多的语法和特性;
3. C++的设计目标是运行效率与开发效率的统一;
二、C++对C的加强
1. C++中更强调语言的“实用性”,所有的变量都可以在需要使用时再定义。
//1-1.cpp
#include <stdio.h>
int main(int argc, char *argv[])
{
int c = 0;
printf("Begin...\n");
for(int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
{
c += i * j;
}
}
printf("c = %d\n", c);
printf("End...\n");
printf("Press enter to continue ...");
getchar();
return 0;
}
用C编译器编译上述demo,会出现如下错误,该错误的意思是:只允许在C99模式下使用‘for’循环初始化声明。C++对该特性做了加强,可以这样使用。
2. register关键字的变化
register关键字请求“编译器”将局部变量存储于寄存器中
1. C语言中无法取得register变量地址,只能获取内存的地址
在C++中依然支持register关键字
1. C++编译器有自己的优化方式,不使用register也可能做优化
2. C++中可以取得register变量的地址
C++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效。
早期C语言编译器不会对代码进行优化,因此register变量是一个很好的补充。
//1-2.cpp
#include <stdio.h>
int main(int argc, char *argv[])
{
register int c = 0;
printf("Begin...\n");
printf("&c = %08X\n", &c);
printf("End...\n");
printf("Press enter to continue ...");
getchar();
return 0;
}
通过C编译器编译1-2.cpp程序,会出现如下错误,说明当一个变量用register关键字修饰的时候,C编译器会将它进行优化,优化之后不能在获取到它的地址。
通过C++编译器编译1-2.cpp程序,可以正常的编译运行。这也说明了C++对register关键字做了优化。即 C++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效。
3. 全局变量的定义
1. 在C语言中,重复定义多个同名的全局变量是合法的
C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上。
2. 在C++中,不允许定义多个同名的全局变量
C++直接拒绝这种二义性的做法。
//1-3.cpp
#include <stdio.h>
int g_var;
int g_var = 1;
int main(int argc, char *argv[])
{
printf("Begin...\n");
printf("g_var = %d\n", g_var);
printf("End...\n");
printf("Press enter to continue ...");
getchar();
return 0;
}
通过C编译器编译运行,结果如下所示:
通过C++编译器编译运行,结果如下所示:
C语言中的const
1. const修饰的变量是只读变量,本质还是变量;
2. const修饰的局部变量在栈上分配空间;
3. const修饰的全局变量在只读存储区分配空间;
4. const只在编译期有用,在运行期无用;
const修饰的变量不是真的常量,它只是告诉编译器该变量不能出现在赋值符合的左边。
4. C++编译器对const常量的处理
1. 当碰见常量声明时在符号表中放入常量
2. 编译过程中若发现使用常量则直接以符号表中的值替换
3. 编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间
注意:C++编译器虽然可能为const常量分配空间,但是不会使用其存储空间中的值。
//1-4.cpp
#include <stdio.h>
int main(int argc, char *argv[])
{
const int c = 0; //常量c放入到符号表中,不会分配空间
int* p = (int*)&c; //为c分配空间
printf("Begin...\n");
*p = 5;
printf("c = %d\n", c); //从符号表中取出数据
printf("End...\n");
printf("Press enter to continue ...");
getchar();
return 0;
}
通过C++编译器编译运行,结果如下所示:
是不是看到这样的结果有点奇怪?现在我们来分析下这段代码,首先定义了一个const的整形常量c,还定义了一个整形指针p,并且指针p指向了c,然后执行了*p=5。在C语言中我们知道,这个时候c的值就改为5了。那为什么C++中就不一样了呢?这是因为C++编译器做了优化。C++中,当碰见常量声明时在符号表中放入常量,C++编译器编译过程中若发现使用常量则直接以符号表中的值替换。通过刚才的分析,出现上述这样的结果就不觉得奇怪了。
C语言中的const变量
C语言中const变量是只读变量,有自己的存储空间。
C++中的const常量
当const常量为全局,并且需要在其它文件中使用,分配存储空间。
当使用&操作符取const常量的地址,分配存储空间。
//1-5.cpp
#include <stdio.h>
int main(int argc, char *argv[])
{
const int a = 1;
const int b = 2;
int array[a + b] = {0};
int i = 0;
for(i=0; i<(a+b); i++)
{
printf("array[%d] = %d\n", i, array[i]);
}
printf("Press enter to continue ...");
getchar();
return 0;
}
现在我们来分析下这段代码,C编译器中是否能成功运行呢?C语言好的朋友知道,当我们定义一个数组的时候,数组的下标不能是变量,所以这段代码通过C编译器编译是不会通过的。当通过C++编译器编译这段代码的时候,C++编译器检查到a和b都是const常量,则将a+b的结果计算后赋值给数组array的下标。C++编译器编译运行结果如下:
C++中的const常量类似于宏定义
const int c = 5; ≈ #define c 5
C++中的const常量在与宏定义不同
const常量是由编译器处理的,提供类型检查和作用域检查
宏定义由预处理器处理,单纯的文本替换
//1-6.cpp
#include <stdio.h>
void f()
{
#define a 3
const int b = 4;
}
void g()
{
printf("a = %d\n", a);
//printf("b = %d\n", b);
}
int main(int argc, char *argv[])
{
f();
g();
printf("Press enter to continue ...");
getchar();
return 0;
}
这段代码,主要是用来学习下C++中const常量和宏定义的区别。运行结果如下:
5. struct类型的加强
C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型
C++中的struct是一个新类型的定义声明
//1-7.cpp
#include <stdio.h>
struct Student
{
const char* name;
int age;
};
int main(int argc, char *argv[])
{
Student s1 = {"wzb", 27};
Student s2 = {"Wang", 27};
printf("Press enter to continue ...");
getchar();
return 0;
}
C编译器编译运行1-7.cpp结果如下:
C++编译器编译运行1-7.cpp结果如下:
6. 函数和变量类型的加强
C++中所有的变量和函数都必须有类型
C语言中的默认类型在C++中是不合法的
问题:
1.函数f的返回值是什么类型,参数又是什么类型?
2.函数g可以接受多少个参数?
//1-8.cpp
#include <stdio.h>
f(i)
{
printf("i = %d\n", i);
}
g()
{
return 5;
}
int main(int argc, char *argv[])
{
printf("Begin...\n");
f(10);
printf("g() = %d\n", g(1,2,3,4,5));
printf("End...\n");
printf("Press enter to continue ...");
getchar();
return 0;
}
int f(); 与 int f(void); 的区别是什么?
在C语言中
int f();表示返回值为int,接受任意参数的函数
int f(void);表示返回值为int的无参函数
在C++中
int f();和int f(void)具有相同的意义,都表示返回值为int的无参函数
7. C++中的布尔类型
1. C++在C语言的基本类型系统之上增加了bool类型;
2. C++中的bool可取的值只有true和false;
3. 理论上bool类型只占用一个字节,如果多个bool变量定义在一起,可能会各占一个bit,这取决于编译器的实现。
true代表真值,编译器内部用1来表示
false代表非真值,编译器内部用0来表示
//1-9.cpp
#include <stdio.h>
int main(int argc, char *argv[])
{
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);
printf("Press enter to continue ...");
getchar();
return 0;
}
通过C++编译器运行结果如下:
bool类型只有true(非0)和false(0)两个值
C++编译器会在赋值时将非0值转换为true,0值转换为false
//1-10.cpp
#include <stdio.h>
int main(int argc, char *argv[])
{
bool b = false;
printf("b = %d\n", b);
b++;
printf("b = %d\n", b);
b = b + 1;
printf("b = %d\n", b);
printf("Press enter to continue ...");
getchar();
return 0;
}
通过C++编译器运行结果如下: