4.2 函數調用與參數傳遞

4.2.1 形參與實參

程序4-6 用函數交換變量(正確)

#include<stdio.h> 
void swap(int* a, int* b) 
{  
	int t = *a; 
	*a = *b; 
	*b = t; 
} 
int main() 
{  
	int a = 3, b = 4;  
	swap(&a, &b);  
	printf("%d %d\n", a, b);  
	return 0; 
}

提示

  1. 用int* a聲明的變量a是指向int型變量的指針。賦值a = &b的含義是把變量 b的地址存放在指針a中,表達式*a代表a指向的變量,既可以放在賦值符號的左邊(左 值),也可以放在右邊(右值)。
  2. 注意:*a是指“a指向的變量”,而不僅是“a指向的變量所擁有的值”。理解這一點相當重 要。例如,*a = *a + 1就是讓a指向的變量自增1。甚至可以把它寫成(*a)++。

4.2.5 數組作爲參數和返回值

程序4-7 計算數組的元素和(錯誤)

int sum(int a[]) 
{  
	int ans = 0;  
	for(int i = 0; i < sizeof(a); i++)
    ans += a[i];  
	return ans; 
}

提示

  1. 這個函數是錯誤的,因爲sizeof(a)無法得到數組的大小。?因爲把數組作 爲參數傳遞給函數時,實際上只有數組的首地址作爲指針傳遞給了函數。在只有地址信息的情況下,是無法知道數組裏有多少個元素 的。
  2. 以數組爲參數調用函數時,實際上只有數組首地址傳遞給了函數,需要另 加一個參數表示元素個數。除了把數組首地址本身作爲實參外,還可以利用指針加減法把其 他元素的首地址傳遞給函數。

程序4-8 計算數組的元素和(正確)

int sum(int* a, int n) 
{  
	int ans = 0;  
	for(int i = 0; i < n; i++)    
		ans += a[i];  
	return ans; 
}

程序4-9 計算左閉右開區間內的元素和(兩種寫法)

int sum(int* begin, int* end) 
{  
	int n = end - begin;  
	int ans = 0;  
	for(int i = 0; i < n; i++)    
	ans += begin[i];  
	return ans;
}
int sum(int* begin, int* end) 
{  
	int *p = begin;  
	int ans = 0;  
	for(int *p = begin; p != end; p++)    
		ans += *p;  
	return ans; 
}

4.2.6 把函數作爲函數的參數

例題4-1 古老的密碼(Ancient Cipher, NEERC 2004, UVa1339)

給定兩個長度相同且不超過100的字符串,判斷是否能把其中一個字符串的各個字母重 排,然後對26個字母做一個一一映射,使得兩個字符串相同。例如,JWPUDJSTVP重排後可 以得到WJDUPSJPVT,然後把每個字母映射到它前一個字母(B->A, C->B, …, Z->Y , A>Z),得到VICTORIOUS。輸入兩個字符串,輸出YES或者NO。

提示

  1. 既然字母可以重排,則每個字母的位置並不重要,重要的是每個字母出現的次數。這樣 可以先統計出兩個字符串中各個字母出現的次數,得到兩個數組cnt1[26]和cnt2[26]。
  2. 下一步 需要一點想象力:只要兩個數組排序之後的結果相同,輸入的兩個串就可以通過重排和一一 映射變得相同。這樣,問題的核心就是排序。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章