当调用函数并且把指向变量的指针作为参数传入时,通常会假设函数将修改变量(否则,为什么函数需要指针呢?)。例如,如果在程序中看到语句
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 = %d\n", i, j);
f(&j);
printf("i = %d, j = %d\n", 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
}