下面使用#define和const定义常量:
1 #define n_define 10 2 3 int main(int argc, char* argv[],int _version) 4 { 5 const int n_const=20; 6 int *p=(int *)&n_const; 7 *p=30; 8 printf("%d",*p); 9 printf(" %d",n_define); 10 11 return 0; 12 }
上述代码所对应的汇编代码如下:
1 mov [ebp+var_4], 14h ;n_const的十六进制 2 lea eax, [ebp+var_4] 3 mov [ebp+var_8], eax ;int *p=(int *)&n_const 4 mov ecx, [ebp+var_8] 5 mov dword ptr [ecx], 1Eh ;*p=30 6 mov edx, [ebp+var_8] 7 mov eax, [edx] 8 push eax 9 push offset asc_432020 ; "%" 10 call printf 11 add esp, 8 12 push 0Ah ;n_define的十六进制 13 push offset aD ; " %d" 14 call printf 15 add esp, 8
汇编代码1-11行对应C++代码5-8行。从汇编代码可以看得出来,在底层const常量和变量没区别。也就是说const定义的是假常量,本质上还是个变量,只不过编译器限制了我们对const常量的修改。而由#define定义的则不同。汇编代码第12行可以看出,编译器已经偷偷做了“手脚”:编译器将n_define替换成了0Ah,而这一步替换是发生在预处理阶段。n_define所对应的20已经变成了二进制,且在指令里面是属于立即数了。所以如果对n_define进行&n_define将会出错。
换一种通俗易懂的说法是:const常量是编译器级别的常量,而#define常量则是真常量。