函数调用时用const保护指针

时间:2022-12-01 14:08:51

当调用函数并且把指向变量的指针作为参数传入时,通常会假设函数将修改变量(否则,为什么函数需要指针呢?)。例如,如果在程序中看到语句

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
}