const是constant的简写,用来定义常量,如果一个变量被const修饰,那么它的值就不能再被改变。
示例代码:
const修饰的普通变量:定义的时候就要给它赋初值,之后哪怕是赋相同值都不行。const修饰的局部变量还是变量,直接修改编译器报错,可以间接修改,存放在栈区,代码块结束时释放。
const修饰全局变量:直接修改编译器报错,间接修改编译器也许会通过,但运行时会报错(段错误)。const修饰的全局变量存放在全局(静态)存储区,编译期最初将其保存在符号表中,第一次使用时为其分配内存,在程序结束时释放。
const修饰字符串常量:字符串常量位于文字常量区(也有文章归类于代码区),本身就不允许被修改,如果没有const的修饰,我们可能会在后面有意无意的修改字符串常量,这样会导致对只读内存区域的赋值,然后程序会立刻异常终止。有了const,这个错误就能在程序被编译的时候就立即检查出来,这就是const的好处。让逻辑错误在编译期被发现。
常量指针和指针常量傻傻分不清楚,以下方法帮助你来区分二者:区分常量指针和指针常量的关键就在于星号的位置,我们以星号为分界线。
如果我们将星号读作‘指针’,将const读作‘常量’的话,内容正好符合。
代码示例:
需要注意的是以下两点:
1、常量指针说的是不能通过这个指针改变变量的值,但是还是可以通过其他的方式来改变变量的值的。
2、常量指针指向的值不能改变,但是这并不是意味着指针本身不能改变,常量指针可以指向其他的地址。
指针常量是指指针本身是个常量,不能在指向其他的地址,需要注意的是,指针常量指向的地址不能改变,但是地址中保存的数值是可以改变的,可以通过其他指向该地址的指针来修改。
是以上两种的结合,指针指向的位置不能改变并且也不能通过这个指针改变变量的值,但是依然可以通过其他的普通指针改变变量的值。
const修饰参数是为了防止函数体内可能会修改参数原始对象。因此,有三种情况可讨论:
1、函数参数为值传递:
值传递(pass-by-value)是传递一份参数的拷贝给函数,因此不论函数体代码如何运行,也只会修改拷贝而无法修改原始对象,这种情况不需要将参数声明为const。例如:void func(int x)不用写成void func(const int x)
2、函数参数为指针:
指针传递(pass-by-pointer)只会进行浅拷贝,拷贝一份指针给函数,而不会拷贝一份原始对象。根据上面对指针常量、常量指针等讨论,同样分为三种情况:
2.1 防止修改指针指向的内容
典型C库函数:char *strcpy(char *dest, const char *src);
2.2 防止修改指针指向的地址
void swap ( int * const p1 , int * const p2 );指针p1和指针p2指向的地址都不能修改。
2.3 防止修改指针指向的内容和地址
1、如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。例如把函数int GetInt(void) 写成const int GetInt(void)是没有意义的。
2、如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。