原文:Exercise 14: Writing And Using Functions
到现在为止,你只使用了作为stdio.h头文件一部分的函数。在这个练习中你将要编写并使用自己的函数。
stdio.h
#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; }
在这个例子中你创建了函数来打印任何属于“字母”和“空白”的字符。下面是一个分解:
ex14.c:2
包含了新的头文件,所以你可以访问isalpha和isblank。
isalpha
isblank
ex14.c:5-6
告诉C语言你稍后会在你的程序中使用一些函数,它们实际上并没有被定义。这叫做“前向声明”,它解决了要想使用函数先要定义的鸡和蛋的问题。
ex14.c:8-15
定义print_arguments,它知道如何打印通常由main函数获得的相同字符串数组。
print_arguments
main
ex14.c:17-30
定义了can_print_it,它只是简单地将isalpha(ch) || isblank(ch)的真值(0或1)返回给它的调用者print_letters。
can_print_it
isalpha(ch) || isblank(ch)
print_letters
ex14.c:38-42
最后main函数简单地调用print_arguments,来启动整个函数链。
我不应该描述每个函数里都有什么,因为这些都是你之前遇到过的东西。你应该看到的是,我只是像你定义main函数一样来定义其它函数。唯一的不同就是如果你打算使用当前文件中没有碰到过的函数,你应该事先告诉C。这就是代码顶部的“前向声明”的作用。
向这个程序传入不同的命令行参数来玩转它,这样会遍历你函数中的所有路径。这里演示了我和它的交互:
$ 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做了检查提供的字符是否是字母或者空白字符的所有工作。当我最后一次运行时,它打印出除了'3'之外的任何东西,因为它是一个数字。
'3'
下面是使它崩溃的两种不同的方法:
argc
argv
strlen
'\0'
#include <string.h>
man
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8