一、对字符串使用格式化输出
#include<stdio.h>
#define BLURB "Authentic imitation!"
int D20_1_stringf(void) {
printf("[%2s]
", BLURB);
printf("[%24s]
", BLURB);
printf("[%24.5s]
", BLURB);
printf("[%-24.5s]
", BLURB);
return 0;
}
- 释义:小数点接数字,代表会输出几个字符,小数点前面的表示占位有几个,负号代表文本左对齐输出。
- 下面演示几个转换说明不匹配的程序
#include<stdio.h>
#define PAGES 336
#define WORDS 65618
int D20_2_intconv(void) {
short num = PAGES;
short mnum = -PAGES;
printf("num as short and unsigned short:%hd %hu
", num, num);
printf("-num as short and unsigned short:%hd %hu
", mnum, mnum);
printf("num as int and char:%d %c
", num, num);
printf("WORDS as int,short, and char: %d %hd %c
", WORDS, WORDS, WORDS);
return 0;
}
- 释义:第一行表示short十进制数字,和short无符号的十进制数,显然数字大小范围在short内;第二行都是第一个在short范围内,第二个short int是两个自己,负数在内存中是以补码的形式存储,但是%hu可以为它是个正数,所以把负数的补码按照正常二进制给都出来了;第三行和第四行都是超出了相应的范围,对数字进行相应的截断。
二、混淆整形和浮点型,结果会更奇怪
#include<stdio.h>
int D20_3_floatcnv(void) {
float n1 = 3.0;
double n2 = 3.0;
long n3 = 2000000000;
long n4 = 1234567890;
printf("%.1e %.1e %.1e %.1e
", n1, n2, n3, n4);
printf("%ld %ld
", n3, n4);
printf("%ld %ld %ld %ld
", n1, n2, n3, n4);
return 0;
}
- 释义:%e转换说明没有把整数转换为浮点数,首先打印的时候,会转换为八位浮点数,原来的long类型是四位,所以系统还会把相邻的四位内存拿过来,导致意外的数字;第三行没有问题;第四行令人疑惑,即使用对了转换说明也会生成虚假的结果。用%ld转换说明打印浮点数会失败,但是在这里,用%ld打印long类型的数竟然也失败了,问题在于C如何把信息传递给函数,具体情况因编译器实现而异,”参数传递"框中针对一个有代表性的系统进行了讨论。
参数传递:以上面程序的第三行为例进行分析,程序把传入的值放入一个称为栈的内存区域,计算机根据变量类型(不是根据转换说明)把这些值放入栈中。因此,n1被存储在栈中,占8个字节(float类型被转换为了double类型),同样n2也在栈中占有8个字节,而n3和n4分别占用4个字节。然后控制转到printf()函数,该函数根据转换说明(不是根据变量类型)从栈中读取数据,%ld转换说明表示读取4个字节,所以printf()读取栈中前4个字节作为第一个值。这是n1的前半部分,将被解释位一个long类型的整数,根据下一个%ld转换说明,printf()会接着读取4个字节,这是n1的后半部分,将被解释位第二个long类型的整数,类似的,后面两个变量在进行读取的时候,就会出现错误的情况。
二、源码:
- D20_1_stringf.c
- D20_2_intconv.c
- D20_3_floatcnv.c
- https://github.com/ruigege66/CPrimerPlus/blob/master/D20_1_stringf.c
- https://github.com/ruigege66/CPrimerPlus/blob/master/D20_2_intconv.c
- https://github.com/ruigege66/CPrimerPlus/blob/master/D20_3_floatcnv.c
- CSDN:https://blog.csdn.net/weixin_44630050
- 博客园:https://www.cnblogs.com/ruigege0000/
- 欢迎关注微信公众号:傅里叶变换,个人账号,仅用于技术交流