const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。  虽然这听起来很简单,但实际上,const的使用也是c语言中一个比较微妙的地方,微妙在何处呢?请看下面几个问题。

  问题:const变量 & 常量

  为什么我象下面的例子一样用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢?

const int n = 5;
int a[n];

  答案与分析:

  1)、这个问题讨论的是“常量”与“只读变量”的区别。常量肯定是只读的,例如5, “abc”,等,肯定是只读的,因为程序中根本没有地方存放它的值,当然也就不能够去修改它。而“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量n被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时维度必须是“常量”,“只读变量”也是不可以的。

  2)、注意:在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const int n,n只是一个变量(常量 != 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的),实际上,根据编译过程及内存分配来看,这种用法本来就应该是合理的,只是ANSI C对数组的规定限制了它。

  3)、那么,在ANSI C 语言中用什么来定义常量呢?答案是enum类型和#define宏,这两个都可以用来定义常量。

 


  问题:const变量 & const 限定的内容

  下面的代码编译器会报一个错误,请问,哪一个语句是错误的呢?

typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
  答案与分析:

  问题出在p2++上。

  1)、const使用的基本形式: const char m;

  限定m不可变。

  2)、替换1式中的m, const char *pm;

  限定*pm不可变,当然pm是可变的,因此问题中p1++是对的。

  3)、替换1式char, const newType m;

  限定m不可变,问题中的charptr就是一种新类型,因此问题中p2不可变,p2++是错误的。

  问题:const变量 & 字符串常量

  请问下面的代码有什么问题?

char *p = "i'm hungry!";
p[0]= 'I';
  答案与分析:

  上面的代码可能会造成内存的非法写操作。分析如下, “i'm hungry”实质上是字符串常量,而常量往往被编译器放在只读的内存区,不可写。p初始指向这个只读的内存区,而p[0] = 'I'则企图去写这个地方,编译器当然不会答应。

  问题:const变量 & 字符串常量2

  请问char a[3] = "abc" 合法吗?使用它有什么隐患?

  答案与分析:

  在标准C中这是合法的,但是它的生存环境非常狭小;它定义一个大小为3的数组,初始化为“abc”,,注意,它没有通常的字符串终止符'

 

 

define和const的区别!

1.const定义常量是有数据类型的,而#define宏定义常量却没有,一是const有类型;二是const可以有不同的作用域。

2.const常量有数据类型,而宏常量没有数据类型。编译器可以对const进行类型安全检查,
   而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误

3.有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

问题?

1.还有其他的劣势么,是什么导致c++要求用const取代#define,有参考文档么?原理?

2.既然有这样那样的劣势,c为什么不要求用const取代#define?

3.#define的优势是是什么?

4.const的劣势是什么?

第三问:define不仅是定义常量,还可以定义带参数的宏,做到一定程度的泛型(利用#或者##操作符)。

 

引用楼主 ch_tei_hyou 的回复:
1.还有其他的劣势么,是什么导致c++要求用const取代#define,有参考文档么?原理?


无论是const还是#define,都是帮助编译器/预处理器 来生成可执行程序的。
用const引入数据类型后,可以帮助编译器识别数据的“属性”,这对编译器是非常重要的
有兴趣的话可以简单看一下编译原理。
#define是预处理阶段的工作,和编译器无关了。

引用楼主 ch_tei_hyou 的回复:
2.既然有这样那样的劣势,c为什么不要求用const取代#define?


要知道,一门语言是有标准的,而且要求标准的稳定。如果在C中加入太多的C++特性,将会
导致C编译器前端过于庞大,这就丧失了C的一些优势。
如果C还有存在的道理,保持自己的简洁、小巧是必须的。
C标准委员会没有接纳这1点,很遗憾。

引用楼主 ch_tei_hyou 的回复:
3.#define的优势是是什么?


从写编译器的角度讲,最大的优势是简单。因为预处理就可以解决掉#define,
不必让编译器来处理这个。

从应用上讲,#define也是不可或缺的。因为它可以让写代码的人体会到方便性。

const与#define最大的差别在于:前者在堆栈分配了空间,而后者只是把具体数值直接传递到目标变量罢了(存储到字符串列表,没有分配具体的空间,直接在预编译阶段直接进行替代) define是应用于预处理的,而const是在编译的时候处理的.

在程序语句中使用的常量的地方, 最好是使用const定义,在这方面来说, const只有优势,没有劣势.如果要说const劣势的地方,那就是它不能做上面3中的define的需要在预处理的时候做的事情.其实,这并非它的劣势,而只是不是它所要担负的工作罢了.