C语言的传值与传址~~

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)对于猜想部分,即蓝色字体,大家看的时候,看看就好,因为毕竟是我自己的想法。

原文地址:https://www.cnblogs.com/hmy-666/p/12839760.html