在这个例子中,我们不希望myPrint函数修改传入的字符串内容,因此入参使用了const限定符,表明传入的字符串是只读的,因此,如果myPrint函数内部如果尝试对str进行修改,将会报错:
$ gcc -o test test.c test.c:6:12: error: assignment of read-only location ‘*str’ str[0] = 'H';
因此,我们自己在编码过程中,如果确定传入的指针参数仅用于访问数据,那么应该将其声明为一个指向const限定类型的指针,避免函数内部对数据进行意外地修改。
修饰全局变量
我们知道,使用全局变量是一种不安全的做法,因为程序的任何部分都能够对全局数据进行修改。而如果对全局变量增加const限定符(假设该全局数据不希望被修改),就可以避免被程序其他部分修改。这里有两种使用方式。 第一种,在a文件中定义,其他文件中使用外部声明,例如: a.h
b.c
第二种,在a文件中定义,并使用static修饰,b文件包含a文件,例如: a.h
b.c
注意,这里必须使用static修饰,否则多个文件包含导致编译会出现重复定义的错误。有兴趣的可以尝试一下。
const修饰的变量是真正的只读吗?
使用const修饰之后的变量真的是完全的只读吗?看下面这个例子:
#include <stdio.h> int main(void) { const int a = 2018; int *p = &a; *p = 2019; printf("%d\n",a); return 0; }
运行结果:
2019
可以看到,我们通过另外定义一个指针变量,将被const修饰的a的值改变了。那么我们不禁要问,const到底做了什么呢?它修饰的变量是真正意义上的只读吗?为什么它修饰的变量的值仍然可以改变?
#include<stdio.h> int main(void) { int a = 2019;
我们分别获取有const修饰和无const修饰的汇编代码。 无const修饰,汇编代码:
.LC0: .string "%d\n" main: push rbp mov rbp, rsp sub rsp, 16 mov DWORD PTR [rbp-4], 2019 mov eax, DWORD PTR [rbp-4] mov esi, eax mov edi, OFFSET FLAT:.LC0 mov eax, 0 call printf mov eax, 0 leave ret
有const修饰,汇编代码:
.LC0: .string "%d\n" main: push &
|