目录
引入
一、const关键字修饰普通变量
二、const关键字修饰指针
1.const放在*的左边
2.const放在*的右边
三、总结
首次遇到const关键字是在学习函数strcpy遇见,当我试着实现strcpy函数时,通过观察strcpy源码是发现在函数的第二个形参(要拷贝的字符串)前用了const关键字进行了修饰。通过此现象,写了改文章对const关键词进行详细分析。下面代码块是我依据strcpy函数源码实现的my_strcpy函数,在形参部分中就可以看见const关键字。
void my_strcpy(char *dest,const char *src)
{
//断言
assert(dest != NULL);
assert(src != NULL);
while(*dest++ = *src++)
{
;
}
}
接下来就会对const关键字进行详细讲解。
首先讲解const修饰普通变量,当定义的变量前无const关键词修饰我们可以对变量重新复制来修改变量中的内容如下面代码所示。
int main()
{
int num = 3;
printf("%d\n", num);
num = 5;
printf("%d", num);
return 0;
}
通过上述代码num会被修改,当我们不希望num别修改时我们可以在变量前加入const关键字,此时num的值就不能被修改,在vs中会直接报错。
到这里可能会有人产生疑问,对于const修饰的num既然其中的值无法被直接修改,那么num会不会变为常量,答案是num依旧是变量!!!我们可以下面的代码进行验证。
我们知道在C99之前不支持变长数组所以在确定元素个数中,应当是常量而不是变量,但是在上述代码中我们将num当做数组的长度放入数组中时编译器会直接报错可见num应当是变量而不是常量。那么const修饰的不通变量一定不能被改变吗,答案依旧是否定的!!!因为const修饰变量时只是在语法层面限制了const修改,但本质上num还是变量,是一种不能被修改的变量。直接修改num是行不通的那么我们可以取出num的地址然后通过解引用操作进行修改。代码和结果如下。这样我们就可以对num进行修改了。
int main()
{
const int num = 3;
printf("%d\n", num);
int* p = #
*p = 5;
printf("%d", num);
return 0;
}
那么我们为了阻止上述的修改从而引入了const修饰指针变量。
当我们写出int *p = &num时此时p是一个变量用来存放num的地址,我们可以通过*p解引用操作对num进行修改,当我们将const放在*号的左边时(const int * p 或者 int const *p),我们发现上述操作无法对num的值进行修改,编译器会直接报错,如下图所示
综上所述我们可以得到结论当const关键字放在*号的左边时修饰的*p,也就是说限制的是p所指向的对象,即p所指向的对象不能被修改。
通过上述讲解,我们就可以很轻松的想到,const放在*号的右边时(const int *p)此时限制的就是p,此时p所指向的地址里的内容是可以进行修改的,但是p所存放的地址不能被修改,也就是p = &(其它变量)是不正确的编译器会报错,错误代码及提示信息如下。
如果我们即不想让p所指向的地址中内容发生改变,也不想让p存放的地址信息发生改变,我们就需要在*号的左边加上const关键字,在*号的右边也加上const关键字。此时就达到我们希望的效果了。
通过上述的学习我们就可以看懂strcpy函数源码中的const char* src 是什么意思了,至于为什么要用const关键字修饰,我们要理解strcpy函数的作用,strcpy作用是将一个数组中内容拷贝到另一个数组中,那么src也就是source(源头)的缩写,也就是数据源,我们在拷贝时是不希望数据源被修改的所以在 要用const关键字修饰 *src。在c语言的很多库函数中形参中都是用到了const关键字例如strlen函数,源码如下。
size_t strlen_a(const char *str)
{
size_t length = 0 ;
while (*str++ )
++ length;
return length;
}
可见const关键字的作用之大!
注:此篇文章仅供参考,若有不足希望指出!