• C连载20-转换说明中的异常


    一、对字符串使用格式化输出

    #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;
    }
    

    20.1

    • 释义:小数点接数字,代表会输出几个字符,小数点前面的表示占位有几个,负号代表文本左对齐输出。
    • 下面演示几个转换说明不匹配的程序
    #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;
    }
    

    20.2

    • 释义:第一行表示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;
    }
    

    20.3

    • 释义:%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类型的整数,类似的,后面两个变量在进行读取的时候,就会出现错误的情况。

    二、源码:

  • 相关阅读:
    SQL 高级查询(层次化查询,递归)
    IntelliJ IDEA添加注释常用的快捷键
    java配置环境变量
    Python单例模式的4种实现方法 ++ redis pool的一种单例实现方式
    MYSQL安装配置文件my-small.ini、my-medium.ini、my-large.ini、my-huge.ini文件的作用
    flask中使用flask-sqlalchemy
    Python向Mysql写入时间类型数据
    [慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时
    Cocos2d-x 3.2 创建新应用
    In-App Purchase Programming Guide----(六) ----Working with Subscriptions
  • 原文地址:https://www.cnblogs.com/ruigege0000/p/13562763.html
Copyright © 2020-2023  润新知