当前位置:嗨网首页>书籍在线阅读

20-参数和陷阱

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

3.6 参数和陷阱

有必要再次提醒读者注意 printf() 函数的用法。读者应该还记得,传递给函数的信息被称为参数。例如, printf("Hello,pal.") 函数调用有一个参数: "Hello,pal." 。双引号中的字符序列(如, "Hello,pal." )被称为字符串(string),第 4 章将详细讲解相关内容。现在,关键是要理解无论双引号中包含多少个字符和标点符号,一个字符串就是一个参数。

与此类似, scanf("%d", &weight) 函数调用有两个参数: "%d"&weight 。C语言用逗号分隔函数中的参数。 printf()scanf() 函数与一般函数不同,它们的参数个数是可变的。例如,前面的程序示例中调用过带一个、两个,甚至三个参数的 printf() 函数。程序要知道函数的参数个数才能正常工作。 printf()scanf() 函数用第 1 个参数表明后续有多少个参数,即第 1 个字符串中的转换说明与后面的参数一一对应。例如,下面的语句有两个 %d 转换说明,说明后面还有两个参数:

printf("%d cats ate %d cans of tuna\n", cats, cans);

后面的确还有两个参数: catscans

程序员要负责确保转换说明的数量、类型与后面参数的数量、类型相匹配。现在,C语言通过函数原型机制检查函数调用时参数的个数和类型是否正确。但是,该机制对 printf()scanf() 不起作用,因为这两个函数的参数个数可变。如果参数在匹配上有问题,会出现什么情况?假设你编写了程序清单 3.9 中的程序。

程序清单3.9  badcount.c 程序

/* badcount.c -- 参数错误的情况 */
#include <stdio.h>
int main(void)
{
     int n = 4;
     int m = 5;
     float f = 7.0f;
     float g = 8.0f;
     printf("%d\n", n, m);    /* 参数太多  */
     printf("%d %d %d\n", n); /* 参数太少  */
     printf("%d %d\n", f, g); /* 值的类型不匹配 */
     return 0;
}

XCode 4.6(OS 10.8)的输出如下:

4
4 1 -706337836
1606414344 1

Microsoft Visual Studio Express 2012(Windows 7)的输出如下:

4
4 0 0
0 1075576832

注意,用 %d 显示 float 类型的值,其值不会被转换成 int 类型。在不同的平台下,缺少参数或参数类型不匹配导致的结果不同。

所有编译器都能顺利编译并运行该程序,但其中大部分会给出警告。的确,有些编译器会捕获到这类问题,然而C标准对此未作要求。因此,计算机在运行时可能不会捕获这类错误。如果程序正常运行,很难觉察出来。如果程序没有打印出期望值或打印出意想不到的值,你才会检查printf()函数中的参数个数和类型是否得当。