Linux中万物皆文件。
js中万物皆对象。
而我觉得编程世界,万物皆内存,无非是读写内存操作,我们要找到我们想要用到的资源,那么一定要先找到内存地址,再去拿出来我们正真想要用的值~~
下面用一个简单的交换程序来说明传值与串址的区别。
(1)传值
1 void swap(int a,int b); 2 void swap1(int* a, int* b); 3 int main() 4 { 5 /* 6 C语言传参机制 7 */ 8 int a = 100; 9 int b = 200; 10 swap(a, b); 11 printf("主函数中a=%d ", a); 12 printf("主函数中b=%d ", b); 13 14 getchar(); 15 } 16 17 void swap(int a, int b) { 18 int temp; 19 temp = a; 20 a = b; 21 b = temp; 22 printf("传值swap普通函数中a=%d ", a); 23 printf("传值swap普通函数中b=%d ", b); 24 }
运行结果:
说明传值的情况下无法实现交换值的功能,因为答案很简单,编程世界万物皆内存,我们在主函数中开辟的a,b的内存地址和被调用函数swap()中a,b的地内存地址是不一样的,
所以我们只是在swap中实现值的交换,而没找到主函数的a,b的内存,再对值进行交换,所以归根没有操作主函数的a,b。所以结果就如上面一样。
(2)址传递
void swap(int a,int b); void swap1(int* a, int* b); int main() { /* C语言传参机制 */ int a = 100; int b = 200; swap1(&a, &b); printf("主函数中a=%d ", a); printf("主函数中b=%d ", b); getchar(); } void swap1(int* a, int* b) { int temp; temp = *a;//*与&互相抵消,这里意思是100赋值给temp *a = *b; *b = temp; printf("传址swap函数中a=%d ", *a); printf("传址swap函数中b=%d ", *b); }
运行结果:
这里结果和上面不同也很简单,这里我们使用了指针,指针用来指向你要的资源地址,我们把a,b以&a,&b传入,所以swap1当然拿到我们主函数中的a,b地址了,此时swap1函数
里面的操作,实际上是对于a,b的值进行交换。打个比方,就比方我们是酒店经理,然后客人甲,与客人乙,说要交换房间(原本甲住在a房间,乙住在b房间),所以交换后,
甲住在b房间,乙住在a房间。
(3)传址2(无意间发现,记录一下)
1 void swap(int a,int b); 2 void swap1(int* a, int* b); 3 int main() 4 { 5 /* 6 C语言传参机制 7 */ 8 int a = 100; 9 int b = 200; 10 swap1(&a, &b); 11 printf("主函数中a=%d ", a); 12 printf("主函数中b=%d ", b); 13 14 getchar(); 15 } 16 17 void swap1(int* a, int* b) { 18 int *temp;//此处与上面不一样 19 temp = a; 20 a = b; 21 b = temp; 22 printf("传址swap函数中a=%d ", *a); 23 printf("传址swap函数中b=%d ", *b); 24 }
运行结果:
运行结果分析,你会发现,我们虽然拿到a,b的地址了,但是我们没有实现交换a,b值的功能,思考一下很简单,因为我们swap函数中做的操作不是交换值,而是交换址,
原本我们如果实现地址的交换,那么a,b的值理论上可以成功交换。但是这里我猜想内存地址是一个固定的,不可交换的,我们可以对内存中的值进行
操作,我们是不能对址进行修改的,打比方,我们酒店101和102号房间的位置对调一下可以吗,答案也是不可能,因为总不能把它砸了,重新建筑吧。
所以,我们在原来上面加上打印地址操作,
结果我的猜想只对了一半,因为我说的是不能进行交换址,这个正确,但是这里它们进行操作的是swap函数中a,b的内存地址,我原本猜想是可以成功拿到a,b的地址,实际上我觉得它已经拿到主函数的a,b地址了,直不过在swap函数中进行值输出时,采用了就近原则,而交换地址这种不合法操作为什么不会报错,我又有了一个猜想,可能是如果交换地址,那就默认交换地址中的值。
所以实际上,交换的不是主函数传过来的地址,交换的是swap函数重新分配的地址,我们只是对swap函数进行操作,
并没有对主函数进行操作,所以主函数中a,b值当然不能成功交换……
红色字体,推翻蓝色的猜想:
1 int main() 2 { 3 /* 4 C语言传参机制 5 */ 6 int a = 100; 7 int b = 200; 8 int *a1; 9 int *b1; 10 int *temp; 11 a1 = &a; 12 b1 = &b; 13 printf("交换前主函数中a1的地址=%d ", a1); 14 printf("交换前主函数中b1的地址=%d ", b1); 15 16 temp = a1; 17 a1 = b1; 18 b1 = temp; 19 20 printf("主函数中a=%d ", a); 21 printf("主函数中b=%d ", b); 22 23 printf("交换后主函数中a1的地址=%d ", a1); 24 printf("交换后主函数中b1的地址=%d ", b1); 25 getchar(); 26 }
运行结果:
我们可以看出,地址是可以交换的,所以蓝色字体无效,而为什么地址可以交换,为什么对于程序3主函数的a,b内存拿到的情况下,无法进行址交换呢,因为swap函数运行的,操作的是自己内部的a,b的内存,并没有操作主函数的a,b内存,所以主函数a,b值不变化。
最后总结:
(1)上面的不管是程序1还是程序2,实际上都是进行值交换,只不过是基于不同方式进行值交换而已。程序1使用传值方式,在swap函数中再进行值交换,此时实际交换的是a,b的影分身,而实际上主函数的a,b并没有进行操作;而程序2,我们采用了址传递a,b,再通过主函数的a,b地址进行值交换,这里swap函数中成功对主函数的a,b进行值交换。
(2)而对于第3个程序,我们想要实现的无非就是址交换,把地址交换,但实际上,我们交换的还是swap函数的a,b地址,没有对主函数a,b进行操作,所以主函数a,b值无变化。
(3)对于猜想部分,即蓝色字体,大家看的时候,看看就好,因为毕竟是我自己的想法。