C語言中交換兩個整數的值之傳值調用和傳址調用

       在C語言中,一說到交換兩個整數的值,大家第一反應可能是這樣的代碼。定義一個第三方變量來輔助交換。
#include<stdio.h>
int main()
{
	int num1 = 10;
	int num2 = 20;
	int tmp = 0;
	tmp = num1;
	num1 = num2;
	num2 = tmp;
	printf("num1 = %d num2 = %d\n",num1,num2);
	return 0;
}

       這個運行結果我就不拿出來了,他是符合我們預期結果的。那麼,如果要求,不允許定義第三變量交換兩個整數的值,你會怎麼做呢?
       那有些人可能會說,不定義第三變量,可以啊,我在主函數外部再寫一個Swap交換函數,通過調用函數來交換兩個數的值嘛!於是,就有了這樣的代碼
#include<stdio.h>
int main()
{
	int num1 = 10;
	int num2 = 20;
	int Swap(int x,int y);
	Swap(num1,num2);
	printf("num1 = %d num2 = %d\n",num1,num2);
	return 0;
}
int Swap(int x,int y)
{
	int tmp;
	tmp = x;
	x = y;
	y = tmp;
	return 0;
}

      那麼我們來看一下運行結果
      

       顯然這個函數並沒有達到預期的效果,那麼問題來了,這是爲什麼呢?我明明調用了這個函數呀,怎麼就沒有交換數值呢?
       這個問題我們先放下,我們先來看一下程序運行過程以及數值和內存的變化情況
       
       我們可以看到,我們在調用交換函數的時候,主函數中定義的兩個整數num1和num2的值的確傳給了函數的參數x和y,但是,num1和num2的地址與x和y的地址是沒有關聯的,這說明num1和num2給Swap函數提供的是當前這兩個變量的值的一份臨時拷貝,當這兩個變量當前的值被函數調用的時候,這兩個變量就與函數沒有關係了。
       接下來,函數內部的程序一行行運行結束之後
      
       我們可以看到函數內部的x和y的值交換了。
       再跳回到主函數進行輸出,這個時候輸出的num1與num2依舊是主函數中被賦給的值,即傳給函數形參的值,而不是通過函數運行之後的值,所以這個代碼沒有輸出我們預期的結果。
       這也就是我們常說的傳值調用。
       經過修改之後,我們又寫出了這樣得代碼
#include<stdio.h>
int main()
{
	int num1 = 10;
	int num2 = 20;
	int Swap(int *x,int *y);
	Swap(&num1,&num2);
	printf("num1 = %d num2 = %d\n",num1,num2);
	return 0;
}
int Swap(int *x,int *y)
{
	int tmp = 0;
	tmp = *x;
	*x = *y;
	*y = tmp;
	return 0;
}

       我們先來看一下運行結果
      
      毫無疑問,這個結果實現了我們的期望值。我們再來看一下內存地址的情況
      
      這裏我們可以看到,num1與num2的地址和x與y的地址相同,也就是說,在調用num1和num2這兩個變量的值的時候,我們通過調用這兩個變量的地址來引用其地址裏存放的值,這個時候進入到函數內部,把x地址裏的值賦給變量tmp,把y地址裏的值賦給x,再把tmp的值賦給y,也就是說把x地址裏的值放到了y地址裏,把y地址裏的值放到x地址裏,然後返回到主函數中,因爲num1與x的地址相同而num2與y的地址相同,所以當x與y的值變了的時候,num1與num2的值也發生了變化,於是輸出結果也就是我們所預期的交換後的值。這就是傳址調用。
      說到這裏,也許有人又有問題了,你不是說不允許定義第三變量嗎?調用的交換函數裏定義的tmp不就是第三變量嘛?
       好啦好啦。我的錯啦。這回真的不定義第三變量了。提供兩種方法
       第一,加減法運算
             num1=num1+num2
             num2=num1-num2
             num1=num1-num2
#include<stdio.h>
int main()
{
	int num1 = 35;
	int num2 = 20;
	num1 = num1+num2;
	num2 = num1-num2;
	num1 = num1-num2;
	printf("num1 = %d num2 = %d\n",num1,num2);
	return 0;
}

      第二,異或運算
      首先,我來給大家介紹一下異或運算。相異爲1,相同爲0。比如3和5異或,即                011^101,
                   011----->3
                   101----->5
                   異或之後
                   110----->6
                   101
                   異或之後
                   011------>3
                   110
                   異或之後
                   101------>5
       我們可以發現兩個數與這兩個數異或的結果,這三個數每兩兩異或,結果都是第三個數。於是這個代碼就寫出來了
#include<stdio.h>
int main()
{
	int num1 = 10;
	int num2 = 20;
	num1 = num1^num2;
	num2 = num1^num2;
	num1 = num1^num2;
	printf("num1 = %d num2 = %d\n",num1,num2);
	return 0;
}
      這兩個程序結果都是正確的。如期的交換了兩個變量的值。

      如有錯誤,歡迎指出!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章