C语言指针入门学习、知识点梳理(四)

本篇内容:指针星号的三种含义以及指针在函数调用时,与实参、形参的变量传递关系,如何通过被调函数修改主调函数普通变量的值。

传送门:

C语言指针入门学习、概念梳理(一)

C语言指针入门学习、概念梳理(二)

C语言指针入门学习、知识点梳理(三)

C语言指针入门学习、知识点梳理(四)


1. 星号*的含义:
  1. 乘法
  2. 定义指针变量:int * p; //定义了一个名叫p的指针变量,int *表示p只能存放int整型变量的地址
  3. 指针运算符:放在已经定义好的指针变量的前面,如果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.形参和实参永远不同,他们在不同的函数中,分配的空间也不同,属于不同的变量,主函数传递给调用函数的值相当于是拷贝过去的,并不影响主函数中的实参,只有调用函数有了主函数变量的地址时,才可以直接控制修改实参变量,而指针可以通过地址在调用函数中远程修改主函数中的变量值。


归纳:如何通过被调函数修改主调函数普通变量的值?

  1. 实参必须为该普通变量的地址,如: 函数名(&a,&b)
  2. 形参必须为指针变量,如 int * p, int *q
  3. 在被调函数中通过 *形参名 = … 的方式就可以修改主调函数一个以上的相关变量的值

(能力有限,博客仅供广大网友参考学习,若有不足之处,还望指正,共同进步!)

猜你喜欢

转载自blog.csdn.net/AII_IIA/article/details/131240733