C与C++中的二等公民

在原来的C语言中,enum、const、auto等关键字都不尽完善,并没有发挥应有的功能,是二等公民,而随着时间的推移,在C++中他们都被完善了,有些还被赋予了新的功能,担当起了重要的角色。相反,原本在成员中称王称霸的一等公民,比如macro宏,在C++中成了贱民,惨遭抛弃。下面我们来仔细看看各种情况。

1,enum

此关键词可以用来定义所谓枚举类型,枚举的本质含义是一种取值范围受限的整型,比如颜色规定为红橙黄绿青蓝紫七色,那么就可以使用数字0-6来指代,再比如进程状态规定为睡眠、运行、暂停、死亡等,可以分别使用0-3的数字来指代,在C++中,可以使用以下代码来达到以上目的:

enum spectrum {red, orange, yellow, green, blue, cyan, purple}; enum spectrum color; color = red; // 正确 color = 1; // 错误

上述代码体现了C++中枚举的用法,第一行定义了一个范围从red到purple的枚举整数类型spectrum,这里的red默认是0,后续的枚举常量以此递增。第二行中我们使用该类型定义了一个枚举变量color,color的取值范围只能是七色之一,不能是别的,因此直接将1赋值给color是错误的,即使这么做数值上无可厚非,但却破坏了枚举的可读性,被C++语法规则所不允许。

2,const

在C语言标准中,const关键字的作用被描述为模棱两可的“只读变量”的意思,使用const修饰的变量无法再次赋值,但却又不被认为是常量(比如无法在case语句总使用),因此单独使用const来修饰一个普通变量的情况,在C语言中几乎是绝迹。在C语言中const几乎唯一的作用是:修饰一个指针,比如:

char *strncpy(char *dest, const char *src, size_t n);

这样的const的作用就是对指针的访问权限进行限制,使其只保留读操作权限,被剥夺写操作权限,让代码更安全。

在C++中,const关键字被赋予更多有益的功能,去掉含糊不清的概念。其功能总结如下:

第一,定义具有类型的常量,用来替代宏,比如:

const float PI = 3.1415;

以上定义语句比宏定义要好,因为具备类型检测,相反,宏定义没有类型检测,在C++代码中不再被推崇。

第二,用以区分函数特征标。在C++中,函数都可以重载,函数本身使用const来修饰,或者某个参数使用const来修饰,都能使得函数的特征标发生改变,从而可以被重载,比如在每个类A中,可以定义两个重载的成员方法:

void A::f(); void A::f()const;

以上两个函数将被视为重载,其中const版本的函数只能有const常对象来调用,比如:

A a; // 此处定义了一个普通对象a const A b; // 此处定义了一个const对象b a.f(); // 此时调用的是 A::f() 版本 b.f(); // 此处调用的是 A::f()const 版本

第三,用来提高程序的健壮性和执行效率,做法是将所有不需要修改其值的变量统统用const来修饰,简而言之,就是能用const的地方尽量都用const。这点跟C语言的一致。比如在上述的strncpy函数中,由于不需要修改src指针的值,因此使用const来修饰。

3,auto

在C语言中,auto几乎是废弃的,因为它的含义是使得局部变量存储在栈中,即成为所谓自动变量(区别于静态变量)。而C语言的语法又规定,局部变量的默认存储区域就是栈,因此auto就是鸡肋,逐渐被遗弃。

int f(void) { int a; auto int b; static int c; }

上述代码完整体现了为什么C语言中auto被遗弃,a是一个不加任何存储类修饰的局部变量,默认就存放在栈内存,代表其生命周期是临时性的。变量b跟a完全一样,auto就是它们默认的存储类修饰符。变量c则不同,它被存储于静态数据区,代表其生命周期与整个程序相同。

在C++中,auto被赋予了权限的含义,也更契合其名字:自动。C++中的auto意味着“自动类型推导”,请看以下例子:

int a; auto b = a;

定义b的时候,如果无法事先确定b的类型,但可以由赋值的数据的类型来自动匹配,此时就是auto派上用场的实际,上面的例子比较简单,在一些模板类、模板函数的设计中,auto关键字可以起到事半功倍的效果。

4,#define

在C语言中,尤其在Linux内核代码中称王称霸的宏定义,在C++中不受待见,虽然宏运行速度快,但由于其他的诸多缺点,功不抵过,最终还是被抛弃,被const常量、inline函数等替代。宏定义的缺点有:

第一,无法确定类型。这在上面将const常量提过,无法确定类型的宏定义不管是对人还是对机器,都没有什么好处。

第二,复杂带参宏的逻辑难以理解,尤其是当参数是比较复杂的表达式时。

C++为了保留宏的优点(直接在代码调用出展开,无需跳转)发明了内联函数,内联函数本身是函数,因此不存在宏参数无类型、无语法检测等缺点。同时,内联函数在编译阶段(而不是预处理阶段)将代码直接插入调用的地方,实现无需跳转的特性,因此又具有了宏执行快速的优点。

C++语言还有更多有意思的特性等待我们去探索,它是一门超级语言联邦工具,难学易用,坚持到底终会见到阳光。

本文分享自微信公众号 - 秘籍酷(mijiku040)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-11-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券