查看文章 |
第四章 函数与程序结构 函数返回值:函数通过return语句向调用者返回值,必要时进行类型转换。 如果函数定义省略了返回值类型,则默认为int类型。 函数之间的通信途径: 1.参数传递:当一个函数调用另一个函数并为其提供数据时,可将数据作为参数传递。 2.函数返回值:被调用函数通过返回值向调用者返回数据。 3.外部变量:当多个函数需要共享一组数据,而这些函数间不存在调用关系时,可以把这些共享数据定义为外部变量。 UNIX下多个源文件的编译和加载:假设有三个源文件file1.c,file2.c和file3.c,命令 cc file1.c file2.c file3.c; 编译三个源文件,将目标代码放入file1.o,file2.o和file3.o中,并将目标文件加载到可执行文件a.out中。当file1.c出现错误,修改后可以单独重新编译filel.c并与另两个目标文件共同加载,即 cc file1.c file2.o file3.o; 而不必重新编译另两个目标文件。 头文件:对于中等规模的程序,最好用一个头文件存放程序中各部分共享的对象(一些宏定义、函数原型),而较大的程序需要更多的头文件。 静态变量: 局部静态变量:当static用于声明局部变量时,该变量将一直占据存储空间,而不随函数的调用而创建和释放。 外部静态变量:通过static声明外部变量,可以将外部变量的作用域限制在其所在的源文件中,同时其他源文件中的变量名也不会与其发生冲突。 静态变量只被初始化一次。 C预处理器(preprocessor):预处理器是编译过程中单独执行的第一个步骤。 1.文件包含:#include <file1> 按定义的规则查找file1(通常为存放标准库头文件的目录,如Unix中的/usr/include);#include "file2" 在源文件所在目录查找file2(通常为用户自己定义的文件),如果没有则按定义的规则查找。找到file1和file2后该语句将被替换为相应文件内容。file1和file2本身也可能包含#include语句。在较大程序中,可以将一些宏定义和extern声明放在头文件中,并用#include指令将头文件包含在所有源文件中。当头文件发生改变时,所有有关源文件必须重新编译。 2.宏替换(macro substitution):#define name replacement_text 所有程序中出现的name都将被替换为replacement_text(注意出现在双引号中的除外)。替换文本可以是任意字符串,name的作用域从宏定义语句开始到源文件末尾结束。 宏定义也可以带参数,如:#define max(a, b) ((a) > (b)) ? (a) : (b)) 当程序中max(a, b)中的参数a,b被实参替换时,替换表达式中的a,b也将被替换,与普通的max(a, b)相比较,宏替换可以不考虑参数的类型。 标准库函数如getchar、tolower等都是以宏替换形式定义,这样可以免去每次使用时都进行函数调用带来的开销。 可以通过:#undef name 取消宏定义,通常被用来确保被调用的是函数而非宏替换。 3.条件包含(conditional inclusion):使用条件语句对预处理过程进行控制,条件语句的值在预处理执行过程中计算,并根据计算所得值选择不同代码。 #if !define(HDR) #if SYSTEM == SYSV #define HDR "sysv.h" #elif SYSTEM == BSD #define HDR "bsd.h" #else #define HDR "msdos.h" #endif #endif #include HDR
|