对C语言中交换两个数是否交换成功的一点理解

本文通过四个实例对比分析了C语言中值传递与指针传递的区别,详细解释了为何某些情况下变量值交换不起作用,而另一些情况则可以成功交换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习指针的时候老师会给一个用变量做参数的交换两个数小编程,但是,那个编程中两个数的值交换前后却没有变化,然后老师由此引入指针。一开始我也不理解为什么同样的交换步骤,为什么有时候可以有时候不可以,然后请教了师兄,师兄讲的很好也很专业,可是我还是似懂非懂。。。然后,现在又再仔细地写了不同情况的交换两个数,终于算是懂了。(下面是我的一点理解,如果有错误,麻烦指出,谢谢!)

//【1】这是指针课题引入的那个编程,这里两个数的值交换不成功

#include<stdio.h>
void swap(int a,int b){
int temp=a; //temp==10
a=b; //a==20;
b=temp; //b==10
}
void main(){
int x=10,y=20;
printf("Before swap:x=%d,y=%d\n",x,y); //x==10,y==20
swap(x,y);
printf("After swap:x=%d,y=%d\n",x,y); //x==10;y==20
}

理解:这里是写了一个子函数,而且子函数的参数是变量,在书里有说变量作为参数时,进行的是传值,也就是实参与形参分别占用不同的内存单元,所以,虽然在子函数的内部a,b的值进行了交换,可是交换后的值却不能传给实参(实参的值可以传给形参,形参的值不能传给实参),所以x,y的值不会变。

//【2】下面这个编程就是我看到上面那个编程想到的,当时我很疑惑,为什么这里类似的步骤(两个数进行交换的三个赋值语句),却又不同的结果。这里两个数交换成功。

#include<stdio.h>
void main(){
int a,b,c;
a=20;
b=10;
printf("before:a=%d,b=%d",a,b);
c=a; //c==20
a=b; //a==10
b=c; //b==20
printf("\nafter:a=%d,b=%d",a,b);
}

理解:要注意看到一点,这里只有一个主函数,并没有进行函数的调用。这里三个赋值语句是进行了拷贝,这个拷贝过程直接就将a的值改为20,b的值改为10。注意区别上面那个编程对函数的调用,虽然上面那个也进行了拷贝,但是它改变的只是子函数中a,b的值,并未改变主函数中x,y的值。

//【3】然后我有想到会不会是因为a,b已经有初始化值,如果它们的值是由我们输入的,会不会交换成功。然后又写了下面这个编程,发现交换成功。这说明scanf对着并没有影响。

#include<stdio.h>
void main(){
int a,b,c;
printf("please enter two number:");
scanf("%d%d",&a,&b);
printf("before:a=%d,b=%d\n",a,b);
c=a;
a=b;
b=c;
printf("after:a=%d,b=%d",a,b);
}

//【4】在之前师兄给我解释的时候,他告诉我基本数据类型之间进行的是传值,而非基本数据类型(如 数组)进行的是传址,然后我就尝试用数组,对两个数进行交换。这个编程也是交换成功。

#include<stdio.h>
void swap(int a[2]){ //数组做函数参数时,是传址
int temp=a[0]; 
a[0]=a[1]; 
a[1]=temp; 
}
void main(){
int x[2]={10,20};
printf("Before swap:x[0]=%d,x[1]=%d\n",x[0],x[1]); 
swap(x);
printf("After swap:x[0]=%d,x[1]=%d\n",x[0],x[1]); 

}

理解:当数组作为参数时,进行的是传址,而且实参数组元素和形参数组元素占用同一段内存单元,改变形参数组的值也将改变实参数组的值,也就是说子函数中的a[0],a[1]的值改变了,主函数的x[0],x[1]页会跟着改变所以实现了两个数的交换。

//虽然这些看起来好像很低级,但是还是想写下来,给自己加深印象





C#简单变色龙游戏 /// /// 创建一副52张的新牌 /// /// public static System.Collections.ArrayList Creat() { System.Collections.ArrayList list = new System.Collections.ArrayList(); for (int i = 3; i <= 6; i++) { for (int j = 1; j <= 13; j++) { Poker p = new Poker(); switch (j) { case 1: p = new Poker((PokerStyle)i, "A", j, 11); break; case 2: p = new Poker((PokerStyle)i, j.ToString(), j, 10); break; case 11: p = new Poker((PokerStyle)i, "J", j, 11); break; case 12: p = new Poker((PokerStyle)i, "Q", j, 2); break; case 13: p = new Poker((PokerStyle)i, "K", j, 3); break; default: p = new Poker((PokerStyle)i, j.ToString(), j, j); break; } list.Add(p); } } return list; } /// /// 洗牌 /// /// /// public static System.Collections.ArrayList shuffle(System.Collections.ArrayList list)//洗牌 { System.Random r = new Random(); for (int i = 0; i <= 7; i++) { int rightOrRight = r.Next(1, 3); Poker[] leftPoker = new Poker[list.Count / 2]; Poker[] rightPoker = new Poker[list.Count % 2 == 0 ? list.Count / 2 : list.Count / 2 + 1]; list.CopyTo(0, leftPoker, 0, list.Count / 2); list.CopyTo(list.Count / 2, rightPoker, 0, list.Count % 2 == 0 ? list.Count / 2 : list.Count / 2 + 1); if (rightOrRight == 1)//左边插右边 { list.Clear(); for (int j = 0; j <= leftPoker.Length - 1; j++) { list.Add(rightPoker[j]); list.Add(leftPoker[j]); } if (leftPoker.Length != rightPoker.Length) { list.Add(rightPoker[rightPoker.Length - 1]); } } else { list.Clear(); for (int j = 0; j <= leftPoker.Length - 1; j++) { list.Add(leftPoker[j]); list.Add(rightPoker[j]); } if (leftPoker.Length != rightPoker.Length) { list.Add(rightPoker[rightPoker.Length - 1]); } } } return list; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值