当调用函数并且把指向变量的指针作为参数传入时,通常会假设函数将修改变量(否则,为什么函数需要指针呢?)。例如,如果在程序中看到语句
f(&x);
大概是希望f改变x的值。但是,f仅需检查x的值而不是改变它的值也是可能的。指针可能高效的原因是:如果变量需要大量的存储空间,那么传递变量的值会浪费时间和空间。
可以使用单词const来表明函数不会改变指针参数所指向的对象。const应放置在形式参数的声明中,后面紧跟着形式参数的类型说明:
void f(const int *p) { *p = 0; // wrong }
这一用法表明p是指向“常整数”的指针。试图改变*p是编译器会检查的一种错误。
问: 声明void f(const int *p);是说函数f不能修改p吗?
答:不是。这说明不能改变指针p指向的整数对象,但是并不阻止f改变p自身。
void f(const int *p) { int j; *p = 0; // wrong p = &j; // legal }
因为实际参数是按值传递的,所以通过使指针指向其他地方的方法给p赋新值不会对函数外部产生任何影响。
#include <stdio.h> void f(const int *p); int main(void) { int i = 6; int j = 10; printf("i = %d, j = %dn", i, j); f(&j); printf("i = %d, j = %dn", i, j); return 0; } void f(const int *p) { int j = 33; p = &j; } /* result i = 6, j = 10 i = 6, j = 10 */
问:声明指针类型的形式参数时,像下面这样在参数名前面放置单词const是否合法?
答:是合法的。然而效果不同于把const放在p的类型前面。在p的类型前面放置const可以保护p指向的对象。在p的类型后面放置const可以保护p本身:
void f(int * const p); { int j; *p = 0; // legal p = &j; // wrong }
这一特性并不经常用到。因为p很少是另一个指针(调用函数时的实际参数)的副本,所以极少有什么理由保护它。更罕见的一种情况是需要同时保护p和它所指向的对象,这可以通过在p的类型前和后都放置const来实现。
void f(const int * const p) { int j; *p = 0; // wrong p = &j; //wrong }