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

本篇继续深入介绍C语言指针的基本概念与知识点,以经典指针程序--------”互换两个数字“进行阐述,基础不牢地动山摇,有关指针的基础概念,需要提前学习的,可以通过链接跳转至第一、第二篇。

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

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

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

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

首先看一个经典程序 : ”互换两个数字“

# include <stdio.h>
//不能完成互换功能
void exchange_1(int a, int b) //形参接收的是值,而不是a,b的地址,实参和形参互不影响,简单来说,
                              //此处括号中及子函数中的形参a,b可以改成其他任意字符,如x,y效果是一样的。
{
    
    
	int t;
	t = a;      //此处的a,b与exchange_1()括号中的a,b是同一个
	a = b;
	b = t;	
	return;     //经过exchange_1函数后,修改了形参a,b 的值,但不影响main函数中实参a,b的值,所以输出还是a = 3,b = 5
}
int main(void)
{
    
    
	int a = 3;  //实参 
	int b = 5;         
    exchange_1(a,b);  //此处括号的a,b与main函数定义的a,b相同,实参单向传给形参
	printf("a = %d, b = %d\n", a,b);
	
	//exchange_1函数中的形参a,b与 main主函数中的实参a,b不是同一个a,b
}
---------------------------------------------------------------------------------------------------------------------------------
	
	运行结果: a = 3, b = 5  //想想为什么?为什么没有交换数值?
	
    经过main主函数exchange_1(a.b)后,实参a,b将数值3,5传递给形参,进入交换子函数后,在函数内部完成了交换,
    随后形参a,b的空间释放,而实参空间未释放,仍是a = 3,b = 5 ,故未达成互换目的。

    形参交换了数据,而实参保持原数据不变,这是单向的实参到形参的传递过程,所以形参的值改变后实参的值没变,
    形参在函数中是变量名,在函数调用时,形参被临时分配相应的内存。调用结束后,形参单元被释放,而实参单元保留并维持原值。   
运行结果是 3,5 还是 5, 3 ?首先要知道,局部变量执行完就释放了,达不到置换效果。main函数中的局部变量a,b,只在本函数使用,所以与exchange_1函数中的a,b不冲突,如果结果是a = 5,b = 3意味着exchange_1把main函数中的a,b改写了;如果结果还是a = 3 , b = 5意味着调用完exchange_1函数后,a,b的值照样没有改变。

若要使其数值交换,需要如何更改呢?

1.在调用子函数更改数值后,在子函数结束,释放形参空间前将结果输出打印出来,另外在主函数中输出打印a,b,测试实参a,b是否被修改

# include <stdio.h>
//不能完成互换功能
void exchange_1(int x, int y)   //形参与实参互不影响,因此与使用什么符号无关
{
    
    
	int t;
	t = x;      //此处的a,b与exchange_1()括号中的a,b是同一个
	x = y;
	y = t;	
    printf("a = %d,b = %d\n", x,y);  //形参交换成功,在函数结束,释放形参前将结果打印输出 
    return;
}

int main(void)
{
    
    
	int a = 3;  //实参 
	int b = 5;         
    exchange_1(a,b);  //此处括号的a,b与main函数定义的a,b相同,实参单向传给形参x,y
    printf("a = %d,b = %d\n", a,b);   //参照组,看看实参a,b的值是否被更改 
}


------------------------------------------------------------------------------------------------------------------------------

运行结果 : 
          a = 5,b = 3
          a = 3,b = 5

结果表明,形参与实参互不影响,形参交换成功,实参未能交换,因为函数调用结束形参将被释放,主函数中实参值不变。

在这里插入图片描述

2. 使用指针------错误用法

# include <stdio.h>
//不能完成互换功能
void exchange_2(int * p, int * q)   //此处指针变量是p, int *是数据类型,指针变量p必须接收同类型的变量地址
{
    
    
//	int t;               //error:错误,t = p类型不一致,p是指针变量,t也必须是同类型变量
    int * t;             //若要互换p、q的值,t必须是int *类型,不能是int类型
	t = p;
	p = q;
	q = t;
    return;
}

int main(void)
{
    
    
	int a = 3;
	int b = 5;
	//exchange_2(*p, *q);    //error: 错误,形参中指针变量p必须接收同类型的便利地址,*p,*q不是变量地址。
	//exchange_2(a, b);      //error: 错误,理由同上
	exchange_2(&a, &b);      //正确,&a, &b都是整型变量地址,传递给整型指针变量p
	printf("a = %d, b = %d\n", a, b);  //对于a,b来说,值和地址都没变,换的是p,q存储的内容。
	return 0;
}

------------------------------------------------------------------------------------------------------------------------------

运行结果:  a = 3, b = 5


1.不要把p,q看成是指针,单纯看成变量,调用函数时传入的不是a,b而是a,b的值,相当于把a,b的值拷贝了一份传递给p,q, 子函数怎么玩都是p,q的值,而不是a,b本身,形参的改变不影响实参。

2.p是地址,*p是值,p和q的地址互换并不影响a,b ,a,b的地址和值并没有改变, 通俗来讲就是:a,b分别住在两间房中,p,q把门牌号互换了,但a,b还各自躺在原来的房间里,房间相对于走廊的地址并没有变(如a开始是在二楼第一间,互换门牌号后还是在二楼第一间)

在这里插入图片描述

3.使用指针------正确用法:

# include <stdio.h>
//能完成互换功能
void exchange_3(int * p, int * q)   //此处指针变量是p, int *是数据类型,指针变量p必须接收同类型的变量地址
{
    
    
    int  t;             //若要互换*p、*q的值,t的类型要与*p,*q一致,即int整型,不能定义成int * 否则语法会错误
	t = *p;             //*p代表的是以p的内容为地址的变量,p存放整型地址,则*p代表整型变量,所以*p是int整型,即t也要是整型int t;
	*p = *q;            //*p就是a, *q就是b,所以互换的不是q,p的值,此函数将a,b的值给改了,完成了交换
	*q = t;             //这里的*p,*q在全局整个程序中都是等同于a, b的,所以*p,*q地址和值都已改变,成功交换主函数中的a,b
    return;
}

int main(void)
{
    
    
	int a = 3;
	int b = 5;
	exchange_3(&a, &b);      //正确,&a, &b都是整型变量地址,传递给整型指针变量p
	printf("a = %d, b = %d\n", a, b);  //对于a,b来说,值和地址都没变,换的是p,q存储的内容。
	return 0;
}

-------------------------------------------------------------------------------------------------------------------------

运行结果: a = 5, b = 3



这里的*p,*q在全局整个程序中都是等同于a, b的,所以*p,*q地址和值都已交换,所以等价于a,b交换。

在这里插入图片描述
仔细观察exchange_1()、exchange_2()、exchange_3()的相同与不同之处,为何只有3才能交换成功。
因为
exchange_1()只改变形参,实参地址与值没变,交换失败;
exchange_2()只交换形参地址,不影响实参,交换失败;
exchange_3()交换*p,*q地址和数值都交换了,且二者分别等同于a,b,故交换成功。

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

猜你喜欢

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