可以将指针定义为指向常量,这意味着不能通过指针修改它所引用的值。下例声明了一个整数和一个整数常量,然后声明了一个整数指针和一个指向整数常量的指针,并分别初始化为对应的整数:
int num = 5;
const int limit = 500;
int *pi; // 指向整数
const int *pci; // 指向整数常量
pi = #
pci = &limit;
下图是它们的内存分配情况。
下面的代码会打印这些变量的地址和值:
printf(" num - Address: %p value: %d\n",&num, num);
printf("limit - Address: %p value: %d\n",&limit, limit);
printf(" pi - Address: %p value: %p\n",&pi, pi);
printf(" pci - Address: %p value: %p\n",&pci, pci);
运行代码会产生类似下面的输出:
num - Address: 100 value: 5
limit - Address: 104 value: 500
pi - Address: 108 value: 100
pci - Address: 112 value: 104
如果只是读取整数的值,那么引用指向常量的指针就没事,读取是完全合法的,而且也是必要的功能,如下所示:
printf("%d\n", *pci);
我们不能解引指向常量的指针并改变指针所引用的值,但可以改变指针。指针的值不是常量。指针可以改为引用另一个整数常量,或者普通整数。这样做不会有问题。声明只是限制我们不能通过指针来修改引用的值。
这意味着下面的赋值是合法的:
pci = #
我们可以解引pci
来读取它,但不能解引它来修改它。
考虑下面的赋值语句:
*pci = 200;
这会导致如下语法错误:
'pci' : you cannot assign to a variable that is const
指针认为自己指向的是整数常量,所以不允许用指针来修改这个整数。我们还是可以通过名字来修改num
变量,只是不能用pci
来修改。
理论上来说,常量的指针也可以如图1-12那样可视化,普通方框表示变量,阴影方框表示常量。pci
指向的阴影方框不能用pci
来修改,虚线表示指针可以引用的数据类型。在上例中,pci
指向limit
。
把pci
声明为指向整数常量的指针意味着:
pci
可以被修改为指向不同的整数常量;pci
可以被修改为指向不同的非整数常量;- 可以解引
pci
以读取数据; - 不能解引
pci
从而修改它指向的数据。
数据类型和
const
关键字的顺序不重要。下面两个语句是等价的:const int *pci; int const *pci;