const 关键字 const 关键字用于定义常量,常量一旦被定义,其值就不能被修改。即变为只读状态,被const修饰的变量编译运行时存放在静态区。
有些编译器或者IDE可能不直接检查指针赋值时const的修饰符,所以可能会出现const修饰的局部变量可用指针修改的情况,但从C98到C23,都把这种操作视为非法的,因此如果你使用了指针去修改const变量,可能会产生因环境问题导致程序无法成功编译的问题。
const修饰变量 测试代码: **[点击运行] **
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> const int a=100 ;int main (int argc ,char *argv[]) { printf ("a=%d\n" , a); a=666 ; printf ("a=%d\n" , a); int *p=&a; *p = 888 ; printf ("a=%d\n" , a); return 0 ; }
输出结果:
compilation 1 2 3 4 5 6 7 8 9 10 main.cpp:7:6: error: cannot assign to variable 'a' with const-qualified type 'const int' a=666; ~^ main.cpp:3:11: note: variable 'a' declared const here const int a=100; ~~~~~~~~~~^~~~~ main.cpp:10:9: error: cannot initialize a variable of type 'int *' with an rvalue of type 'const int *' int*p=&a; ^ ~~ 2 errors generated.
由以上测试代码可以知道:
1. const修饰的变量不能使用赋值语句修改 2. const修饰的变量不能赋值给非const指针
const修饰指针 const可以修饰变量,这当然包括指针;同时指针也可以指向const修饰的变量,关键字的顺序决定了指针和指针指向的内容是否被修饰符修饰。
静态变量的指针 即指向静态变量的指针,const关键字只修饰了指针指向的内容,而不是指针本身。 静态变量的指针只能指向静态变量,但是指针本身不是静态的,所以可以修改指针的值,但是不可以修改指针指向的变量的值。
写法: const int* p;//推荐、int const *p;//不推荐
测试代码: **[点击运行] **
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <stdio.h> int main (int argc ,char *argv[]) { int const *p; const int * q; const int a = 100 ; const int b = 200 ; p = &a; q = &b; printf ("p=%d\n" , *p); printf ("q=%d\n" , *q); p = &b; q = &a; printf ("p=%d\n" , *p); printf ("q=%d\n" , *q); return 0 ; }
输出结果:
output
静态的指针变量 即静态的指针,const关键字只修饰了指针,而不是指针指向的变量。因此可以通过指针修改指针指向的变量的值,但是指针自己不能重新被赋值。
写法: **int* const p;**可见定义指针的时候星号跟着类型走还是比较规范的。
测试代码: **[点击运行] **
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <stdio.h> int main (int argc ,char *argv[]) { int a = 100 ; int b = 200 ; int * const p = &a; printf ("p=%d\n" , *p); *p = 666 ; printf ("p=%d\n" , *p); p = &b; printf ("p=%d\n" , *p); return 0 ; }
输出结果:
output 1 2 3 4 5 6 7 8 9 10 11 12 //不注释掉ERROR代码块的编译报错 main.cpp:16:7: error: cannot assign to variable 'p' with const-qualified type 'int *const' p = &b; ~ ^ main.cpp:7:16: note: variable 'p' declared const here int* const p = &a; ~~~~~~~~~~~^~~~~~ 1 error generated. //注释掉ERROR语句的输出: p=100 p=666
静态变量的静态指针 指针和指针的类型都是静态的,指针本身不能修改,指针指向的内容也不能被修改
写法: const int* const p;
测试代码: **[点击运行] **
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <stdio.h> int main (int argc ,char *argv[]) { const int a = 100 ; const int b = 200 ; const int * const p = &a; printf ("p=%d\n" , *p); *p = 666 ; printf ("p=%d\n" , *p); p = &b; printf ("p=%d\n" , *p); return 0 ; }
输出结果:
output 1 2 3 4 5 6 7 8 9 10 11 12 13 14 //不注释掉ERROR代码块的编译报错 main.cpp:11:8: error: read-only variable is not assignable *p = 666; ~~ ^ main.cpp:15:7: error: cannot assign to variable 'p' with const-qualified type 'const int *const' p = &b; ~ ^ main.cpp:6:22: note: variable 'p' declared const here const int* const p = &a; ~~~~~~~~~~~~~~~~~^~~~~~ 2 errors generated. //注释掉ERROR语句的输出: p=100
总结 const修饰符可以让程序变得更健壮,const经常用在指针变量上,特别是动态申请空间的指针,使用const变量修饰后可以有效防止指针丢失从而造成内存泄漏。但是需要注意的是在定义指针时const修饰符的写法, const修饰符的位置不同,指针指向的内容和指针本身是否可以被修改的含义也不同。所以应该使用更有规律的定义写法从而提高代码的可读性。