[C language advanced 2 - data storage (2) - shaping improvement]


foreword

This article continues to learn the relevant knowledge points of data storage in memory.

  • data storage
  • Integer boost

3. Knowledge point practice of data storage

Learn the knowledge points of data storage in memory through a few exercises, and first review the knowledge points of shaping and upgrading that you have learned before: [C Language Basics 9 - Detailed Operator Description (2)] 12.1 Shaping and Improvement

Integer promotion is promoted according to the sign of the data type of the variable

  1. The integer promotion of negative numbers, the most significant bit is supplemented by the sign bit, i.e. 1, for example
char a=-1;
11111111 截断后的补码
11111111111111111111111111111111 整形提升后
  1. The integer promotion of positive numbers, the highest bit is supplemented by the sign bit, that is, 0, for example:
char a=1;
00000001 截断后的补码
00000000000000000000000000000001 整形提升后
  1. The integer promotion of unsigned types, the highest bit directly supplements the sign bit, that is, 0, for example:
unsigned char c = -1;
11111111 截断后的补码
00000000000000000000000011111111  整形提升后

3.1 Exercise 1

int main()
{
    
    
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d, b=%d, c=%d", a, b, c);
	return 0;
}

At first glance, he thought the result was -1, -1, -1, and the following specific analysis :

	1char a = -1;
第一步:-1是整数,在内存的存储形式
	10000000000000000000000000000001  -1原码
	11111111111111111111111111111110  -1反码
	11111111111111111111111111111111  -1补码
第二步:赋值给变量a,截断补码低字节的数据
	11111111
第三步:以%d的形式打印,先要整形提升,
       因为变量a是有符号,且是负数,所以高位补1
	11111111111111111111111111111111  补码
	11111111111111111111111111111110  反码
	10000000000000000000000000000001  原码
第四步:最终打印是的原码,数值是十进制 -1
	
	2signed char b = -1;
	过程同有符号变量a的分析过程
	
	3unsigned char c = -1;
第一步:-1在内存的存储形式
	10000000000000000000000000000001  -1原码
	11111111111111111111111111111110  -1反码
	11111111111111111111111111111111  -1补码
第二步:赋值给变量c,截断补码低字节的数据
	11111111
第三步:以%d的形式打印,先要整形提升,
	因为变量c是无符号的,最高位1为数据位,
	不是符号位,所以高位直接补0
	00000000000000000000000011111111  补码
第四步:因为正数三码相同
	最终打印的是原码,数值是十进制255

The result is shown below:
insert image description here

3.2 Exercise 2

int main()
{
    
    
	char a = -128;
	printf("%u\n", a);
	return 0;
}

At first glance, he thought the result was -128, and the following specific analysis :

	char类型 有符号类型数据范围 -128-127
	char a = -128;
第一步:-128在内存的存储形式
	10000000000000000000000010000000 原码
	11111111111111111111111101111111 反码
	11111111111111111111111110000000 补码
第二步:赋值给char 变量a,发生截断,取低字节数据
	10000000 - a
第三步:打印%u,首先进行整形提升
	因为变量a是有符号,且是负数,所以高位补充符号位,即补1
	11111111111111111111111110000000 补码 负数
第四步:%u,认为是无符号数据,即正数。最高位1为数据位
	11111111111111111111111110000000 补码 正数
第五步:因为正数三码相同
	最终打印的是原码,数值是十进制4,294,967,168
	

The result is shown below:
insert image description here

3.2 Exercise 3

int main()
{
    
    
	char a = 128;
	printf("%u\n", a);
	return 0;
}

At first glance, he thought the result was 128. The following is a detailed analysis :

第一步:整形128在内存的存储形式
	00000000000000000000000010000000 原码=反码=补码
第二步:赋值给char类型 a,发生截断,取低字节数据
	10000000 - a
第三步:按照%u打印,先对a进行整型提升,
	因为变量a是有符号,且是负数,所以高位补充符号位,即补1
	11111111111111111111111110000000 补码 负数
第四步:%u,认为是无符号数据,即正数。最高位1为数据位
	11111111111111111111111110000000 补码 正数
第五步:因为正数三码相同
	最终打印的是原码,数值是十进制4,294,967,168

The result is shown below:
insert image description here

3.4 Exercise 4

int main()
{
    
    
	int i = -20;
	unsigned int j = 10;
	printf("%d\n", i + j);
	return 0;
}

At first glance, he thought the result was -10, and the following specific analysis :

第一步:整形 -20 在内存的存储形式
	10000000000000000000000000010100 原码
	11111111111111111111111111101011 反码
	11111111111111111111111111101100 补码
第二步:整形 10 在内存的存储形式
	00000000000000000000000000001010 原码
	00000000000000000000000000001010 反码
	00000000000000000000000000001010 补码
第三步:i + j    补码相加
	11111111111111111111111111101100 -20的补码
	00000000000000000000000000001010 10的补码
	11111111111111111111111111110110 相加后的补码
第四步:最终打印的是原码,数值是十进制 -10
	11111111111111111111111111110101 反码
	10000000000000000000000000001010 原码	

The result is shown below:
insert image description here

3.5 Exercise 5

int main()
{
    
    
	unsigned int i = 0;
	for ( i = 9	; i >=0; i--)
	{
    
    
		printf("%u\n", i);
	}
	return 0;
}

At first glance, he thought the result was 9 to 0, a total of 10 numbers, the following specific analysis :

  1、i从90时,
	是正常的输出90
  2、i=-1时
第一步:-1是整数,在内存的存储形式
	10000000000000000000000000000001  -1原码
    11111111111111111111111111111110  -1反码
	11111111111111111111111111111111  -1补码
第二步:-1赋值给无符号类型时,认为最高1为数据位
	11111111111111111111111111111111  变成的正数的补码了
	数值大于0,又进入循环了,所以是死循环

The result is shown below:
insert image description here

3.6 Exercise 6

int main()
{
    
    
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
    
    
		a[i] = -1 - i;
	}
	printf("%d\n", strlen(a));//字符串长度,字符'\0'之前的字符个数
	printf("%d\n", sizeof(a));//字符串中字符的个数
	return 0;
	
}

At first glance, he thought the result was 1000, 1000. The following specific analysis :
insert image description here

	char类型 有符号类型数据范围 -128-127
  1、i从0127时,
	是正常的输出-1 -2 -3 ....-128
  2、i=128时
  a[128]=-129
第一步:-129是整数,在内存的存储形式
	10000000000000000000000010000001 原码
	11111111111111111111111101111110 反码
	11111111111111111111111101111111 补码
第二步:-129 赋值给char类型a[128]时,发生截断,取低字节数据
	01111111 - a[128]=127

insert image description here

strlen obtains the length of the string, which is the number of characters before the character '\0', and when the 256th element a[256]=0, the ASCII code value is 0, which is the ASCII code value of the character '\0', So think that the string is over, strlen(a)=255.

So the element rule of the array is:

  • from -1 to -128,
  • then output 127 to 0
  • Again from -1 to -128
  • then output 127 to 0
  • It's a circle, it's a circle

insert image description here
sizeof(a) finds the number of characters in the string, sizeof(a)=1000:
insert image description here
there are 1000 characters in the array, the 256th element is 0, the ASCII code is the same as the character '\0', that is, the string This ends, strlen(a)=255.
, there are elements from 256 to 999, sizeof(a)=1000. Below is the output.
insert image description here

3.7 Exercise 7

unsigned char i = 0;//无符号类型的数据范围是:0-255
int main()
{
    
    
	for ( i = 0; i <=255; i++)
	{
    
    
		printf("hello world\n");
	}
	return 0;
}

At first glance, I thought that the result was to print 256 lines of hello world. The following specific analysis :

1、i从0255时
	正常打印 hello world
2、当i=256时
第一步:i=256,在内存中的存储形式
	00000000000000000000000100000000 补码
	赋值给无符号char i,发生截断,取低字节数据
	00000000 - i 此时i又满足循环条件了,又陷入死循环了

The result is shown in the figure below:
insert image description here


Summarize

Through 7 exercises to consolidate the knowledge points of data storage, especially the content of integer promotion , pay attention to mastering.

The next article will update the relevant knowledge points of floating-point storage in memory.

Guess you like

Origin blog.csdn.net/taibudong1991/article/details/124039145