char的整型提升与%d或%u打印结果讲解

  本博客讲解char的整型提升与char类型数据在%d与%u格式下的打印结果,想了解short的整型提升也可以看,因为两种提升的原理相同。废话不多说,开讲!!!

  1.整型提升的概念

    整型提升是C程序设计语言中的一项规定:在表达式计算中,各种整型要提升为int类型,如果int类型不足以表示则要提升为unsigned int类型;然后执行表达式的结果。(coming from百度百科)

    由于char所占字节不足4,所以在运算或打印时先要进行整型提升

  2.整型提升的分类

 (1)有符号位:有符号位的整型数据在整型提升时要求符号位(最高位)不变,前面待补位全部补上符号位。总之,负数补1,正数补0;

 (2)无符号位:无符号位的整型数据在整型提升时要求前面待补位全部补上0即可。

      3.原码--反码--补码

    在正式讲解整型提升前,我觉得非常有必要讲一下三码。一般而言,在整型中有符号数的正数与无符号数在内存中存储时三码相同,而有符号数中的负数在内存中存补码。

          4.整型提升的步骤

    (1)将整型数据转化int类型下的内存存储形式,这里以-1为例,(注意这里无需关心数据的类型),比如char a=-1与unsigned char a=-1,它们的数据转化都一样:

        10000000000000000000000000000001--  -1的原码

        1111111111111111111111111111111111110--  -1的反码

        1111111111111111111111111111111111111--   -1的补码

   因为负数在内存中存补码,所以其存储形式为11111111111111111111111111111111

  (2)得到该数据在其数据类型中的存储形式:

     由于char与unsigned char类型占一个字节,所以它们的数据在存储时要截取int类型存储形式的后八位,因此-1在char与unsigned char类型中的存储形式是11111111

    (3)start整型提升

    {1}有符号位的整型提升

   由于char代表有符号位类型,而且11111111的最高位是1,所以待补位全补1

11111111->11111111111111111111111111111111

     {2}无符号位的整型提升

  由于unsigned char代表无符号位类型,所以待补位全补0

11111111->00000000000000000000000011111111

  (4)不同打印格式下的不同结果

     {1}%d--打印有符号位的十进制整型数

   由于11111111111111111111111111111111的最高位是1,是负数,而负数在内存中存补码,欲得其值先补转原:

    11111111111111111111111111111111--补码

    11111111111111111111111111111110--反码

    1000000000000000000000000001--原码

最终打印结果为-1;

      {2}%u--打印无符号位的十进制整型数

   由于无符号数三码相同,所以由00000000000000000000000011111111直接得出结果为255

    5.精算例题讲解----带你实战一波

 例一:

int main()
{
	unsigned char a =-1;
	printf("%d %u", a, a);
	//答案:  255   255
	return 0;
}
//11111111--  -1在unsigned char中的存储形式
//整型提升后,见下
//00000000000000000000000011111111--整型提升后无符号数三码相同,所以无符号数的两种打印格式的结果相同

例二:

int main()
{
	char a = 32;
	//10000000-a在char类型中的存储形式
	//a是有符号类型数据,整型提升后,见下
	//111111111111111111111111100000000-补码,也是a整型提升后在内存中的存储形式
	//111111111111111111111111011111111-反码
	//100000000000000000000000100000000-源码
	    printf("%d %u",a,a);
//      答案: -128  4294967168
		//可见由于a在char数值范围内的%d打印结果是其本身,即-128->127
	return 0;
}

例三:

int main()
{
	int i;
	char a[1000];
	for (i = 0; i < 1000; i++)
	{

		a[i] = -1 - i;
	}
	//printf("c=%d", strlen(a));
	//求c的值
//数组a的元素是char类型,每一个元素占一个字节
//i:0->999时,a的元素:-1 ->-1000;
//看到这里,大家是不是觉得答案就是1000呢?错了,听我开讲。
//我们知道i从0到127时,a[i]的值都是其本身,可是从a[128]=-129开始,你们看看它们的结果
printf("%d %d %d %d %d", a[128], a[129], a[254], a[255] , a[256]);
//    a[128]=127 a[129]=126 a[254]=1  a[255]=0   a[256]=-1
//看到没,i从128到256时,a[i]的结果居然循环了
//而strlen函数是用于打印字符串长度的,一旦碰到'\0'便会停止打印(所打印的长度不包括'\0'),而'\0'的ASII码值为0,
//所以strlen打印字符串一直到a[255]=0,所以答案结果为c=255;
	return 0;
}

你可能感兴趣的:(c语言,c语言)