C語言-進階探討
不定長度參數
有時候函數不知道會有幾個參數要傳進來,例如printf跟scanf
這時候就需要用到不定長度參數,必須引入stdarg.h標頭檔
不定長度引數使用幾個識別字來建立不定長度引數
- va_list
一種特殊的型態,在va_start、va_arg與va_end裡當作參數使用。 - va_start
啟始不定長度引數 - va_arg
讀取不定長度引數 - va_end
終止不定長度引數
要宣告不定長度參數時,要在函數定義時使用’…’,表示要使用不定長度參數,而且告知要傳遞幾個參數
void func(int, ...);
然後在函數裡面使用va_arg取出參數時必須指定用什麼型態取出
va_arg(num_list, double);
以下為範例程式
#include <stdio.h>
#include <stdarg.h>
void func(int, ...);
int main(void) {
double x = 1.1, y = 2.2, z = 3.3;
double a = 0.1, b = 0.2, c = 0.3;
puts("三個參數:");
func(3, x, y, z);
puts("六個參數:");
func(6, x, y, z, a, b, c);
return 0;
}
void func(int length, ...) {
double tmp;
va_list num_list;
va_start(num_list, length);
int i;
for(i = 0; i < length; i++) {
printf("%.2f\n", va_arg(num_list, double));
}
va_end(num_list);
}
執行結果
三個參數:
1.10
2.20
3.30
六個參數:
1.10
2.20
3.30
0.10
0.20
0.30
命令列參數
程式在執行過程中,可以接受外在的參數來執行不同功能
例如在Windows底下的指令copy
copy source.txt target.txt
copy其實是一段程式,source.txt跟target.txt則是命令列參數
在之前的舉例中,main函數的括號總是空白的,而要使用命令列參數就要寫
1 | int main(int argc, char *argv[]) { |
argc是一個整數,紀錄有幾個參數,例如上面的copy程式的argc就是3
每個參數之間都用空白做區隔
而argv就是參數,argv[0]是”copy”,argv[1]是”source.txt”,argv[2]是”target.txt”
而如果你的參數中包含空白,就需要用雙引號””括起來,例如
copy "Hello World.txt" target.txt
這樣argv[0]就是是”copy”,argv[1]是”Hello World.txt”,argv[2]是”target.txt”了
以下舉檔案複製為範例程式
1 |
|
#inline
呼叫函數的時候,會因為需要分配記憶體空間,而產生一些效率上的負擔
為了提高效率,一些小函數可以建議編譯器像巨集一樣展開
這時候就需要用到inline保留字了
在宣告函數原型的時候加上inline,表示建議編譯器展開
如果編譯器判斷採納的話,才會展開程式碼
而判斷的標準視編譯器而定
以下是範例程式
1 |
|
執行結果
5 的平方為 25
static
當變數宣告的時候加上static時,該變數就會一直存在記憶體中直到程式結束
不管離開區塊還是區域都是一樣,以下是範例程式
1 |
|
執行結果
1
2
3
4
5
6
7
8
9
10
static修飾之後表示只有該區域可以看到,例如修飾全域變數或者函數
這樣該變數或該函數只有那個檔案可以使用
使用時機在於此變數或函數不想被其他檔案所使用
或者不同檔案間可以使用相同名字的變數而不衝突
如果修飾在函數裡面,表示只有那個函數可以使用
很適合用來統計函數被呼叫了幾次