本篇内容:指针星号的三种含义以及指针在函数调用时,与实参、形参的变量传递关系,如何通过被调函数修改主调函数普通变量的值。
传送门:
C语言指针入门学习、概念梳理(一)
C语言指针入门学习、概念梳理(二)
C语言指针入门学习、知识点梳理(三)
C语言指针入门学习、知识点梳理(四)
1. 星号*的含义:
- 乘法
- 定义指针变量:int * p; //定义了一个名叫p的指针变量,int *表示p只能存放int整型变量的地址
- 指针运算符:放在已经定义好的指针变量的前面,如果p是一个已定义好的指针变量,则p表示以p的内容为地址的变量
int * p;中的星号与P = 5中的星号不是同一个,前者表示p是一个指针变量,后者表示取值运算符,*p等同于5
C语言变量中的约定俗成:整型用ijkl 浮点型用xyz 指针用pqst
# include <stdio.h>
int main(void)
{
int * p; //该语句等价于 int *p; 也等价于int* p; 一般来说写法写int * p;
int i = 5;
char ch = 'A'; //单个字符必须用单括号,否则会被系统认成变量
p = &i; //正确,*p是以p的内容为地址的变量
*p = 99; //p接收了i的地址,所以*p就等同于i,即i的值为被赋值99
printf("i = %d, *p = %d\n", i, *p);
//p = &ch; //error 类型不一致
//p = ch; //error 类型不一致
//p = 5; //error
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
运行结果: i = 99, *p = 99;
通过以上程序,可以清楚了解地址及指针的作用,注意区分 p 、 *p、 &i 、int * p;这些是了解指针、学习指针、运用指针的基础知识,务必熟记于胸。
# include <stdio.h>
void swap_1(int a, int b); //函数声明,此处还可以写成: void swap_1(int , int )
void swap_2(int * p, int * q) //形参名字不是*p,*q而是p,q,接收实参数据, 函数结束后释放p,q,所以光调换p,q值不影响主函数中的a,b
{
//C语言是值传递,此时p存放a的地址(如1000H),p也有自己的地址(如2000H),
int * t; //*p表示的是a地址中的数据(3),修改*p就会修改变量a的值。
t = p; p = q; q = t; //此处换的是p,q的地址,而没有换*p,*q,即主函数中a,b的地址和值都不变,所以输出结果还是a = 3, b = 5
}
void swap_3(int * p, int * q) //形参名字不是*p,*q而是指针变量p,q,接收实参数据(地址数据)
{
//C语言是值传递,此时p存放a的地址(如1000H),p也有自己的地址(如2000H),
int t; //*p,*q等同于a,b为int型,所以为保持类型一致,t也必须是整型int
t = *p; *p = *q; *q = t; //*p,*q虽然在子函数中,但通过地址可以直接修改主函数中a,b的值,输出结果为a = 5, b = 3
}
int main(void)
{
int a = 3;
int b = 5;
//swap_1(a, b); //不报错,但无法修改主函数中a,b的值,不能完成交换
//swap_2(a, b) //error:错误,形参是指针变量p和q,p要接收的是整型地址而不是整型变量,应改为swap_2(&a, &b);
//swap_2(&a, &b); //不报错,把a的地址传递给p,把b的地址传递给q。但是函数结束后主函数中a,b仍未完成交换
swap_3(&a, &b); //虽然调用函数结束后,形参指针变量p,q的值会被释放,但通过指针*p,*q,主函数中a,b的值已经被改写了,交换成功
printf("a = %d, b = %d\n", a, b);
return 0;
}
void swap_1(int i, int j) //返回值为void,可以直接写return; 也可以不写return,每调用一次return只能返回一个值
{
int t;
t = i; i = j; j = t; //等号两边类型一致,不报错,但修改形参的值不影响主函数变量,无法完成交换
//return; //return有返回值,终值函数的作用
}
------------------------------------------------------------------------------------------------------------------------
三个函数中,只有swap_3()才能完成交换,输出: a = 5, b = 3
其余两个函数,输出结果都是: a = 3, b = 5
总结一句话就是: 熟练掌握形参、实参、指针变量、地址、星号的概念,只有这样才不容易被程序中各种变量绕晕。
1.形参互换,调用函数结束后形参p,q被释放,所以没法儿影响main主函数中的实参a,b,无法完成交换
2.但是由于的特性,形参p,q通过拷贝实参a,b的地址,可以利用*p,*q远程修改主函数中a,b的值,完成交换。
3.形参和实参永远不同,他们在不同的函数中,分配的空间也不同,属于不同的变量,主函数传递给调用函数的值相当于是拷贝过去的,并不影响主函数中的实参,只有调用函数有了主函数变量的地址时,才可以直接控制修改实参变量,而指针可以通过地址在调用函数中远程修改主函数中的变量值。
归纳:如何通过被调函数修改主调函数普通变量的值?
- 实参必须为该普通变量的地址,如: 函数名(&a,&b)
- 形参必须为指针变量,如 int * p, int *q
- 在被调函数中通过 *形参名 = … 的方式就可以修改主调函数一个以上的相关变量的值
(能力有限,博客仅供广大网友参考学习,若有不足之处,还望指正,共同进步!)