C语言入门学的是谭浩强,至于这本书,如果只是为了考试学学还是不错的,但是若以后要从事编程工作与C打交道比较多的话,个人认为仅以此书入门是不够的。
C primer plus 是本更不错的入门书籍,讲得很全面。所以这本书也比较厚,有点难啃... 系列文章参考于此书。
printf() 函数基础扩充:
想必大家的第一个C语言程序都应该是下面这个在屏幕上输出hello world 的经典程序吧。
#include<stdio.h> int main() { printf("hello world!"); }
这里打印出的是一个字符串,当然我们也可以用printf来打印出其他参量。printf打印变量取决于参量的类型,例如在打印整数时使用%d符号,打印字符时用%c符号。这些符号叫做转换说明,它们指定了如何把数据转换成可显示的形式。
切记给控制字符串后面的参数列表中的每个项目都使用一个转换说明,也就是转换说明要和参量一一对应,如
printf("a is %d, b is %d",a); //错误
printf("a is %d, b is ",a,b); //错误
printf("a is %d, b is %d",a,b) //正确
再而是要切记转换说明的类型要和参量的类型相匹配
#include <stdio.h>
int main()
{
float n1 = 3.0;
double n2 = 3.0;
long n3 = 1234567890;
long n4 = 2000000000;
printf("%f %f ",n1,n2); //正确匹配
printf("%ld %ld ",n3,n4);
printf("%ld %ld %ld %ld ",n1,n2,n3,n4); //错误匹配
}
上面代码运行结果如下(window7环境下, 其他平台环境上可能会有不同结果)
可见第三个匹配错误的输出语句显示出了一些奇怪的数字,为什么会出现这样的结果呢,这个printf的输出机制和参数传递机制有关
参数传递机制随实现的不同而不同,下面参数传递是在windows系统中的工作原理,如下面的函数调用
printf("%ld %ld %ld %ld ",n1,n2,n3,n4);
该调用告诉计算机把变量n1、n2、n3、n4的值传递给计算机,计算机把他们放置到堆栈的一块内存区域中来实现。计算机根据变量的类型而非转换说明符把这些值放到堆栈中。所以在堆栈中n1占用8个字节(当被作为printf的参数时,float被转换为double),n2占8个字节,n3、n4分别占4个字节。
然后控制转移到printf()函数,该函数从堆栈中把这些值读出来,但是在读取的时候是按照转换说明符去读的。%ld指出应该读取4个字节,所以printf()在堆栈中读取前4个字节作为他的第一个值,也就是n1的前半部分,被解释成一个long型,下一个%ld指出再读取4个字节作为第二个值,同理n1的后半部分也被解释成了一个long型。同样,%ld的第三个和第四个实例使得n2的前半部分和后半部被分别解释成long型。所以虽然n3和n4的说明符正确,但printf()仍读取了错误的字节。
printf()的返回值:
printf是有返回值的,它返回所打印的字符的数目(所有打印出的字符,包含空格,不可见的换行字符)。如果有输出错误,便会返回一个负数。
其返回值是打印输出用途的附带功能,通常不怎么用。使用返回值得一个可能原因是检查输出错误,常用于向文件中输出而非向屏幕输出的情况。
参考:C primer plus