交换函数实现的核心在于两个变量存储两个整数下,防止互相覆盖,引入第三个变量起到保管的作用。
理论模拟:如果有a=1,b=3两个整数需要交换位置,当令其a=b(b=3)=3,然后再令其b=a(a=3)=3,则最终会输出a=b=3。因为在其过程中,没有保存a的初始值,则直接被b赋值后覆盖。为此我们引入第三个变量temp,当令其temp=a(a=1)=1,然后再令其a=b(b=3)=3,再然后令其b=temp(temp=1)=1,则最终实现a=3,b=1。
简单实现
(基础版)
#include<stdio.h>
int main()
{
int a,b,temp;
scanf("%d%d",&a,&b);
temp=a,a=b,b=temp;
printf("%d %d",a,b);
return 0;
}
(数组版)
#include<stdio.h>
int main()
{
int a[2],temp;
scanf("%d%d",&a[0],&a[1]);
temp=a[0],a[0]=a[1],a[1]=temp;
printf("%d %d",a[0],a[1]);
return 0;
}
自定义函数
(要求:交换在自定义函数,输入输出在主函数)
(全局变量版)
#include<stdio.h>
int a,b,temp;
void swap();
int main()
{
scanf("%d%d",&a,&b);
swap();
printf("%d %d",a,b);
return 0;
}
void swap()
{
temp=a,a=b,b=temp;
}
(错误辨析版)值传递
有这样一个题,很经典,也很具有迷惑性,如下
当时我做这题时,没有学过指针,只学过值传递,没有了解过地址传递(将在下文进行解释)看到红框中的经典交换函数,毫不犹豫且自信得写上了错误答案510。
理论实践
#include<stdio.h>
void swap(int a,int b);
int main()
{
int x,y;
scanf("%d%d",&x,&y);
swap(x,y);
printf("%d %d",x,y);
return 0;
}
void swap(int a,int b)
{
int temp;
temp=a,a=b,b=temp;
}
what???怎么跟我想的完全不一样!
(对于没有学过指针和地址传递的小伙伴是一脸)
其实代码稍加修改就可以实现交换,如下(将在下文进行解释)
(正确解释版)地址传递
#include<stdio.h>
void swap(int *a,int *b);
int main()
{
int x,y;
scanf("%d%d",&x,&y);
swap(&x,&y);
printf("%d %d",x,y);
return 0;
}
void swap(int *a,int *b)
{
int temp;
temp=*a,*a=*b,*b=temp;
}
一个不能实现位置交换,而另一种却能,主要区别在于一个仅为值传递,而另一个实现了地址传递。
分别输出swap和main中结果
值传递:
这种方式是使用变量、常量、数组元素作为函数的参数,实际传递的是实参的值。形参接收到的只是实参的值(另外复制一份值),因此值传递时形参与实参分别占用了不同的存储单元,这种传递方式称“参数的值传递”或者“函数的传值调用”。
值传递的特点是单向传递。即主调函数调用时给形参也分配了存储单元,然后将实参值复制给形参,在调用结束后形参的存储单元就被释放,这时形参值的改变并不会影响到实参的值,也就是说实参的存储单元仍然保留原内容。如果在写交换函数时使用值传递,那么就会出现交换函数“失效” 的现象。
(借鉴于:【C语言】交换函数以及它的秘密 -- 地址传递)
地址传递:
这种方式是使用数组名或者指针作为函数的参数,实际传递的内容是该数组的首地址或者指针的值。也就是说形参接收到的是实参的存储单元地址,因此地址传递时形参与实参占用的是相同的存储单元,这种传递方式称为“参数的地址传递”。
地址传递的特点是编译系统不会为形参分配新的内存,数组名或者指针就是一组连续空间的首地址。因此通过地址传送时,形参取得了该实参的首地址,然后使用指针即可实现与实参共同拥有同一段内存空间,此时对形参做的操作就会使实参也发生变化。
(借鉴于:【C语言】交换函数以及它的秘密 -- 地址传递)
此处我们所用的就是指针实现的地址传递。指针的概念本文就不在陈述。
(数组版)地址传递数
void change(int b[2]);
int main()
{
int a[2];
scanf("%d%d",&a[0],&a[1]);
change(a);
printf("%d %d",a[0],a[1]);
return 0;
}
void change(int b[2])
{
int temp=b[0];
b[0]=b[1];
b[1]=temp;
}
此处我们所用的就是数组实现的地址传递,实际传递的内容是该数组的首地址。数组的概念本文就不在陈述。
可能还有同学疑问?
为什么(全局变量版)没有地址传递就可以实现交换?
其实如果明白了值传递和地址传递的概念应该一目了然!
因为全局变量在主函数和自定义函数中所用的变量是同一个,不存在值传递和地址传递的概念。不用传递,它们就是它们本身(无可厚非地址也是当然是同一个了)。改变自定义函数中变量,就如同改变主函数的变量。
既然没有终点,那在何处又何妨呢。
希望对你有帮助,语言学习贵在坚持输入和输出!