到現(xiàn)在為止,你只使用了作為stdio.h
頭文件一部分的函數(shù)。在這個練習(xí)中你將要編寫并使用自己的函數(shù)。
#include <stdio.h>
#include <ctype.h>
// forward declarations
int can_print_it(char ch);
void print_letters(char arg[]);
void print_arguments(int argc, char *argv[])
{
int i = 0;
for(i = 0; i < argc; i++) {
print_letters(argv[i]);
}
}
void print_letters(char arg[])
{
int i = 0;
for(i = 0; arg[i] != '\0'; i++) {
char ch = arg[i];
if(can_print_it(ch)) {
printf("'%c' == %d ", ch, ch);
}
}
printf("\n");
}
int can_print_it(char ch)
{
return isalpha(ch) || isblank(ch);
}
int main(int argc, char *argv[])
{
print_arguments(argc, argv);
return 0;
}
在這個例子中你創(chuàng)建了函數(shù)來打印任何屬于“字母”和“空白”的字符。下面是一個分解:
ex14.c:2
包含了新的頭文件,所以你可以訪問isalpha
和isblank
。
ex14.c:5-6
告訴C語言你稍后會在你的程序中使用一些函數(shù),它們實際上并沒有被定義。這叫做“前向聲明”,它解決了要想使用函數(shù)先要定義的雞和蛋的問題。
ex14.c:8-15
定義print_arguments
,它知道如何打印通常由main
函數(shù)獲得的相同字符串?dāng)?shù)組。
ex14.c:17-30
定義了can_print_it
,它只是簡單地將isalpha(ch) || isblank(ch)
的真值(0或1)返回給它的調(diào)用者print_letters
。
ex14.c:38-42
最后main
函數(shù)簡單地調(diào)用print_arguments
,來啟動整個函數(shù)鏈。
我不應(yīng)該描述每個函數(shù)里都有什么,因為這些都是你之前遇到過的東西。你應(yīng)該看到的是,我只是像你定義main
函數(shù)一樣來定義其它函數(shù)。唯一的不同就是如果你打算使用當(dāng)前文件中沒有碰到過的函數(shù),你應(yīng)該事先告訴C。這就是代碼頂部的“前向聲明”的作用。
向這個程序傳入不同的命令行參數(shù)來玩轉(zhuǎn)它,這樣會遍歷你函數(shù)中的所有路徑。這里演示了我和它的交互:
$ make ex14
cc -Wall -g ex14.c -o ex14
$ ./ex14
'e' == 101 'x' == 120
$ ./ex14 hi this is cool
'e' == 101 'x' == 120
'h' == 104 'i' == 105
't' == 116 'h' == 104 'i' == 105 's' == 115
'i' == 105 's' == 115
'c' == 99 'o' == 111 'o' == 111 'l' == 108
$ ./ex14 "I go 3 spaces"
'e' == 101 'x' == 120
'I' == 73 ' ' == 32 'g' == 103 'o' == 111 ' ' == 32 ' ' == 32 's' == 115 'p' == 112 'a' == 97 'c' == 99 'e' == 101 's' == 115
$
isalpha
和isblank
做了檢查提供的字符是否是字母或者空白字符的所有工作。當(dāng)我最后一次運行時,它打印出除了'3'
之外的任何東西,因為它是一個數(shù)字。
下面是使它崩潰的兩種不同的方法:
can_print_it
和 print_letters
的錯誤。main
中調(diào)用print_arguments
時,試著使argc
加1,于是它會越過argv
數(shù)組的最后一個元素。can_print_it
嗎?strlen
函數(shù),讓print_arguments
知道每個字符串參數(shù)都有多長,之后將長度傳入print_letters
。然后重寫print_letters
,讓它只處理固定的長度,不按照'\0'
終止符。你需要#include <string.h>
來實現(xiàn)它。man
來查詢isalpha
和isblank
的信息。使用其它相似的函數(shù)來只打印出數(shù)字或者其它字符。