Latent C language -- data storage

Introduction to data types

C language type:

1. Built in type

char

short

int

long

double

float

2. User defined type (construction type)

Meaning of type:

1. Use this type to open up the size of memory space (the size determines the scope of use)

2. How to view memory space

int main()
{
	int a = 10;
	float f = 10.0;

	return 0;
}

Different storage methods and memory

Basic classification of types

1. Plastic surgery Family

Char (character type):

        unsighed char

        signed char

short:

         unsighed short

         signed  short

int :

         unsighed int

         signed  int

long:

         unsighed long

         signed long

2. Floating point family

float single precision floating point

Double double precision floating point

Construction type

1. Array type

2. Structure type: struct

3. Enum type enum

4. union type

Pointer type

int *pi;

char *pc;

float *pf;

void* pv;

void type: null type:

It is usually applied to the return type, parameter and pointer type of a function

void test(void)
{
	printf("hehe\n");
}
int main()
{
	test(100);
	return 0;
}

Shaping storage in memory

Let's first understand these concepts:

Original code, inverse code and complement code

The three representation methods have two parts: symbolic number (integer) and numerical bit. The symbolic bit is 0 for "positive" and 1 for "negative", while the three representation methods of numerical bit are different.

(the original code, inverse code and complement of unsigned number are the same)

Calculation rules:

Original code: directly translate binary into binary in the form of positive and negative numbers.

Inverse code: the symbol of the original code remains unchanged, and other bits are reversed by bit in turn

Complement: inverse code + 1

int main()
{
	int a = 20;//4 bytes - 32bit
	//000000000 10100 - original code
	//000000000 10100 - inverse code
	//000000000 10100 - complement
    //0x00000014 - hexadecimal
	int b = -10;
	//100000000000000000001010 - original code
	//011111111111111111111111110101 - inverse code
	//1111 1111 1111 1111 1111 1111 1111 0110 - complement
    //Fff6 - hex
	return 0;
}

Positive original code, inverse code and complement code are identical

For integers, the data stored in memory is actually stored as a complement.

In the computer system, numerical values are represented and stored by complement

sum:

Integer:

1. Signed number:

The positive original code, inverse code and complement code are the same

Negative original code, inverse code and complement code are different

2. Unsigned number:

The original code, inverse code and complement code are the same

Large and small end introduction

What is the size end?

Big end storage mode: it means that the low bit of data is saved in the high address of memory, while the high bit of data is saved in the low address of memory

Small end storage mode: it means that the low bit of data is saved in the low address of memory, while the high bit of data is saved in the high address of memory

Example: 11 22 33 44 - big end

44 33 22 11 - small end

Example: 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

int main()
{
	//Write a piece of code to tell us 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;
}
int check_sys()
{
	int a = 1;
	char* p = (char*)&a;
	return *p
}
int main()
{
	//Write a piece of code to tell us the byte order of the current machine
	//Return 1, small end
	//Return 0, big end
	int ret = check_sys();
	if (ret == 1)
	{
		printf("Small end\n");
	}
	else
	{
		printf("Big end\n");
	}
	return 0;
}

Meaning of pointer type:

1. The pointer type determines how many bytes the pointer dereference operator can access

char*p *p accessed 1 byte

int*p * P accessed 4 bytes

2. The pointer type determines the + 1 and - 1 of the pointer. How many bytes are added or subtracted

char*p p+1 skip one character

int*p * p+1 skip an integer - 4 bytes

Exercise: what is the output of the following code

1.

Answer:

Integer promotion occurs: when integer promotion occurs, the high bit is supplemented with the symbol bit, i.e. 1. Integer high-order 0, no complement

Exercise 2: what is the output of the following code

 

int main()
{
	char a = -128;
	//10000000000000000000000010000000
	//11111111111111111111111101111111
	//11111111111111111111111111110000000 complement
	//11111111111111111111111111111111111111110000000 integer lifting result
	printf("%u\n", a);
	//%d print decimal signed integer 
	//%u print decimal unsigned integer
	return 0;
}

Supplement:

1. % d # decimal signed integer.

2. % u # decimal unsigned integer.

3. % ld # output long integer.

4. % s} string.

5. % c # single character.

6. The value of the% p # pointer.

7. % e# floating point number in exponential form.

8. % x,% X * unsigned integer in hexadecimal.

9. % 0} unsigned integer in octal.

10. % g # automatically select the appropriate representation.

 char:

signed char

unsigned char

Each store 1 byte and 8 bit s

Range of signed char: - 128-127

Unsigned char range: 0-255

practice:

 

1000000 00000000 00000000 00010100
1111111 11111111 11111111 11101011
1111111 11111111 11111111 11101100 - Complement
0000000 00000000 00000000 00001010 - Complement
1111111 11111111 11111111 11110110 - result                           
1111111 11111111 11111111 11111010
1000000 00000000 00000000 00001010 - -10

Exercise: what is the result of this?

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

Answer: 255

-1 to - 128 to 127 to 0

Exercise: what will the next code output?

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

Answer: dead cycle

Storage of floating point in memory

Common floating point numbers: 3.1415 1E10

The family of floating point numbers includes: float double

give an example:

int main()
{
	int n = 9;
	float *pFloat = (float*)&n;
	printf("n The value of is:%d\n", n);
	printf("*pFloat The value of is:%f\n", *pFloat);

	*pFloat = 9.0;
	printf("num The value of is:%d\n", n);
	printf("*pFloat The value of is:%f\n", *pFloat);
	return 0;
}

 

num and float are obviously the same number in memory. Why are the interpretation results of floating point number and integer so different?

According to the international standard IEEE754, any binary floating-point number V can be expressed as:

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

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

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

2^E indicates exponential bit

For example: the decimal 5.0 is written as 101.0, which is equivalent to 1.01x22. Then, according to the format of V above, we can get s=0M=1.01  E=2.

The decimal 5.0 is written as - 101.0, which is equivalent to -1.01x2^2. Then, 5 = 1, M=1.01, E=2.

IEEE 754 stipulates that for 32-bit floating-point number 1, the highest bit is sign bit s, the next 8 bits are exponent E, and the remaining 23 bits are significant digits M.

//9.0
//1001.0
//(-1)^0 * 1.001 * 2^3
//(-s)^s *    M  * 2^E
//S - 0
//M - 1.001
//E - 3

IEEE754 has some special provisions on non m and index E. As mentioned earlier, 1sm < 2, that is, M can be written as 1 The form of xxxx , where xxxxxx represents the decimal part.

IEEE 754 stipulates that when saving m in the computer, the first digit of this number is always 1 by default, so it can be rounded off and only the following 0xxxx part is saved. For example, when saving 1.01 Save only 01. When reading, add the first 1. The purpose of this is to save 1 significant digit. Take the 32-bit floating-point number as an example. There are only 23 bits left for M. after rounding off the 1 of the first bit, it is equivalent to saving 24 significant digits.

int main()
{
	float f = 5.5;
	//5.5
	//101.1
	//(-1)^0 * 1.011*2^2
	//S = 0
	//M = 1.011
	//E = 2
	//0100 0000 1011 0000 0000 0000 0000 0000
	//0x40b00000 - hex
	return 0;
}



As for the E index, the situation is more complicated.

First, e is an unsigned integer (unsigned int), which means that if e is 8 bits, its value range is 0 - 255; If e is 11 bits, its value range is 0-2047. However, we know that negative numbers can appear in E in scientific counting method, so IEE 754 stipulates that the real value of e must be added with an intermediate number when stored in memory. For 8-bit e, the intermediate number is 127; For an 11 bit e, the median is 1023 For example, e of 2 ^ 10 is 10, so when saving as a 32-bit floating-point number, it must be saved as 10 + 127 = 137, that is, 10001001.

Then, the index E can be extracted from the memory and divided into three cases:

E is not all 0 or all 1

At this time, floating point numbers are represented by the following rules That is, the calculated value of index E minus 127 (or 1023) Get the true value Then add 1.0 before the significant number M For example, the binary form of 05 (1 / 2) is 01 Since it is specified that the positive part must be 1 That is, if the decimal point is shifted to the right by one digit, the price code is - 1 + 127 = 126 Represents 111110, and the mantissa 1.0 is 0 after removing the integer part, and park Qi is 0 to 23 bits 00000000000000000000000, then the binary common representation is

0  01111110 00000000000000000000000

E is all 0

At this time, the exponent E of the floating-point number is equal to 1-127 (or 1-1023), and 0 is the real value. The significant number M is no longer added with the first 1, but is reduced to a decimal of xxxx. This is done to indicate: 0 And a small number close to 0.

E is all 1

At this time, if the significant digits M are all 0. Represents + infinity (plus or minus depends on sign bit 3),
 

Keywords: C Back-end

Added by SoN9ne on Fri, 11 Feb 2022 09:28:50 +0200