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;
}
提示
- 用int* a聲明的變量a是指向int型變量的指針。賦值a = &b的含義是把變量 b的地址存放在指針a中,表達式*a代表a指向的變量,既可以放在賦值符號的左邊(左 值),也可以放在右邊(右值)。
- 注意:*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;
}
提示
- 這個函數是錯誤的,因爲sizeof(a)無法得到數組的大小。?因爲把數組作 爲參數傳遞給函數時,實際上只有數組的首地址作爲指針傳遞給了函數。在只有地址信息的情況下,是無法知道數組裏有多少個元素 的。
- 以數組爲參數調用函數時,實際上只有數組首地址傳遞給了函數,需要另 加一個參數表示元素個數。除了把數組首地址本身作爲實參外,還可以利用指針加減法把其 他元素的首地址傳遞給函數。
程序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。
提示
- 既然字母可以重排,則每個字母的位置並不重要,重要的是每個字母出現的次數。這樣 可以先統計出兩個字符串中各個字母出現的次數,得到兩個數組cnt1[26]和cnt2[26]。
- 下一步 需要一點想象力:只要兩個數組排序之後的結果相同,輸入的兩個串就可以通過重排和一一 映射變得相同。這樣,問題的核心就是排序。