const int a = 1; int const a = 1;
const关键字修饰变量a,表示a是一个整型变量,且这个变量的值是不可改变的。这两个定义的做用同样,编译后变量a分配在只读数据段中,这个数据段在一块只读的内存区域中,任何对这块区域的操做都是非法的。函数
以下面的程序:spa
#include <stdio.h> int main(void) { int const a = 100; a = 200; return 0; }
编译器会报错:指针
因此在定义的时候对该变量温馨化是使得该变量具备值的惟一机会。调试
const关键字在指针变量的定义以前,以下所示:code
int const a = 100; const int *p; //指针指向的内容不能改变 //等同于 int const *p; p = &a;
该定义表示p是一个指针变量,指向一个整型变量的存储空间,而且这个整型变量是一个不可改变的值的变量。也就是说指针p是能够改变的,而指针所指向的内容是不可改变的。内存
例如:开发
#include <stdio.h> int main(void) { int a = 100; int b = 200; const int *p; p = &a; printf("a = %d\n", *p); *p = 200; //错误,指针所指向的内容(经过*p方式)不能改变 p = &b; //正确,指针自己能够改变 printf("a = %d\n", *p); return 0; }
运行结果为:字符串
const关键字在指针变量的定义之中:编译器
int a = 100; int * const p = &a; //指针自己不能改变
该定义表示p是一个指针变量,指向一个整型变量的存储空间,而且这个整型变量是一个能够改变值的变量。而指针p的值不能改变,只能永远指向这个内存单元,也就是说指针p是不能够改变的,而指向的内容是能够改变的。string
例如:
#include <stdio.h> int main(void) { int a = 100; int b = 200; int * const p = &a; printf("a = %d\n", *p); *p = 200; //正确,指针所指向的内容(经过*p方式)能够改变 //p = &b; //指针自己不能够改变 printf("a = %d\n", *p); return 0; }
运行结果:
在指针变量定义以前和定义之中均有关键字,以下:
const int a = 100; int const * const p = &a; //指针和指针指向的内容都不能改变
该定义表示a是一个指针变量,指向一个整型变量的存储空间。这个整型变量是一个不能改变值的变量,并且指针a的值也不能改变:
例如:
#include <stdio.h> int main(void) { int a = 100; int b = 200; int const * const p = &a; printf("a = %d\n", *p); *p = 200; //错误,指针所指向的内容不能改变 p = &b; //错误,指针自己不能够改变 printf("a = %d\n", *p); return 0; }
编译结果:
指向非const变量的指针或者非const变量的地址能够传给指向const变量的指针,C语言能够作隐式转换,以下:
int a = 100; const int *p; p = &a; //常量指针指向一个普通变量
可是指向const变量的指针,或者const变量的指针币能够传给非const变量的指针,以避免意外修改了const存储区的内容,以下:
const int a = 100; int *p = &a; //普通指针不能指向一个常量变量
第一点是最重要的,来看一个程序:
#include <stdio.h> //将全部空格替换为"_",失败返回NULL char * replace(char *str) { char *p; if(str == NULL) return NULL; p = str; while(*p != '\0'){ if(*p == ' ') *p = '_'; //进行字符串的替换 p++; } return p; } int main(void) { char *p = "hello world and china\n"; if(replace(p) != NULL) printf("the string : %s\n", p); return 0; }
编译并运行程序:
程序出现了段错误,说明内存访问出错了,这个错误出如今*p = '_';这个语句上。该语句将字符串的值修改,可是做为replace()函数的参数的源字符串是一个字符串常量,这个常量被分配在只读数据段中。所以对次字符串的操做形成了非法内存访问,出现了段错误。
若是使用const关键字能够很好的预防这个问题。
修改上面的程序,使用const关键字对字符创常量进行声明,编译器会发现修改常量的错误:
#include <stdio.h> //将全部空格替换为"_",失败返回NULL const char * replace(const char *str) //使用const修饰变量 { const char *p; if(str == NULL) return NULL; p = str; while(*p != '\0'){ if(*p == ' ') *p = '_'; //进行字符串的替换 p++; } return p; } int main(void) { const char *p = "hello world and china\n"; //将源字符串声明为const变量 if(replace(p) != NULL) printf("the string : %s\n", p); return 0; }
编译结果:
编译器报错,提示*p = '_';出错,程序试图写只读数据段的错误被编译器发现了,这时开发人员能够很容易就能够发现这个错误。原本在运行时才出现的错误,在编译阶段就由编译器发现了,这样就省了大量的调试时间,这对程序开发来讲是颇有益的。