程序 5-3-3
%p 是 printf 语句中的格式控制字符的一种,表示将一个数据按照地址的格式来输出,
而&则是取地址操作符,&x 表示取到 x 的地址。因此,第 6 行和第 13 行的意思就是,取到 x
的地址,并把这个值按地址的格式输出。虽然程序 5-3-3 的最终运行结果是无法预计的,但
是至少有一点可以肯定,那就是第 6 行和第 13 行输出的数据肯定不同,读者可亲自上机感
受。
形参不一定全是变量,也可以出现常量,如果出现了常量的参数,那么函数就不能对这
个参数做修改。
程序 5-3-4
程序 5-3-4 展示了常量作为函数参数的做法,如果我们试图在第 11 行和第 12 行之间插
入一行对 x 赋值的语句,程序将会不能成功运行。此外,函数的返回值也是可以用 const 限
定符来修饰的,只不过在绝大多数情况下,这样做是毫无意义的,只有在函数返回值是一个
指针(指针是后面章节的内容)的时候,才有可能会这样做。
函数的调用是有一定代价的,程序需要在内存的一段代码中跳转到另外一段代码,并且,
任何一个函数在执行的时候都会被分配一定的内存空间。对于一些功能简单的函数,我们可
以通过一些手段来节约这一点函数调用的开销,而这个手段就是#define 预编译指令。
对于#define 指令,我们早已不再陌生,不过之前我们眼里的#define 都是用来定义常
量的,如果读者以为它的功能仅限于此的话,那么就太小看这个功能强大的工具了。5.2 节
我们说过,#define 指令在“定义”常量的时候并不是像定义用 const 修饰的常量那样开辟
一段内存空间来储存数据,而是在预编译阶段进行文本的替换,虽然我们眼里看起来和常量
没什么区别,实际上在编译器看来是有本质区别的。那么,既然#define 能够用于将一些符
号替换成数字,它也能实现将符号替换成代码。我们说预编译阶段是发生在编译之前的,所
以#define 实现的函数实际上就只是一些简单的语句罢了,并没有被编译器单独划成一个模
块,因此,在执行用#define 实现的“函数”时就不会有函数调用的开销。
01 include <stdio.h>
02 void fun(const int);
03 int main()
04 {
05 int x = 10;
06 fun(x);
07 getchar();
08 return 0;
09 }
10 void fun(const int x)
11 {
12 printf("%d",x);
13 }
01 #include <stdio.h>
02 #define PRODUCT(a,b) a*b
03 int main()
04 {
05 printf("%d", PRODUCT (2,3));
06 getchar();
07 return 0;
08 }