How is data stored in memory? (superior)

1. Binary representation of integer data

There are three binary representations of integer data: original code, inverse code, and complement code
1. Original code: represent the binary digits according to the type, the highest bit is the sign bit (1 means negative number, 0 means positive number)
2. Inverse Code: the sign bit of the original code remains unchanged, and the rest are reversed bit by bit;
3. Complementary code: inverted code + 1
;

Pay attention to one point: the original code, inverse code, and complement code of positive and negative numbers are different! ! !
Positive numbers: original code, inverse code and complement code are the same.
Negative number: original code, inverse code, and complement code are changed according to the above conditions

How do the above three expressions? give a simple example

`Create an integer variable num, open up four bytes of space in the memory to store data, four bytes = 32 bits, that is, 32-bit binary

int num = 10;

Original code:
0000000000000000000000000001010
Inverse code:
00000000000000000000000000001010
Complementary code:
0000000000000000000000000001010

int num = -10;
Original code:
1000000000000000000000000001010
Inverse code: (the sign bit remains unchanged, and the rest are reversed bit by bit)
11111111111111111111111111111110101
Complementary code: (inverse code + 1)
11111111111111111111111 11111111110110

Pay attention to three points:
1. What is stored in the memory is complement code.

why?
In computer systems, values ​​are always expressed and stored in two's complement. The reason is that, using the complement code, the sign bit and the value field can be
processed uniformly;
at the same time, addition and subtraction can also be processed uniformly (the CPU only has an adder). In addition, the complement code and the original code are converted to each other, and the operation process
is the same. No additional hardware circuitry is required.

2. It is generally expressed in hexadecimal in memory.

Because 1 hexadecimal digit can represent 4 binary digits, when viewing variables in memory, you only need to look at (32 / 4) 8 digits, which is convenient for viewing.
insert image description here

3. The complement code in the memory is stored backwards.
insert image description here

2. Detailed introduction of data types

What are the basic data types in C language?

char         //字符数据类型,      1个字节大小(以64平台为例)
short        //短整型             2个字节大小
int          //整型               4个字节大小
long long    //更长的整型         8个字节大小
float        //单精度浮点型       4个字节大小
double       //双进度浮点型       8个字节大小
char*        //字符型指针类型     8个字节大小
int*         //整型指针类型       8个字节大小
double       //双精度型指针类型   8个字节大小

1.1 Basic classification of types

Integer family :

char
    unsigned char
    signed char
short
    unsigned short
    signed short
int 
    unsigned int 
    signed int
long
    signed long
    unsigned long
long long
    unsigned long long
    unsigned long long

Why is the char type an integer?
Because when characters are stored, the ASCII code value is stored, which is an integer, so it is classified into the integer family

Floating point family:

float
long float
double
long double

Pointer type family:

int*
char*
float*
double*
void*

empty type:

void //表示空类型(无类型)
     //一般用于函数的返回类型,函数的参数,指针类型

Constructed types: (custom types and variables)

array type type array name []
structure type struct
enumeration type enum
joint type union

1.2 Recognize the difference between signed and unsigned (signed and unsigned)

For the types of the integer family, there is a difference between signed and unsigned. Different compilers recognize different chars, some are defined as signed char, and some are defined as unsigned char; char is defined in
VS2019 The above is signed char. But what is certain is that

short == signed short;int ==signed int等

What is the difference between signed char and unsigned char?

signed char

We know that the char type is a byte (8 bits).
Assuming its binary digits are: 01010111
, the first digit is its sign bit.
The figure below shows all the possibilities of storing eight bits in binary, because the first bit is the sign bit, so we can know that the
value range of sigened char is -128 ~ 127 . And only in this range, the next cycle will be performed for the part beyond.
insert image description here
insert image description here

unsigned char

Each bit in binary is a value bit, there is no sign bit.
Assuming that the binary digit of unsigned char is: 10010101
, the value range of unsigned char octet binary digit is: 0 ~ 255.
Similarly, even if the value increases, it will not exceed this range, and the next cycle will be performed for the excess part.

insert image description here

insert image description here

Understanding this, let's look at some code to strengthen it, especially pay attention to the unsigned type (unsigned).

1.3 Code understanding one:

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

The value of the char a variable is -1; first use 32 binary bits to find the complement.
Original code: 10000000000000000000000000000001
Inverse code: 11111111111111111111111111110
Complementary code: 111111111111111111111111111111
But because it is stored in char type, only 8 bit bits can be taken, from After the complement code, 8 bits are truncated, and 11111111 is obtained
but printed with %d (signed in decimal form) Integer integer) format to print, so the integer promotion occurs (a is a signed type, so use the number of the sign bit to complete the 32 digits of the binary bit ) to get:
complement code: 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110
original code
: 1000000000 0000000000000000000001
so The output value of char a should be -1;
similarly, because char == signed char, char a and signed char b are the same, so the output value of signed char b should also be -1;

The variable value of unsigned char c is - 1; first use 32 binary bits to find the complement.
Original code: 10000000000000000000000000000001
Inverse code: 11111111111111111111111111110
Complementary code: 111111111111111111111111111111
But because it is stored in char type, only 8 bit bits can be taken, from After the complement code, 8 bits are truncated to get 11111111. The key
point is here! ! ! Because the c variable is an unsigned char, the sign bit is not considered, and it is all numerical bits. When the plastic promotion occurs, all 0s will be added . So get:
complement code: 00000000000000000000000011111111
sign bit is 0, indicating that it is a positive number, so the inverse code, the original code is the same, the output value should be 255.
insert image description here

1.4 Code 2 understanding:


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

First find the complement of -128:
original code: 1000000000000000000000010000000
inverse code: 11111111111111111111110111111 complement
: 111111111111111111111110000000
because it is char type , can only store the last 8bit bits, truncated to get: 10000000
and because it is char type, the complement is the sign bit, Get: 1111111111111111111111110000000.
If you use %d to print, the sign bit is 1, which is a negative number, and the complement needs to be converted into the original code: the final result is naturally -128; if you use %u (
print unsigned integer in decimal form) to print, %u has no The concept of the sign bit, if all the binary bits are numeric bits, then the printout is: 1111111111111111111111110000000
This number is very big, bear with it. What is printed is: 4294967168
insert image description here

1.5 Code three understanding:

#include<stdio.h>
#include<Window.h>
int main()
{
    
    
	unsigned int i;
	for(i = 9; i >= 0; i--)
	{
    
    
		printf("%u\n", i);
		Sleep(1000);//减慢打印时间
		            //单位是毫秒
	}

	return 0;
}

In fact, it is easy to see that the code is in an infinite loop, because unigned int is an unsigned integer that is always greater than or equal to 0, and the for loop cannot be jumped out. When i = -1, it was supposed to jump out, but because it is an unsigned type, the complement of negative 1 is:
1111111111111111111111111111111. So what is printed is a very large number.
insert image description here

1.6 Code four understanding:

int main()
{
    
    
	char a[1000];
	int i;
    for (i = 0; i < 1000; i++)
	{
    
    
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));	
	return 0;
}

First look at the condition of for, i is incremented from 0 to 1000 times
, and then look at the assignment of a[ i ].
-1, -2, -3, -4, -5, -6, -7... -998, -999.
But as we said earlier, the value range of char is -128 ~ 127. The extra part is used for the next cycle.
So it should be as shown in the figure:
insert image description here
The strlen function measures the length of the string, and the condition for judging the end is to meet '0'; so when strlen encounters the 256th number 0, it ends the judgment. So the final output should be 255;
insert image description here

1.7 Code five understanding:

#include <stdio.h>

unsigned char i = 0;//0~255
int main()
{
    
    
for (i = 0; i <= 255; i++)
       {
    
    
          	printf("hello world\n");
       }
	return 0;
}

The value range of unsigned char is 0 ~ 255
, so it is an endless loop.

insert image description here

3. Introduction and judgment of big and small endian byte order

What big endian little endian?

Big-endian (storage) mode means that the low bits of data are stored in the high address of the memory, while the high bits of the data are stored in the low address of the memory; little endian (storage) mode means that the low bits of data are stored in the low bits of the
memory address, while the high bits of the data are stored in the high address of the memory.

Why there is big endian and little endian:

Why is there a difference between big and small endian modes? This is because in the computer system, we use bytes as the unit, and each address unit corresponds to a byte, and a byte is 8bit. But in the C language, in addition to the 8-bit char, there are also 16-bit short types and 32-bit long types (depending on the specific editor). In addition, for processors with more than 8 bits, such as 16-bit or For a 32-bit processor, since the register width is greater than one byte, there must be a problem of how to arrange multiple bytes. Therefore, it leads to big-endian storage mode and little-endian storage mode. For example: a 16bit short type x, the address in the memory is 0x0010, the value of x is 0x1122, then 0x11 is the high byte, and 0x22 is the low byte. For the big-endian mode, put 0x11 in the low address, that is, 0x0010, and put 0x22 in the high address, that is, 0x0011. Little endian mode, just the opposite. Our commonly used X86 structure is little-endian mode, while KEIL C51 is big-endian mode. Many ARMs and DSPs are in little-endian mode. Some ARM processors can also choose the big-endian mode or the little-endian mode by hardware

In short, the byte order of variables stored in memory (discussing the order of storage in bytes) is different on different compilers. Some compilers store in little-endian byte order, and vice versa. sequential storage. Little-endian storage is to store the content of the low-order byte of a data at a low address, and store the content of a high-order byte of a data at a high address.
Big-endian storage is to store the content of the low-order byte of a data at a high address, and store the content of a high-order byte of a data at a low address.

To give a simple example:
insert image description here
you can write a program to determine the endianness of your compiler :

int main()
{
    
    
	int a = 1;//整型存放四个字节 00 00 00 01
	          //用字符p来接收整型的第一个字节
	char* p = (char*)&a;//a强制类型转换后取得一个字节的内容
	if (*p == 1)        //用1 或 0判断段大小端存放
		printf("小端\n");
	else
		printf("大端\n");
	return 0;
}

insert image description here
When I use VS2019, it is stored in little endian byte order.
insert image description here

The editor is dull, if there are mistakes, please criticize and point out in the comment area, give me a like and support when the judge leaves, thank you.
insert image description here

Guess you like

Origin blog.csdn.net/LHY537200/article/details/130909236