一、constconst的应用是一个老生常谈的技术点。前面反复的分析很多次包括最新的const的扩展等等。但const应用几乎是贯穿着所有开发的应用的。可以这样说只要稍微大一些的程序都会用到const关键字即使开发者自己不使用调用的库或第三方的接口中大概率也会存在。const不仅仅是一种常量的限定关键字更是作为一种代码级别的安全机制为各类开发人员所重视。二、c和c中const的应用在c/c中const的应用非常广泛。从函数、对象、函数参数到变量等都可以看到const关键字的影子。如果开发者只是在c/c中任何单一一个环境中使用const其出现问题的可能性都不大。但问题往往是由于c对c的兼容性导致很多开发者稀里糊涂的就把c/c混合编程了。这种应用到最后就出现一个问题如果C的代码恰好也符合C的规范那么用C编译器编译可能就没有问题但如果用C的编译器来编译就有可能出现问题。这对于老油条们来说可能很快就定位出来了问题的原因。但对于一些新手或不太熟悉此方面的技术点的开发者来说可能就得大费一番周章甚至觉得不可思议遇到了玄学问题。三、二者的区别对于c/c中const应用的主要不同可以从以下几点来分析功能范围不同这个属于C和C语言的范畴比如支持类内成员函数的const,类内无法static与const共同使用等等这个不是重点初始化不同C语言允许对常量不进行初始化但C则要求必须进行初始化类成员允许使用列表初始化常量表达式的限定不同C语言中const只代表只读不是真正的常量这意味着可以利用一些技巧绕过只读限制而C中则是真正的常量。所以前者不能作为数组之类的大小限定或switch中的case标签使用但C则可以链接属性不同如果说前面的两个点即使出现问题也很容易解决的话这点就是挖坑的典型代表了。在C语言中全局const默认的链接属性是外部链接可以为其它编译单元访问而C中则为内部链接仅在当前文件可见。那么想要让外部的其它编译单元看到则必须显式的使用extern来标记相关常量当然在其它的一些细节上比如对指针的限定C限定更严格以及对返回值的限定上C有一些特有的功能如常函数等也存在着一些微小的不同。但整体上来看几乎可以认为是一致的。这里就不再展开分析有兴趣可以查找一下相关的资料认真分析一下。四、例程下面看一个例程如果能明白这个例程的意义就可以明白上面对c/c中const的区别中的第四点有一个清醒的认识//main.cpp#includestdio.h// 其它编译单元const变量externconstintkInit;intmain(){printf(reference kInit %d\n,kInit);return0;}//extern_demo.cpp// 定义const变量/*extern*/constintkInit100;大家可以分别使用C或C的编译器自己去试一下大家可以看看用gcc编译如果不修改文件后缀名会怎么样看看有什么区别编译错误会不会消失或者打对extern的注释同样也是没有问题的。那么如何才能查看这个属性呢其实有很多的工具可以利用比如使用nm命令前面对其有过详细分析说明# 1. C编译 gcc -o main main.c extern_demo.c nm main|grep kInit 0000000000002018 R kInit # 2. C编译extern解注释 g -o m main.cpp extern_demo.cpp nm m |grep kInit 0000000000002018 R kInit # 3. C编译extern注释 编译无法通过报main.cpp.o: in function main: undefined reference to kInit # 4. C直接编译extern_demo.cpp为中间文件 g -c extern_demo.cpp nm extern_demo.o|grep kInit 0000000000000000 r _ZL5kInit有没有发现如果在C的编译中不使用extern关键字变量kInit前面是一个小写r而在C语言及增加extern关键字后其前面为大家的R。大写代表是外部链接属性意味着外部编译单元可以访问而小写则代码内部编译链接属性只能在内部编译单元访问。五、总结其实很多编程的细节特别是C和C混合编程中的细节往往不经过实践很难有深刻的印象。但是这种细节的遇到又经常是一个小概率的事件。这两者结合在一起就会让很多的开发者特别是c/c混合编程的人员有一种玄幻的感觉。其实不是玄幻是技术没掌握到位。