当前位置:网站首页>C language: data storage in memory
C language: data storage in memory
2022-06-13 09:11:00 【Caixinzhi】
This data storage in memory will be divided into two parts : One is the storage of integer in memory ; The second is the storage of floating-point type in memory .
One 、 The storage of integers in memory . First , We need to know the original code 、 Inverse code 、 Complement code , These three have been sorted out in detail before , I'll just tell you more about it . Next, let's take a look at the size side ( Big endian byte order & Small endian byte order ).
that , What are the big and small ends ?
Storage mode of large end byte order : There is a high address in the low order , There is a low address in the high order .
Storage mode of small end byte order : There is a low address in the low order , High address exists in high bit .
( among , The smallest unit of size is byte !)
Next , It will describe how to use a program to determine whether the machine used is a big end or a small end .
#include <stdio.h>
int check_sys()
{
int a = 1;
char* p = (char*)&a;
if (*p == 1)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int ret = check_sys(); // return 1 It's the small end , return 0 It's the big end
if (ret == 1)
{
printf(" The small end \n");
}
else
{
printf(" Big end \n");
}
return 0;
}The main idea of this code is :check_sys Function by casting , Extract whether the data stored in a byte size is equal to the first byte data in memory , If equal , Is the small end byte order ; If not , Is the big endian byte order .
Because the value we take 1 Is a very special value , therefore , We can also simplify the code further , See below for the specific code :
#include <stdio.h>
int check_sys()
{
int a = 1;
return *(char*)&a;
}
int main()
{
int ret = check_sys(); // return 1 It's the small end , return 0 It's the big end
if (ret == 1)
{
printf(" The small end \n");
}
else
{
printf(" Big end \n");
}
return 0;
}After understanding the original code 、 Inverse code 、 After the complement and the contents of the size side , We can study signed and unsigned integers , It will be explained through the following topics :
Topic 1 :
// What the following code will output ?
#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;
}about a In terms of variables , here -1 yes int type , Turn into char Type truncation occurs , Because the binary complement is stored in memory , therefore , Truncation also truncates the binary complement in memory , Only the lowest 8 Bits of data , And because in the end %d Printed out in the form of , Therefore, the retained data will be promoted by integer , For signed integer lifts , Will fill the sign bit in the highest bit of the binary , Finally, it is converted to the original code by complement , You will find , Finally print it out a The value of is -1.
about b In terms of variables , although C There is no provision in the language char And signed char It's the same , But in many mainstream compilers , Will default to char Namely signed char, For example, I often use VS2019 etc. , therefore , Last b The printed results will also a equally , by 1.
about c In terms of variables , Preceded by a sign char equally , But when it comes to integer lifting , For unsigned integer lifts , Will fill in the highest bit of binary 0, Finally print it out c The value is 255.
Topic two :
// What the following code will output ?
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n", a);
return 0;
}First ,-128 When stored in memory as a complement , stay char Truncation occurs in types , because char Stored is a signed type , Therefore, integer promotion occurs during printing , Will fill the sign bit in the highest bit of the binary , And then because it uses %u Printed , Therefore, it will be automatically recognized as an unsigned number in memory , So the original code will be equal to its complement , The number of prints will be very large .
Topic three :
// What the following code will output ?
#include <stdio.h>
int main()
{
char a = 128;
printf("%u\n", a);
return 0;
}This question is similar to question two , Just put -128 Change it to 128, And then you'll find out ,128 The binary sequence put in after truncation is the same as -128 The truncated binary sequences are equal , So after the same calculation , It will print out a very large amount of data just like topic 2 .
Topic four :
// What the following code will output ?
#include <stdio.h>
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
return 0;
}This is a relatively simple question , Used to distinguish the previous questions , Directly use two binary data stored in memory to calculate , Get the binary and then print out the original code , You will see that the result is -10.
Topic 5 :
// What the following code will output ?
#include <stdio.h>
int main()
{
unsigned int i;
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
}
return 0;
}because i It's an unsigned integer , And when printing, it is printed with %u In the form of printing , So when i Reduced to 0 When , At the beginning of the next cycle ,i by -1, Its binary complement 32 Bits become all 1, In the case of unsigned , The original code is equal to the complement , By this time i Will become a very large value , Then this very large value will continue to decrease to 0, Then it becomes very big , This infinite cycle goes on .
Topic 6 :
// What the following code will output ?
#include <stdio.h>
int main()
{
char a[1000];
int i;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a));
return 0;
}This is an important question , because char At most 8 A bit , When char When it is unsigned , Its value range is from 0 To 255; And in the sign char in , The value range is from -128 To 127, however , Whether signed or unsigned , Their length (strlen) It's all the same , by 255. therefore , The final printed result is 255.
inference : Different integer types have a certain value range , And there are different value ranges for whether there is a symbol or not . You can use the header file for details limits.h Go to the document to view .
Topic 7 :
// What the following code will output ?
#include <stdio.h>
unsigned char i = 0;
int main()
{
for (i = 0; i <= 255; i++)
{
printf("hello world\n");
}
return 0;
}This problem is similar to the previous one , Because there is no sign char The range of theta is zero 0 To 255, therefore i The value of cannot be greater than 255 Of ,for The condition in the loop is always true , So the program prints in an infinite loop .
Two 、 Storage of floating point in memory . This part will lead to... Through an example .
Example :
#include <stdio.h>
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n The value of is :%d\n", n); //9
printf("*pFloat The value of is :%f\n", *pFloat); //0.000000
*pFloat = 9.0;
printf("n The value of is :%d\n", n); //1091567616
printf("*pFloat The value of is :%f\n", *pFloat); //9.000000
return 0;
}Before looking at this code , We need to know that the rules for storing floating-point numbers and integers in memory are different , You can't use the integer method directly , that , What are the storage rules for floating point numbers ?
For any binary floating-point number V Can be expressed in the following form :(-1)^S*M*2^E
1.(-1)^S The sign bit , When S=0,V Is a positive number ; When S=1,V It's a negative number .
2.M Represents a significant number , Greater than or equal to 1
3.2^E Indicates the index bit
for example :5.5 Convert to binary to 101.1( That is to say -1^0*1.011*2^2)
Through the description above , It can be inferred that , Binary floating-point numbers only need to be stored in memory S、M、E Just three values , How are these three numbers stored in memory ?
For single precision floating point numbers float( That is to say 32 Bit floating point ) For storage , The highest bit is the sign bit S, next 8 Bits are exponents E, The rest 23 Bits are significant numbers M.
For double precision floating point numbers double( That is to say 64 Bit floating point ) For storage , The highest bit is the sign bit S, And then 11 Bits are exponents E, The rest 52 Bits are significant numbers M.
M Deposit of : Because significant numbers M The range of values is always greater than or equal to 1 Less than 2 Of , So the positive part will be stored 1 Give up , Save only the decimal part in memory .
E Deposit of :E Is an unsigned number , If it's negative , In memory E The true value of must be added with an intermediate number , about 8 Bit E, The median number is 127; about 11 Bit E, The median number is 1023.
You know how floating-point numbers are stored , Next , It is necessary to understand how it is taken out .
Three cases of fetching from memory :
1.E Not all for 0 Or not all of them 1: Index E The calculated value of minus 127( or 1023), Get the real value ; And then the significant number M Add first place before 1 that will do .
2.E All for 0: Index E be equal to 1-127( or 1-1023) That's the true value ; Significant figures M Directly for 0.XXX, In this way, it is easy to see that it is an infinite close to 0 Number of numbers .
3.E All for 1: And E All for 0 contrary , Is a number close to infinity .
Through the above series of rules , We can make the above example well , The above example has four prints , Next , Just list the four prints one by one .
First print : Because it is an integer 、 Integer extraction , So the result must be printed out 9.
Second print : Because it is a floating-point number , So it will be stored in the original memory 32 Bits to restore , It will find E For all 0. It is not difficult to see from the second of the three cases taken from the memory above , The restored floating-point number is an infinitely close to 0 Number of numbers .
The third print : According to the conversion rules of floating point numbers ,9.0 Convert to binary to 1001.0( That is to say -1^0*1.001*2^3), And then because you want to take it out in the form of an integer , So write this by floating point numbers 32 A bit , Turn to the original code , Read it as an integer , You can get 1091567616 The result is .
The fourth print : Because it is a floating-point number that is stored in 、 Floating point number extraction , So the result must be printed out 9.000000.
边栏推荐
- Neo4j - CQL使用
- 20211108 det(AB)=det(A)det(B)
- 20211028 Stabilizability
- 线上调试工具Arthas高级
- Overview of common layers of image recognition neural network (under update)
- 20211115 any n-order square matrix is similar to triangular matrix (upper triangle or lower triangle)
- Neo4j environment construction
- Opencv gaussianblur() explanation (Sigma value)
- Two good kids
- 教程篇(5.0) 02. 管理 * FortiEDR * Fortinet 网络安全专家 NSE 5
猜你喜欢

Simulink的Variant Model和Variant Subsystem用法

Mttr/mttf/mtbf diagram
![[network security penetration] if you don't understand CSRF? This article gives you a thorough grasp](/img/16/907c7c414502b22129f774fbffdafe.png)
[network security penetration] if you don't understand CSRF? This article gives you a thorough grasp

Final principle

an error occurred while trying to rename a file in the destination directory code 5

What exactly is Huawei cloud desktop saying when it says "smooth"?

202012 CCF test questions

基于微信小程序的图书馆管理系统.rar(论文+源码)

【安全】零基础如何从0到1逆袭成为安全工程师

How Simulink adds modules to the library browser
随机推荐
基于微信小程序的图书馆管理系统.rar(论文+源码)
Talking about acid of database
20211018 some special matrices
20211020 段院士全驱系统
How many TCP connections can a machine create at most?
你不知道的stringstream的用法
Message Oriented Middleware
消息中间件
Yolov5 face video stream
Jfinal and swagger integration
QML(06)——qml. Add a new folder under QRC
Pytorch model tuning - only some layers of the pre training model are loaded
Loss outputs Nan for the Nan model
Drill down to protobuf - Introduction
20211028 Stabilizability
JUC原子引用与ABA问题
Agile development practice summary-4
JUC Unsafe
20220524 如何把CoppeliaSim安装到D盘
20211104 why is the trace of a matrix equal to the sum of eigenvalues, and why is the determinant of a matrix equal to the product of eigenvalues