Deep analysis of data storage in memory
Data type introduction
Basic built-in types
char //Character data type short //Short int //plastic long //Long integer long long //Longer shaping float //Single-precision floating-point double //Double precision floating point number
Meaning of type:
1. Use this type to open up the size of memory space (the size determines the scope of use)
2. Vision of memory space
Basic classification of types
Plastic family
char
unsigned char
signed char
short
unsigned short
signed short
int
unsigned int
signed int
long
unsigned long
signed long
Floating point family
float
double
Construction type - custom type
struct - structure type
array
enum - Enumeration
union - Consortium
Pointer type
int *p
char *p
float *p
void *p
Empty type
void – the return type used for the function
Function parameter -- void test(void);
Pointer -- void *p
Shaping storage in memory
The creation of a variable needs to open up space. The size of space varies according to different types. How is the data stored? Let's first look at the binary representation of integers:
For integers:
There are three binary representations of integers: original code, inverse code and complement code
**Positive integer: * * original code, inverse code and complement code are the same
**Negative integer: * * original code, inverse code and complement code to be calculated
The binary sequence written directly according to the value of the data is the original code
The sign bit of the original code remains unchanged, and the other bits are reversed by bit to obtain the inverse code
Inverse code + 1 to get complement
int main() { int a = -10; //Original code //10000000000000000000000000001010 //11111111111111111111111111111110101 - inverse code //11111111111111111111111111111110110 complement //1111 1111 1111 1111 1111 1111 1111 0110 //F F F F F F F 6 //FFFFFFF6 return 0; }
Memory storage of a:
The data is stored in binary form in the memory. After debugging and checking the address memory of a, it can be seen that the integer is stored in the memory as a complement
The original, inverse and complement of positive numbers are the same
For plastic surgery: data storage is complement
Why is the complement stored?
In the computer system, numerical values are represented and stored by complement. The reason is that by using complement, the symbol bit and value field can be processed uniformly; At the same time, addition and subtraction can also be processed uniformly (CPU only has adder). In addition, the complement and original code are converted to each other, and the operation process is the same, without additional hardware circuit.
int main() { //1-1 //1 + (- 1) / / CPU has no subtracter, only adder, which should be converted into addition calculation //00000000000000000000000000000001 //10000000000000000000000000000001 //10000000000000000000000000000010 //-The original code is - 2 after adding //000000000 01 -- complement of 1 //111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 //100000000000000000000000000000000 Only 32 can be stored in memory bit The one who goes in can't save it. It's lost //000000000000000000000000000000000000000 -- 0 / / more appropriate return 0; }
We find that the memory of a is stored upside down. Next, let's look at the size end of a knowledge point
Large and small end introduction
Large end byte order and small end byte order
int main() { int a=0x11223344; return 0; }
Address high ----------- > address high
44332211 small end byte order
11223344 big endian byte order
Big endian byte order:
Store the contents of the low byte order of the data at the high address and the contents of the high byte order at the low address
Small end byte order:
Store the contents of the low byte order of the data at the low address and the contents of the high byte order at the high address
The current compiler is a small endian storage mode
Baidu written test questions
Please briefly describe the concepts of large end byte order and small end byte order, and design a small program to judge the byte order of the current machine.
#include<stdio.h> int main() { //Write code to judge the byte order of the current machine int a=1; char* p=(char*)&a; if(*p==1) { printf("Small end\n"); } else { printf("Big end\n"); } return 0; }
Judging by function
#include<stdio.h> int check_sys() { int a=1; char* p=(char*)&a; return *p;//Return 1 small end and 0 large end } int main() { int ret=check_sys(); if(ret==1) { printf("Small end\n"); } else { printf("Big end\n"); } return 0; }
Practice explanation
1.
int main() { char a=-1; //10000000000000000000000000000001 //11111111111111111111111111111110 //11111111111111111111111111111111 //11111111 //Plastic lifting //11111111111111111111111111111111 signed char b=-1; //11111111 //Plastic lifting //11111111111111111111111111111111 unsigned char c=-1; //11111111 //Plastic lifting //00000000000011111111 -- complement //11111111111111111111111111111100000000 -- inverse code //11111111111111111111111111100000001 -- complement printf("a=%d b=%d c=%d",a,b,c); return 0; }
Supplement:
1. Is char signed or unsigned?
The C language standard is not specified and depends on the compiler
Int is a signed int
Short is a signed short
2.
#include <stdio.h> int main() { char a = -128; printf("%u\n",a); return 0; }
The explanation is as follows:
1000000000000000000000000010000000 - original code
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111110000000 - complement
10000000
a is the signed char, the high bit is filled with the sign bit, and the shaping is lifted,
11111111111111111111111111111110000000 - complement
Print with% u and print in unsigned form. It is considered that it is stored in memory without symbols, so the complement is the original code
3.
#include <stdio.h> int main() { char a = 128; printf("%u\n",a); return 0; }
The explanation is as follows:
00000000000000000000000010000000
01111111111111111111111101111111
011111111111111110000000 - complement
10000000
a is the signed char, the high bit is filled with the sign bit, and the shaping is lifted,
11111111111111111111111111111110000000 - complement
Print with% u and print in unsigned form. It is considered to be unsigned. The unsigned number is the same as the original inverse complement, so the complement is the original code
Supplement:
char
The value range of signed char is - 128 to 127
00000000–>0
00000001–>1
......
01111111 – > 127 – positive maximum
10000000 - -128
10000001 10000000 11111111 -127
......
11111110 11111101 10000010 -2
11111111 11111110 10000001 -1
Inverse complement original code
4.
#include<stdio.h> int main() { int i=-20; unsigned int j=10; printf("%d\n",i+j);//%d thinks that the number in memory is signed and% u thinks that the number in memory is unsigned return 0; }
The explanation is as follows:
100000000000000000000000000000010100 – i original code
11111111111111111111111111111111101011 – i inverse code
11111111111111111111111111111111111101100 – i complement
00000000000000000000000000001010–j
11111111111111111111111111111110110 – i+j complement
11111111111111111111111111110101
%d thinks that the number in memory is signed and% u thinks that the number in memory is unsigned
The sign bit remains unchanged and is reversed by bit
10000000000000000000000000001010 -->-10
#include<stdio.h> int main() { unsigned int i; for(i=9;i>=0;i--) { printf("%u\n",i); } return 0; }
The explanation is as follows:
i is an unsigned shape. i will never be less than 0. It's an endless loop
6.
#include<stdio.h> int main() { char a[1000]; int i; for(i=0;i<1000;i++) { a[i]=-1-i; } //-1 -2 -3...... -127 -128 127 126...... 3 2 1 0 -1 -2 -3...... printf("%d",strlen(a));//\0 is the end flag return 0; }
The explanation is as follows:
Char is a signed char with a value range of - 128 to 127. Because strlen calculates the string, it stops calculating when it sees \ 0, and strlen calculates the length of the string before 0.
7.
#include<stdio.h> int main() { unsigned char i = 0;//Unsigned char value range 0-255 for(i=0;i<=255;i++)//This condition will always be met { printf("hello world\n"); } return 0; }
Dead cycle
The explanation is as follows:
The value range of unsigned char is 0-255, and the circular judgment part is always satisfied