1C语言入门_3简单函数_3形参和实参解读

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第 3 章 简单函数 3. 形参和实参
下面我们定义一个带参数的函数, 我们需要在函数定义中指明参数的个数和每个 参数的类型,定义参数就像定义变量一样,需要为每个参数指明类型,参数的命 名也要遵循标识符命名规则。例如: 例 3.4. 带参数的自定义函数
#include
void print_time(int hour, int minute) { printf("%d:%d\n", hour, minute); }
int main(void) { print_time(23, 59); return 0; }
需要注意的是, 定义变量时可以把相同类型的变量列在一起,而定义参数却不可 以,例如下面这样的定义是错的:
void print_time(int hour, minute) {

printf("%d:%d\n", hour, minute); }
学习 C 语言的人肯定都乐意看到这句话:“变量是这样定义的,参数也是这样 定义的,一模一样”,这意味着不用专门去记住参数应该怎么定义了。谁也不愿 意看到这句话:“定义变量可以这样写,而定义参数却不可以”。C 语言的设计 者也不希望自己设计的语法规则里到处都是例外, 一个容易被用户接受的设计应 该遵循最少例外原则(Rule of Least Surprise)。其实关于参数的这条规定也不 算十分例外,也是可以理解的,请读者想想为什么要这么规定。学习编程语言不 应该死记各种语法规定,如果能够想清楚设计者这么规定的原因(Rationale), 不仅有助于记忆,而且会有更多收获。本书在必要的地方会解释一些 Rationale, 或者启发读者自己去思考, 例如上一节在脚注中解释了 void 关键字的 Rationale。 [C99 Rationale]是随 C99 标准一起发布的,值得参考。 总的来说,C 语言的设计是非常优美的,只要理解了少数基本概念和基本原则就 可以根据组合规则写出任意复杂的程序, 很少有例外的规定说这样组合是不允许 的,或者那样类推是错误的。相反,C++的设计就非常复杂,充满了例外,全世 界没几个人能把 C++的所有规则都牢记于心,因而 C++的设计一直饱受争议, 这个观点在[UNIX 编程艺术]中有详细阐述。 在本书中,凡是提醒读者注意的地方都是多少有些 Surprise 的地方,初学者如 果按常理来想很可能要想错, 所以需要特别提醒一下。而初学者容易犯的另外一 些错误, 完全是因为没有掌握好基本概念和基本原理,或者根本无视组合规则而 全凭自己主观臆断所致, 对这一类问题本书不会做特别的提醒,例如有的初学者 看完第 2 章 常量、变量和表达式之后会这样打印π 的值:
double pi=3.1416; printf("pi\n");
之所以会犯这种错误,一是不理解 Literal 的含义,二是自己想当然地把变量名 组合到字符串里去, 而事实上根本没有这条语法规则。如果连这样的错误都需要 在书上专门提醒,就好比提醒小孩吃饭一定要吃到嘴里,不要吃到鼻子里,更不 要吃到耳朵里一样。 回到正题。我们调用 print_time(23, 59)时,函数中的参数 hour 就代表 23,参 数 minute 就代表 59。确切地说,当我们讨论函数中的 hour 这个参数时,我们 所说的“参数”是指形参(Parameter),当我们讨论传一个参数 23 给函数时, 我们所说的“参数”是指实参(Argument),但我习惯都叫参数而不习惯总把 形参、实参这两个文绉绉的词挂在嘴边(事实上大多数人都不习惯),读者可以 根据上下文判断我说的到底是形参还是实参。 记住这条基本原理: 形参相当于函

数中定义的变量,调用函数传递参数的过程相当于定义形参变量并且用实参的 值来初始化。例如这样调用:
void print_time(int hour, int minute) { printf("%d:%d\n", hour, minute); }
int main(void) { int h = 23, m = 59; print_time(h, m); return 0; }
相当于在函数 print_time 中执行了这样一些语句:
int hour = h; int minute = m; printf("%d:%d\n", hour, minute);
main 函数的变量 h 和 print_time 函数的参数 hour 是两个不同的变量,只不过 它们的存储空间中都保存了相同的值 23,因为变量 h 的值赋给了参数 hour。同 理,变量 m 的值赋给了参数 minute。C 语言的这种传递参数的方式称为 Call by Value。在调用函数时,每个参数都需要得到一个值,函数定义中有几个形参, 在调用时就要传几个实参,不能多也不能少,每个参数的类型也必须对应上。 肯定有读者注意到了,为什么我们每次调用 printf 传的实参个数都不一样呢? 因为 C 语言规定了一种特殊的参数列表格式,用命令 man 3 printf 可以查看到 printf 函数的原型:
int printf(const char *format, ...);

第一个参数是 const char *类型的,后面的...可以代表 0 个或任意多个参数, 这些参数的类型也是不确定的,这称为可变参数(Variable Argument),第 6 节 “可变参数”将会详细讨论这种格式。总之,每个函数的原型都明确规定了返回 值类型以及参数的类型和个数,即使像 printf 这样规定为“不确定”也是一种 明确的规定,调用函数时要严格遵守这些规定,有时候我们把函数叫做接口 (Interface),调用函数就是使用这个接口,使用接口的前提是必须和接口保持 一致。
Man Page
Man Page 是 Linux 开发最常用的参考手册,由很多页面组成,每个页面描述一 个主题,这些页面被组织成若干个 Section。FHS(Filesystem Hierarchy Standard)标准规定了 Man Page 各 Section 的含义如下: 表 3.1. Man Page 的 Section Section 1 2 3 4 5 6 7 8 用户命令,例如 ls(1) 系统调用,例如_exit(2) 库函数,例如 printf(3) 特殊文件, 例如 null(4)描述了设备文件/dev/null、 /dev/zero 的作用 系统配置文件的格式,例如 passwd(5)描述了系统配置文件 /etc/passwd 的格式 游戏 其它杂项,例如 bash-builtins(7)描述了 bash 的各种内建命令 系统管理命令,例如 ifconfig(8) 描述
注意区分用户命令和系统管理命令,用户命令通常位于/bin 和/usr/bin 目录, 系统管理命令通常位于/sbin 和/usr/sbin 目录,一般用户可以执行用户命令, 而执行系统管理命令经常需要 root 权限。系统调用和库函数的区别将在第 2 节 “main 函数和启动例程”说明。 Man Page 中有些页面有重名,比如敲 man printf 命令看到的并不是 C 函数 printf, 而是位于第 1 个 Section 的系统命令 printf, 要查看位于第 3 个 Section 的 printf 函数应该敲 man 3 printf,也可以敲 man -k printf 命令搜索哪些页 面的主题包含 printf 关键字。本书会经常出现类似 printf(3)这样的写法,括 号中的 3 表示 Man Page 的第 3 个 Section,或者表示“我这里想说的是 printf 库函数而不是 printf 命令”。

相关文档
最新文档