1. 类型检查更严格
举个例子,我们都知道,当一个变量定义为const类型后,这个变量的值是不能被改变的,但是在C中,我们可以拐着弯去修改const类型变量的值,如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
对于const类型变量a,我们无法直接再去给它赋值200,但是我们可以定义一个指针变量p来保存a的地址,通过*p
来修改a的值,在C里面这样是可以做到的,这叫明修栈道暗度陈仓。我们再来详细分析一下这个过程,a是个const int
类型,那么取地址后就变成了const int *
类型,也就是说相当于把const int *
类型的变量赋给了int *
类型,把const给干掉了,所以可以对*p
进行赋值了。C中可以随便赋值,这就导致了不严谨。
在C++里,int *p = &a
编译则不会通过,因为无法将const int *
类型的变量赋给了int *
类型,所以既然设定了a为const类型的变量,它就不会让你有修改的机会。C++不喜欢强转,C++会认为你设计有问题。还有个小细节,在定义a的时候,C中可以不赋初值,系统会给一个随机值,而C++中强制你在定义的时候要初始化,这一点在语言的层面上做的就比较友好了。
再举个常见的例子,我们知道malloc函数返回的是void *
类型,在C中,我们可以直接将返回值赋给char *
的变量,但是在C++中,必须转换成char *
类型才可以,如下:
- 1
- 2
- 1
- 2
2. 增加bool类型
在C语言中是没有bool类型的,C中表示真假用的是0和非0。C++中有bool类型,可以使用true和false来表示真和假。但是在C++中,也可以将0和非0赋给bool类型的变量,这点其实C++做的不太严谨,既然有了bool类型,个人觉得只能用true和false去赋值会更好,可读性也更强。
bool类型其实说白了就是个枚举,C中虽然没有,但是我们可以用枚举来定义这个类型。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
C中必须使用typedef才可以直接使用Bool,否则需要加enum来定义,如enum BOOL b = FALSE;
。在C++中,枚举类型可以直接用来定义变量,不需要再加上enum关键字,也不需要使用typedef来重新命名。
3. 真正的枚举
这是什么意思呢?C中的枚举算不上真正的枚举,C 语言中枚举的本质就是整型,枚举变量可以用任意整型来赋值。而C++中枚举变量,只能用被枚举出来的元素去初始化。比如我们定义一个枚举类型:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
在C中我们可以:
- 1
- 2
- 3
- 1
- 2
- 3
但是在C++中:
- 1
- 2
- 3
- 1
- 2
- 3
说个题外话,枚举除了列举一些固定的值以外,还能充当宏的作用。还是上面的例子,如果我们把SEASON去掉,完全可以将枚举中的值作为宏来处理,因为枚举中的值默认是从0开始,也可以手动赋不一样的值,如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
这样会将四个值打印出来,可以完美替代宏去操作了,这也是枚举的一个妙用吧。
4. 表达式可以被赋值
在C中,表达式是不可以被赋值的,但是在C++中,某些表达式是可以被赋值的。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
在C中,表达式的值是可以赋值给其他变量的,比如a=b=5;
是将5赋给b,再将表达式b=5的值赋给a,所以a和b都等于5。但是C中不能将100赋值给表达式(a=b),虽然该表达式的值是a的值,但是不允许这样操作,可在C++中是允许的,最后会打印出a=100 b=5。
5. 输入与输出
在C中我们一般用scanf和printf来输入和输出,在C++中使用cin和cout来输入和输出,这两个有啥区别呢?从语言的角度来说,scanf和printf是函数,cin和cout是类对象,他们有相同的功能而已。举个与C对比的例子:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
使用setw()函数来设定域宽,使用setprecision和setiosflags来设定小数位。使用hex、oct和dec来表示十六进制、八进制和十进制。关于输入输出后面再细写吧。