数据类型和转换匹配

数据类型

long long 8字节,long(unsigned long) 4字节(16和32位编译器)或8字节(64位编译器),short 2字节,

int(unsigned int) 2字节(16位编译器)或4字节(32和64位编译器) ,char 1字节,float 4字节,double 8字节
<1>整形变量范围
8位  : signed -128到127        unsigned 0 到 255
16位 :signed -32768到32767      unsigned 0到65535
32位 :signed-2147483648到2147483647   unsigned 0到4294967295
对于较小的整形常量,可以通过加后缀L变成long类型,LL long long类型,UL,ULL
如: #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
 这个表达式将使一个16位机的整型数溢出,因此要用到长整型符号L,告诉编译器这个常数是的无符号长整型数。
 
<2>浮点型
<a>浮点常数(指数记数法):
可以没有小数点(2E5)或指数部分(1.3),但不能同时没有二者;可以省略纯小数部分(3.E16)或整数部分(.45E-6)但不能同时省略。
ey:5.6*10^(-5) ---->   5.6E-5  浮点常量中不要使用空格
默认情况下,编译器将浮点常量当做double类型;可以通过f或F后缀使编译器把浮点常量当做float型以减少运算量。
十六进制浮点常量表示:使用前缀0x,0X,接着是十六进制数字,然后是p或P,最后是2的指数。ey:  0xa.1fp10
<b>float 至少6位有效数字,取值范围至少10^-37到10^37     32位
double 至少13位有效数字,                                              64位
 
<3>_Bool类型(C99):只可以具有值1(真)和0(假)
_Bool a;a=scanf("%d",&num)==1;     注:运算符==比=的优先级高,可以不外加括号。
C99 还提供stdbool.h,该头文件可以使用bool代替_Bool,把true和false定义为值位1和0的符号常量。
 
转换说明符和修饰符
<1>printf()转换说明符及动作的打印输出:
转换说明                 输出
%a,%A                    浮点数,十六进制数字和p或P记数法(C99)
%e %E                     浮点数,e或E记数法
%f                           浮点数,十进制记数法
%g %G                    根据数值不同自动选择%f或%e。%e在指数小于-4或者大于等于精度时使用
%c                          一个字符
%s                          字符串
%p                          指针
%d(%i) %u             有符号十进制整数和无符号十进制整数
%o %x %X              无符号八进制整数和使用0f(0F)的无符号十六进制整数
%%                         打印一个%号
注意:转换说明符写错时,编译器不出错。
<2>printf格式转换修饰符
<3>printf格式转换修饰标志
<4>scanf格式转换说明符
 
#include <stdio.h>
void main()
{
 double i=3345.61;
 char a[12]="haha";
 printf("*%f* ",i);
 printf("*%e* ",i);
 printf("*%g* ",i);
 printf("*%010.3f* ",i); //左补0,字段宽度最小为10,对%e%E%f:小数点右边打印3位数字
 printf("*%10.3e* ",i);
 printf("*%10.3g* ",i); // 右对齐,对%g%G:有效数字的最大位数是3
 printf("*%-10.3s* ",a); //左对齐    ,对%s:最多能打印3个字符
}
输出结果:
*3345.610000*
*3.345610e+03*
*3345.61*
*003345.610*
* 3.346e+03*
*   3.35e+03*
*hah            *
 
不匹配的转换
<1>不匹配的整数转换
#include <stdio.h>
void main()
{  short num = 336, mnum = -336;
   int word=65618;
   printf("%hd,%hu ",num,num); //hd 表输出数据类型为short (signed) int  ;hu short unsigned (int)
   printf("%hd,%hu ",mnum,mnum); 
   printf("%d,%c ",num,num); // d (signed) int  c char
   printf("%d,%hd,%c ",word,word,word); 
}
输出结果:
336,336
-336,65200
336,P
65618,82,R
第一行中0到32767的有符号数与无符号数是一样的
第二行中无符号数的32768到65535对应有符号数的-32768到-1 ,即65535代表-1,65200=65536-336代表-336。在这种表示方法中,一个数字可以被解释成两种不同的值(有符号和无符号数)
第三行和最后一行:把short int(2个字节)转换为char(一个字节)取低八位,“以256取模”用336除以256取其余数80即为char
     打印比系统允许的最大的short int(32767)大的int整数65618,取低16位,“以65536取模”,用65618除以65536取其余数位82。若余数在32767和65536之间会被打印成负数
 
<2>不匹配的浮点数转换和自动转换原则
#include<stdio.h>
void main()
{ float n1 = 3.0; 
 double n2 = 3.0;
 long n3 = 2000000000;
 long n4 = 4000000000;
 printf("%e %e ",n3,n4);
 printf("%.1e %.1e %.1e %.1e ",n1,n2,n3,n4);
 printf("%ld %ld %ld %ld",n1,n2,n3,n4);
}
-7.853020e+223 0.000000e+000
3.0e+000 3.0e+000 -7.9e+223 0.0e+000
0 1074266112 0 1074266112
第一二行说明:
a.当被用作printf()的参数时,float被转换成double。n1会 被扩展到8字节,以使printf能正确显示它
b.%e没有将整数转换为浮点数。
最后一行:如果printf在其他地方出现不匹配错误,即使正确的说明符也会产生虚假的结果。
 
<3>自动转换原则
void foo(void)
{
  unsigned int a = 6;
  int b = -20;
  (a+b > 6) ? puts("> 6") : puts("<= 6");
}
答案是输出是 ”>6”
原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。 因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。
 
 
 
注:
<1>N.A:表示“本栏目(对我)不适用”,在没有东西可填,空格也不许有的时候就要写N/A,n/a,n.a,N.A
<2>可移植的类型:inttypes.h
<3>printf()的参数传递:
计算机根据数据的类型把这些值放入堆中(n1,n2占8字节,n3,n4占4字节);
printf读取时是根据转换说明符取读取(%ld说明符指出,printf应读取4个字节作为它的第一个值)
原文地址:https://www.cnblogs.com/zhoutian220/p/4006899.html