Table of contents
2. Storage of shaping in memory
2.1 Inverse code complement of original code
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
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.