一、在介绍指针形参之前,先简要说明下两个运算符 & 和 *。
1、 取址运算符 & 用来取得其操作数的地址。取址运算符的操作数必须是在内存中可寻址到。换句话说,该运算符只能用作函数或对象(例如左值),而不可以用于位字段,以及那些未被存储类型修饰符register声明的内容。
float x, *ptr;
ptr = &x; // 合法:使得指针ptr指向x
ptr = &(x+1); // 错误: (x+1) 不是一个左值
2、当已具有一个指针,并且希望获取它所引用的对象时,使用间接运算符 *(indirection operator),有时候会被称为解引用运算符(dereferencing operator)。它的操作数必须是指针类型。
float x, *ptr = &x;
*ptr = 1.7; // 将1.7赋值给变量x
++(*ptr); // 并将变量x的值加1
在这个示例最后,ptr的值保持不变,但x的值变成2.7。
二、对函数来说,它所传递的任何参数仅仅是原来参数的一个拷贝
如果通过指针传递参数,其实质仍然是值传递,传递的是地址而已。用指针传递参数,可以实现对实参进行改变的目的,是因为传递过来的是实参的地址,因此使用*a实际上是取存储实参的内存单元里的数据,即是对实参进行改变,因此可以达到目的。在使用的过程中需要通过对地址的解引用来操作其所指向的变量,同时可以通过指针的自增自减移动从而改变所指向的值,灵活度较大。
举例说明:
程序1
#include<stdio.h>
void fun(int *p)
{
int b=22;
p=&b;
}
int main(void)
{
int a=1;
int *q;
q=&a;
printf("%d\n",*q);
fun(q);
printf("%d\n",*q);
return 0;
}
输出为
程序2
#include<stdio.h>
void fun(int *p)
{
*p=22;
}
int main(void)
{
int a=1;
int *q;
q=&a;
printf("%d\n",*q);
fun(q);
printf("%d\n",*q);
return 0;
}
输出为
程序1,明明改变了P的指向了,为什么还是输出1呢?
其实问题的关键不是指针作为形参的问题,而是函数传参的问题。q是a的地址,以实参形式传递给子函数fun(),而在fun()函数内部使用时,其实p仅仅是q的拷贝值。将p的值修改为&b,只是p的指向从a转向了b而已。而主函数中q及a都没有发生过改变。
注:C语言里,改变值只能通过指针(地址)方式进行传递,或许你会说传递数组不是也可以改变值么,实际上,传递数组就是传递指针(或许对数组来说,这个指针有点特别)
参考:https://blog.csdn.net/a3748622/article/details/79286974