Data storage in C language

Table of contents

1. Data type

1. Integer family

2. Floating point family

 3. Structure type

(1), array type:

(2), structure type:

(3), enumeration type:

(4), joint type:

 4. Pointer type

 5. Empty type

Second, the storage of integers in memory

 3. Storage of floating point numbers in memory

1. Storage rules for floating point numbers

2. Storage of floating-point numbers for the three values ​​​​of S, M, and E

3. Three situations in which the index E is taken out of the memory

(1) The case where E is not all 0 or not all 1

(2) The case where E is all 0

(3) The case where E is all 1

 4. Big and small endian byte order storage



1. Data type

After the previous study, we learned that the types of data in C language are roughly:

char, short , int ,long , long long , float , double   these types

For details, please see the data types of the first introduction to C language that I published earlier !

Can be divided into the following types:

1. Integer family

It includes the types of char, short , int , and long . Under these types, they are divided into two types-signed and unsigned.

Among them, the signed ones are expressed as: signed ... ,

Unsigned representation is: unsigned...

For example, signed integer type is: signed int , unsigned short integer type: unsigned short [int] (int can be written or not)

Of course, some careful students will find out why there is char type data in the integer family?

In fact, although char is a character type, the char type stores its Ascii code value in the computer , and the Ascii code value is an integer , so the char type is naturally included in the integer family!

Note that if it is data with a signed bit, the highest bit is the sign bit , and if the highest bit is 0 , it means a positive number , and if the highest bit is 1 , it means a negative number

If it is unsigned data, the highest bit is also a data bit, and there is no positive or negative of 0/1

Just remember the above points


2. Floating point family

It is called the floating-point number family, so the members of this family are naturally float and double types.

Among them, everyone knows that float is a single-precision floating-point type , and double is a double-precision floating-point type.

This family is very simple, we know it well, so let's move on to the next family.


 3. Structure type

Constructed types are also known as custom types

Divided into the following four categories, namely: array type, structure type, enumeration type, union type

Let's talk about these types in detail

(1), array type :

Why is it said that the array type is a custom type? The reason is very simple. For example, everyone will understand the reason.

For example: int arr[10] , to create such an array, then remove the array name arr , the remaining int [10] is the type , and for example char p[20], remove the array name p, the remaining char [20] is the type, so when creating an array, there are many types and they are all created according to your own needs, so the array type is naturally called a constructed type or a custom type! 

(2), structure type :

The structure has the keyword struct, the structure is to create a name, and then create members in it, and the members can assign their own values. For example, if you define a structure Student, you can set the name in it: char name[20], age : int age , student number: char id[20] , etc., can naturally also be called structural types!

~~~~ Regarding the specific content of the structure, a blog will be published in the near future to share the knowledge

(3), enumeration type:

The keyword of the enumeration type is: enum , which I explained in detail in the previous blog - the keywords of C language for the first time , and how to use it. Please pay attention to my previous blog.

(4), joint type:

The keyword of the joint type is: union. Everyone knows that this type has it. You don’t need to know too much. If you are interested, you can check the information online to increase your knowledge.


 4. Pointer type

There are roughly the following types of pointers, which should be familiar to everyone

int* p,char* p,float* p,void* p

The only thing to pay attention to is the last void pointer, which we have never seen before, just understand it


 5. Empty type

void represents an empty type (no type )

This is usually applied to the return type of the function , the parameter of the function , and the pointer type mentioned above , etc.


Second, the storage of integers in memory

Speaking of storage in memory, you should first understand the three concepts of original code, inverse code, and complement code

Original code:

It is ok to directly translate the value into binary in the form of positive and negative numbers

Inverse code:

The sign bit of the original code remains unchanged, and the other bits are reversed bit by bit

complement:

Inverse +1 to get complement

Attention Note: What is stored in the memory is the complement of the data! !

These three representations have sign bit and value bit, sign bit: 0 means positive, 1 means negative

For positive numbers , the original code, inverse code, and complement code are the same

For example: int a = 1; the sign bit of a is positive, then the highest bit of a is 0

Then the original code of a is: 00000000 00000000 00000000 00000001, the inverse code of the natural positive number a, and the complement code is naturally this

Note here: because a is an integer, it occupies four bytes and 32 bits, so the original code is a binary sequence composed of 32 0s and 1s.

For negative numbers, it satisfies the mutual conversion of the original code, inverse code, and complement code mentioned above. Let’s give an example.

int b = -1; the sign bit of b is negative, then the highest bit of b is 1

Then the original code of b is: 10000000 00000000 00000000 00000001

The inverse code of b is: 11111111 111111111 11111111 11111110 ( the sign bit remains unchanged, and the other bits are inverted )

The complement of b is: 11111111 111111111 11111111 11111111 ( complement +1 )

It can be seen that what b stores in memory is the complement of b: 11111111 111111111 11111111 11111111

This is the end of the storage knowledge of integers in memory!


 3. Storage of floating point numbers in memory

1. Storage rules for floating point numbers

According to international standards, any binary floating-point number V can represent the following form:

(-1)^S * M * 2^E

(-1)^S represents the sign bit , when S=0 , V is a positive number , when S=1 , V is a negative number

M represents a valid number , M is greater than or equal to 1 and less than 2

2^E means exponent bit

Let's give an example to illustrate these three values ​​in detail.

9.0 is written in binary form as: 1001.0

1001.0=(-1)^0 * 1.001* 2^3

That is, S=0, M=1.001, E=3, everyone can understand it more deeply according to this example!

2. Storage of floating-point numbers for the three values ​​​​of S, M, and E

standard regulation:

For 32-bit floating-point numbers ( single-precision floating-point numbers: float ), the highest 1 bit is the sign bit S , the next 8 bits are the exponent E , and the remaining 23 bits are the effective number M

For 64-bit floating-point numbers ( double-precision floating-point numbers: double ), the highest 1 bit is the sign bit S , then 11 bits are the exponent E , and the remaining 52 bits are the effective number M

Note: When the effective number M is stored, 1 can be omitted, because M must be preceded by 1, and one more bit can be stored when it is omitted.

The index E is more complicated. First, E is an unsigned integer. The value range of 8 bits is: 0~255, and the value range of 11 bits is: 0~2047. However, E may have negative numbers, and the standard stipulates: Add an intermediate number when storing in E, +127 for 8 digits , +1023 for 11 digits.

Let me give you an example.

float f = 5.5;

5.5 converted into binary is 101.1, then 101.1=(-1)^0 * 1.011 * 2^2

S=0,M=1.011,E=2+127=129

Then store in memory:

Binary is: 0 10000001 01100000000000000000000

Convert hexadecimal to: 0x 40 b0 00 00

3. Three situations in which the index E is taken out of the memory

(1) The case where E is not all 0 or not all 1

Subtract 127 (or 1023) from the calculated value of the exponent E to get the real value, and then add the effective number M to the first digit 1

(2) The case where E is all 0

The exponent E of the floating-point number equal to 1-127 (or 1-1023) is the real value, M does not add the first 1, but restores it to a decimal of 0. small numbers

(3) The case where E is all 1

Represents positive and negative infinity (positive or negative depends on the sign bit S)

Note: You mainly need to understand the first situation , and only need to understand the second and third situations


 4. Big and small endian byte order storage

Speaking of big and small endian storage, you may have heard of this concept, so next, let’s first understand the basic concept of big and small endian storage

Big endian storage:

Store the data at the low byte of a data at the high address, and store the data at the high byte at the low address

Little-endian storage:

Store the data at the low byte of a data at the low address, and store the data at the high byte at the high address

Let me explain the concept

For example: I create an integer a, expressed in hexadecimal form

int a = 0x11 22 33 44; 0x here is the sign of hexadecimal, 11 is the highest bit, and 44 is the lowest bit

Then, for example, from left to right in the memory , the address is from low address to high address , as shown in the figure:

The following picture shows big-endian storage :

 The following picture shows little-endian storage :

 

After verification, it proves that the VS compiler  we usually use is small-endian storage . Students who are interested in other compilers can come down and verify it for themselves.


The above is the data storage related content we talked about today, see you in the next blog! !

Guess you like

Origin blog.csdn.net/m0_64411530/article/details/123720764