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),