Storage of integer data in memory(1)

Table of contents

1. Types of data

2. Storage of shaping in memory

2.1 Inverse code complement of original code

2.2 Big endian little endian

3. Storage instance

3.1 Shaping range

3.2 Signed integer and unsigned integer 

3.3 Characteristics of data storage


Through the study of the storage of data in the memory a few days ago, I specially summarized it.

1. Types of data

plastic surgery
     char           character data type occupies 1 byte
     short short integer occupies 2 bytes
     int integer occupies 4 bytes
     long long integer occupies 4 or 8 bytes
     long long Longer integer occupies 8 bytes
floating point
     float Single-precision floating-point number occupies 4 bytes
    double Double-precision floating-point number occupies 8 bytes 

2. Storage of shaping in memory

       We know that the creation of variables is to open up address space in memory, and the size of the space is determined by different data types. How is the data stored in memory?

     2.1 Inverse code complement of original code

     We know that integers are stored in two's complement (binary) form in memory

      The original code, inverse code, and complement code of positive numbers are all the same.

For example int a = 1 original code 00000000 00000000 00000000 00000001

                                Inverse 00000000 00000000 00000000 00000001

                                Complement 00000000 00000000 00000000 00000001

      The complement of a negative number needs to be reversed except for the sign bit to obtain the complement, and then add 1 to the complement to finally obtain the complement.

l For example int a = -1 original code 10000000 00000000 00000000 00000001

                               Inverse 111111111 111111111 111111111 111111110

                               Complement 111111111 111111111 111111111 111111111

Let's go to the memory to see, if you are using the VS compiler, you can see it according to the following steps:


#include<stdio.h>
int main() {

	int a = 10;
	int b = 20;

	return 0;
}

 The above is a simple piece of code for debugging. Press ctrl+F11 or F11 to enter debugging.

Then continue with ctrl+F11 or F11 until the arrow reaches return 0.

Then press the following operation to find the memory .

Then enter &a and press the Enter key, &b and press the Enter key 

 The data in VS memory is displayed to us in hexadecimal.

It is not difficult for us to conclude that the hexadecimal system of a = 10 10 is 00 00 00 0a

                      The hexadecimal system of b = 20 20 is 00 00 00 14

By comparing with what is displayed in the above memory, the old feeling order is very awkward. Through the query, it is found that this is related to big endian and small endian .

2.2 Big endian little endian

 What is big endian little endian?
 The byte order of big-endian data is stored in low-order in 
 high high-order in low-address.

According to online information, big-endian storage or little-endian storage is related to the compiler. If we want to know whether the compiler we use is big-endian or little-endian, we can write a program to achieve it. Here I choose to use 1, but other numbers can also be used.

                           Low High
     if little endian 01 00 00 00 
     if big endian 00 00 00 01

#include<stdio.h>
int main() {

	int a = 1;

	char* p = &a;
	if (*p == 1) printf("小端");
	else printf("大端");

	return 0;
}

3. Storage instance

Let's give some code examples for a deeper understanding.

3.1 Shaping range

    Query the value range of variables through code

#include<stdio.h>
#include<limits.h>
int main() {
	
	INT_MAX;

	return 0;
}

Point the mouse to INT_MAX, right-click, and then click Go to Definition. 

3.2 Signed integer and unsigned integer 

int a = 1; signed integer

unsigned int a = 1; unsigned integer

What is the output of the following piece of code?

#include <stdio.h>
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;
}

My understanding:

//#include<stdio.h>
//int main() {
//
//                          //因为-1是一个整形数int    放在char里会发生截断      
//                          //11111111 11111111 11111111 11111111  (-1的补码)
//						    //11111111 (对补码进行截断,截断了后八位)
//	char a = -1;
//	//11111111
//
//	signed char b = -1;
//	//11111111
//
//	unsigned  char c = -1;
//	//无符号位时,截断后高位补0
//	//11111111
//	//00000000 00000000 00000000 11111111  高位补0后的值 255  最高位为0,表示正值 即无符号
//	printf("%u %d %d",a,b,c);  //最终输出 -1 -1 255
//
//
//	return 0;
//}

What do the following two pieces of code output?

//1
#include <stdio.h>
int main()
{
    char a = -128;
    printf("%u\n",a);
    return 0;
}



//2
#include <stdio.h>
int main()
{
    char a = 128;
    printf("%u\n",a);
    return 0;
}

%u is to print integer and unsigned output decimal number

 reason:

//#include<stdio.h>
//int main() {
//
//char a = -128;
10000000 00000000 00000000 10000000  -128的原码
11111111 11111111 11111111 01111111  -128的反码
11111111 11111111 11111111 10000000  -128的补码
10000000     因为 a为char型  所以对-128的补码进行截断
11111111 11111111 11111111 10000000  整形提升 由于符号位为1 故高位补位时全补1 
//                                       整形提升 高位补0还是1 取决于截断后的最高符号位 
//
//char a1 = 128;
//printf("%u %u",a,a1);    //%u  打印整形(故需要整形提升) 无符号输出十进制数
//	return 0;
//}

3.3 Characteristics of data storage

Let's try to run the following pieces of code:

#include<stdio.h>
int main(){

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

    return 0;
}
#include <stdio.h>
unsigned char i = 0;
int main()
{
    for(i = 0;i<=255;i++)
   {
        printf("hello world\n");
   }
    return 0;
}

Under normal circumstances, we would think that the first code will stop when it outputs from 9 to 0, and the second one will stop after printing 256 hello world, but is this really the case?

by running

 After running, it turned out to be an endless loop.

For the sake of observation, let's add some code:

#include<stdio.h>
#include<windows.h>
int main() {
	unsigned int i;
	for (i = 9; i >= 0;i--) {

		printf("%u\n",i);
      Sleep(1000);

	}
return 0;
}

 Run as follows:

It is not difficult for us to understand from 9 to 0, but how did the number become 4294967295 after 0?

 Through observation, we know that the variable i is an unsigned integer, that is, the value range of i is from 0 to a large number, so i will never take a negative number, so it will infinitely loop, when it is reduced to -1

      Original code 10000000 00000000 00000000 00000001

      Inverse code 111111111 111111111 111111111 111111110

      Complement 111111111 111111111 111111111 111111111

And because %u is an unsigned decimal number, so

4294967295 is 111111111 111111111 111111111 111111111

What if you replace %u with %d?

0 followed by -1?

This is because %d outputs a signed decimal number, so 111111111 111111111 111111111 111111111 is the complement of -1 at this time

  Complement 111111111 111111111 111111111 111111111

  Inverse code 111111111 111111111 111111111 111111110

  Original code 10000000 00000000 00000000 00000001

Through the above, we come to a law: cycle

 As shown in the figure above, when the char type is unsigned, the value of 0 minus 1 is 255, and the value of 255 plus 1 is 0, that is, 0---255 is a cycle.

                    When the char type is signed, the value of 127 plus 1 is -128, and the value of -128 minus 1 is 127, that is, -128---127 is a cycle.

Guess you like

Origin blog.csdn.net/m0_73381672/article/details/131013016