函数的参数不仅可以是整型,浮点型,字符型等数据,还可以是指针类型;它的作用是将一个变量的地址传送到另一个函数中。
关于地址,指针,指针变量可以参考我的上一篇文章:
地址,指针,指针变量是什么?他们的区别?符号(*)在不同位置的解释?_juechen333的博客-CSDN博客指针是C语言中的一个重要概念,也是C语言的一个重要特色;使用指针,可以使程序简洁、紧凑、高效。不掌握指针,就没有掌握C语言的精华。https://blog.csdn.net/qq_57342311/article/details/129225045
目录
一、引入
1.1改变指针变量的值
1.2改变指针变量所指向的值
二、程序练习
2.1程序实现
2.2程序分析
一、引入
我们先来看一个问题:输入整数 a 和 b,按大小先后顺序输出 a 和 b。
可以使用多种方法来处理这个这个问题
1.1改变指针变量的值
#include<stdio.h>
int main()
{
int* p1, * p2, * p, a, b; //定义指向整型的指针变量和整型变量
printf("请输入两个整数:");
scanf_s("%d,%d", &a, &b);
p1 = &a; //赋予a的地址,指向变量a
p2 = &b; //赋予b的地址,指向变量b
if (a < b) //如果a<b,交换p1和p2
{
p = p1;
p1 = p2;
p2 = p;
}
printf("a=%d, b=%d\n", a, b); //输出a, b的值
printf("max = %d, min = %d\n", *p1, *p2); //输出指针变量p1和p2所指向的变量值
return 0;
}
判断语句中也可以改为直接对 p1 和 p2 赋予新值,不用中间变量 p,使程序更加简练。
{
p1 = &b;
p2 = &a;
}
运行结果:
程序分析:
由图可知,指针变量 p1 和 p2 的值发生了交换,而变量 a,b的值未发生交换。
这种算法是不交换原来变量的值,而是交换指针变量的值。
1.2改变指针变量所指向的值
用指针变量作为函数参数
#include<stdio.h>
int main()
{
void swap(int* p1, int* p2);
int* point_1, * point_2, a, b; //定义指向整型的指针变量和整型变量
printf("请输入两个整数:");
scanf_s("%d,%d", &a, &b);
point_1 = &a; //赋予a的地址
point_2 = &b; //赋予b的地址
if (a < b) //如果a<b,调用swap函数
{
swap(point_1, point_2);
}
printf("a=%d, b=%d\n", a, b); //输出a, b的值
printf("max = %d, min = %d\n", *point_1, *point_2); //输出两个指针变量的值所指向的变量值
return 0;
}
void swap(int* p1, int* p2) //自定义函数,交换指针变量p1和p2
{
int* temp;
temp = p1;
p1 = p2;
p2 = temp;
}
运行结果:
程序分析:
由运行结果我们可以看出:变量 a 和 b 未发生交换,指针变量 point_1 和 point_2 的值也没有发生交换,那么函数 swap 到底实现交换功能了吗?我们将swap函数添加一个输出语句看一下结果。
void swap(int* p1, int* p2) //自定义函数,交换指针变量p1和p2
{
int* temp;
temp = p1;
p1 = p2;
p2 = temp;
printf("*p1 = %d, *p2 = %d\n", *p1, *p2);
}
可知在swap函数中,*p1 = 8,*p2 = 5;实现了交换的功能,但没有将改变的值传回去。
结合函数调用的知识,我们可以知道调用函数时,采取的是单向值传递,形参的改变不能使实参也随之改变。
由图可知,指针变量 point_1 和 point_2 的值没有发生交换,那么他们指向的变量也没有发生变化。
如果在函数中我们能使指针变量所指向的变量发生变化,那么就可以达到交换原变量的目的,此时而指针变量本身的值(即地址)不发生变换
我们对 swap 函数稍作修改,使它访问到指针变量所指向的变量。
void swap(int* p1, int* p2) //自定义函数,交换指针变量所指向的变量*p1和*p2
{
int temp;
temp = *p1; //交换*p1和*p2
*p1 = *p2;
*p2 = temp;
}
运行结果:
程序分析:
从结果我们可以看出,变量 a 和 b 发生了交换,也就是指针变量 point_1 和 point_2 指向的变量发生了交换。
由图可知,指针变量 point_1 和 point_2 的值(即地址 &a,&b)未发生变化,指针变量所指的变量(即变量 a,b)发生了变化。
这种算法是交换原来变量的值,而不交换指针变量的值。
这里需要注意的是中间变量 temp 的定义形式:
void swap(int* p1, int* p2) //自定义函数,交换指针变量所指向的变量*p1和*p2
{
int* temp; //指针变量temp
*temp = *p1; //交换*p1和*p2
*p1 = *p2;
*p2 = *temp;
}
这时程序虽然语法上没有报错,但编译时会报错,*p1 就是 a,是整型变量,而 *temp 是指针变量 temp 所指向的变量,由于未给 temp 赋值,因此temp的值是无法确定的,所以temp所指向的存储单元也是未知的,因而 *temp = *p1 就是向一个未知的存储单元赋值,这是不合法的。
总结:
函数的调用只可以得到一个返回值,而使用指针变量作为参数,可以得到多个变化了的值。
二、程序练习
输入3个整数 a,b,c,要求按大小顺序将他们输出,用函数实现。
2.1程序实现
#include<stdio.h>
int main()
{
void exchange(int* q1, int* q2, int* q3); //声明函数,后面需要调用
int a, b, c, * point_1, * point_2, * point_3;
printf("请输入三个整数:");
scanf_s("%d,%d,%d", &a, &b, &c);
point_1 = &a; point_2 = &b; point_3 = &c;
exchange(point_1, point_2, point_3);
printf("Max = %d, Mid = %d, Min = %d\n", a, b, c);
return 0;
}
void exchange(int* q1, int* q2, int* q3) //自定义函数,交换3个变量的值
{
void swap(int* p1, int* p2); //声明函数,后面需要调用
if (*q1 < *q2) { swap(q1, q2); }
if (*q1 < *q3) { swap(q1, q3); }
if (*q2 < *q3) { swap(q2, q3); }
}
void swap(int* p1, int* p2) //自定义函数,交换指针变量所指向的变量*p1和*p2
{
int temp;
temp = *p1; //交换*p1和*p2
*p1 = *p2;
*p2 = temp;
}
2.2程序分析
exchange 函数的作用是对3个数按大小排序,在执行 exchange 函数过程中,要嵌套调用 swap 函数,swap 函数的作用是对两个数按大小排序,通过调用 swap 函数(最多调用3次)实现3个数的排序。
主函数中3个指针变量的值未发生改变,3个指针变量所指向的变量的值发生了改变。
要熟练掌握指针变量和指针变量所指向变量之间的关系,避免混淆!