1. 程式人生 > >C語言中交換兩個整數的值之傳值呼叫和傳址呼叫

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;
}
      這兩個程式結果都是正確的。如期的交換了兩個變數的值。
      如有錯誤,歡迎指出!