在C语言中,所有函数的参数传递都是按值传递的,这意味着函数接收的是参数值的一个拷贝,而不是原始参数本身,即使这个参数是一个指针,情况也是如此。
将一个指针作为参数传递给函数时,传递的是指针变量的值,这个值是指针所指向的内存地址。虽然指针本身是一个变量,但是在函数调用的上下文中,指针变量的值(即内存地址)被拷贝给函数参数。因此,函数内部操作的是这个地址拷贝,而不是原始的指针变量。
这里有一个关键点需要理解:虽然传递的是指针值的拷贝,但是通过这个拷贝的指针,函数仍然可以访问核修改指针所指向的内存区域的内容,这是因为拷贝的指针和原始的指针都指向相同的内存地址。然而,如果想要修改指针本身(比如让它指向一个新的内存地址),就需要能够修改原始指针变量的值,而不仅仅是通过它的拷贝来访问内存。
我们通过一个简单的例子来说明:
void modifyPointer(int *p)
{
p++;
*p = 10;
printf("函数内部p指针的指向地址:%p\n", p);
}
int main()
{
int buff[3] = {3, 5, 6};
int *pBuff = &buff[1];
printf("修改前pBuff指针的指向地址:%p.\n", pBuff);
modifyPointer(pBuff);
printf("修改后的pBuff指针的指向地址:%p\n", pBuff);
printf("buff[2]的值为:%d.\n", buff[2]);
return 0;
}
可以看下函数运行结果:
如果我们需要修改一个指针本身,可以使用二级指针,即指向指针的指针。这样,可以传递一个指向原始指针的指针,函数内部通过这个二级指针的拷贝来修改原始指针的值。
我们再来看下面的例子:
void modifyPointer(int **p)
{
(*p)++;
**p = 10;
printf("函数内部p指针的指向地址:%p\n", *p);
}
int main()
{
int buff[3] = {3, 5, 6};
int *pBuff = &buff[1];
printf("修改前pBuff指针的指向地址:%p.\n", pBuff);
modifyPoint(&pBuff);
printf("修改后的pBuff指针的指向地址:%p\n", pBuff);
printf("buff[2]的值为:%d.\n", buff[2]);
return 0;
}
函数运行结果:
简而言之,即使是指针,在C语言中也是按值传递的,这意味着传递的是指针值的拷贝。要修改指针本身,而不仅仅是它所指向的数据,我们需要通过二级指针实现。