Overview
The memory model in C Language basically corresponds to the actual storage model of the current von noriman computer, which is very good at machine ing, this is the main reason why C/C ++ is suitable for underlying development. In addition, there is another reason why C language is suitable for underlying development, that is, C language has provided a lot of support for underlying operations, provides many underlying functions.
The following describes the issues.
Problem: shift operation
When using the shift operator, you must be aware of the following two problems:
(1) In the right shift operation, whether to fill in 0 or sign a blank space;
(2) number of digits that can be displaced.
Answer and analysis:
">>" And" <"mean to move each bit of a variable to the right or left, usually in the form:
Shift right: variable name> Number of shifted digits
Left shift: variable name <Number of shifted digits
After the shift, the bit at one end is "squeezed out", while the bit at the other end is filled with 0. The shift in C language is not cyclical.
(1) The answer to the first question is very simple, but it depends on different situations. IfEnter 0 if the number is unsigned. If there is a number of symbols, it is possible to enter 0 or symbol bit. If you want to solve the problem of filling the vacant space in the right shift operation, declare the variable as unsigned, so that the vacant space will be set to 0.
(2) The answer to the second question is also simple: if n digits are moved, the number of shifted digits must be less than 0 and less than N. In this way, all data will not be removed in one operation.
For example, if Integer Data occupies 32 bits and N is an integer data, both N <31 and n <0 are valid, n <32 and n <-1 are invalid.
Note that the right shift of a signed integer is not the same as that of a signed integer. To prove this, we can think that-1> 1 cannot be 0.
Problem: Bit Segment Structure
Struct rpr_atd_tlv_header
{
Ulong RES1: 6;
Ulong type: 10;
Ulong RES1: 6;
Ulong length: 10;
};
The bitwise structure is a special structure. When you need to access Multiple Digits of one byte or word by bit, the bitwise structure is more convenient than the bitwise operator.
The bit structure is defined as follows:
Struct bit structure name {
Data type variable name: integer constant;
Data type variable name: integer constant;
}-Bit structure variable;
The integer constant must be a non-negative integer in the range of 0 ~ 15 indicates the number of binary bits, that is, the number of bits.
The variable name is a selection item and can be left unspecified. This is required for arrangement.
For example, a single-digit structure is defined below.
Struct{
Unsigned Incon:8;/*Incon occupies a low byte of 0 ~ 8 in total*/
Unsigned txcolor:4;/*Txcolor occupies a byte of 0 ~ 3-digit, 4-digit*/
Unsigned bgcolor:3;/*Bgcolor occupies 4-byte ~ 6-digit, 3-digit*/
Unsigned Blink:1;/*Blink occupies 7th bytes*/
} Ch;
The access of the bitwise structure member is the same as that of the structure member.
For example, to access the bgcolor member in the structure of the above sample bit, you can write it as follows:
The ch. bgcolor structure member can be used with other structure members. Access and setting by bit for convenience and saving
For example:
StructInfo {
CharName [8];
IntAge;
StructADDR address;
FloatPay;
Unsigned state:1;
Unsigned pay:1;
} Workers;
The structure of the above example defines information about a worker. There are two bit structure members, each of which has only one bit. Therefore, only one byte is occupied, but two pieces of information are saved. The first byte indicates the state of the worker, the second digit indicates whether the salary has been paid. The bit structure can save storage space.
Be sure not to exceed the value limit
Problem: byte alignment
In the process of using VC programming, I once called the structure defined in the DLL and found that the structure was out of order and I could not read the correct value. Later I found that this was because of the DLL and the callProgramThe Byte alignment option is different, so I would like to ask, what is the same with byte alignment?
Answer and analysis:
About byte alignment:
1. When different structures use different byte alignment definitions, interaction between them may become very difficult.
2. During cross-CPU communication, bytes can be used to ensure uniqueness, such as the communication protocol and the register structure when writing the driver.
Three Alignment modes:
1. Natural alignment: equal to the size of the data type.
2. Specify the alignment mode:
# PragmaPack (8)//Specify align as 8;
# PragmaPack ()//Restore to original value
3. Actual alignment:
Actual align = min (Order align, natual align)
For complex data types (such as structures): The actual alignment mode is the largest actual alignment mode for its members:
Actual align = max (actual align1, 2, 3 ,...)
Compiler filling rules:
1. The member is an integer multiple of the member actual align and adds padding to the front.
Member actual align = min (Structure actual align, set align)
2. The structure is an integer multiple of the actual align structure, followed by padding.
Example Analysis:
# PragmaPack (8)//Specify align as 8
StructStest1
{
CharBreak;
LongLo1;
CharCH2;
} Test1;
# PragmaPack ()
Now
Align of stest1 = 4, sizeof stest1 = 12 (4*3)
Test1 is arranged in the memory as follows (FF is padding ):
00 -- 04 -- 08 -- 12 ------
01 FF 01 01 01 01 01 01 FF
Callback -- lo1 -- CH2
# Pragma pack (2) // specify align as 2
Struct stest2
{
Char CH3;
Stest1 test;
} Test2;
# Pragma pack ()
Now align of stest1 = 2, align of stest2 = 2, sizeof stest2 = 14 (7*2)
Test2 is arranged in the memory as follows:
00 -- 04 -- 08 -- 12 ------
02 FF 01 FF 01 01 01 01 01 01 FF
CH3 extract -- lo1 -- CH2
Note:
1. In this way, the compiler cannot optimize a specific platform. If efficiency is very important, try not to use the # pragma pack. If it is necessary, you 'd better set it only as needed.
2. To add a pack, you must add it to the header file of the defined structure. Do not rely on the command line option, because if many people use this header file, not everyone knows that the pack should be used. This is especially manifested in the fact that when someone else develops a library file, if a library function uses struct as its parameter, an error will occur when the caller and the library file developer use a different pack, this type of error is hard to check.
3. In the header files provided by VC and BC, pack is added in addition to the four-byte structure, otherwise, the compiled windows program will not run normally.
4. Do not include other header files after # pragma pack (N). If the included header file changes the align value, unexpected results will be generated.
5. Do not define a data structure at the same time. This ensures consistent pack values.
Problem: bitwise operators
Unlike other advanced languages, C fully supports bitwise operators. This is similar to bit operations in assembly languages. The bitwise operators in C are listed as follows:
When there are too many threads, there are too many threads, too many threads.
Operator Function
── ─
& Bit logic and
| Bit logic or
^ Bit logic exclusive or
-Bit logic inversion
> Right shift
<Move left
When there are too many threads, there are too many threads, too many threads.
Note:
1. bitwise operations detect, set, or shift the actual bit in a byte or word.Only applicable to balanced and integer variables and their variants, not to other data types.
2. The result of relational operation and logical operation expression can only be 1 or 0. The bitwise operation result can take values other than 0 or 1. Note the differences between bitwise operators and logical operators. For example, if X = 7, the value of X & 8 is true (the two non-zero values are still non-zero ), the value of X & 8 is 0.
3. &, | and &&,~ And! Relationship
| And ~ Operators treat their operands as a sequence and operate independently by bit. For example, 10 & 12 = 8. This is because the "&" operator treats 10 and 12 as binary descriptions 1010 and 1100. Therefore, only when the same bits of the two operands are 1 at the same time, the corresponding digit in the result is 1. Similarly, 10 | 12 = 14 (1110), through the complement operation ,~ 10 =-11 (11... 110101 ). <How many are single-digit sequences?>
&, And! Operators treat their operands as "true" or "false", and 0 represents "false". Any non-0 value is considered as "true ". They return 1 representing "true" and 0 representing "false". For "&" and "" operators, if the value of the left operand is determined, the value of the expression can be determined, they do not calculate the right operand at all. So ,! 10 is 0, because 10 is not 0; 10 & 12 is 1, because 10 and 12 are not 0; 10 12 is also 1, because 10 is not 0. In addition, in the last expression, 12 is not calculated at all, as is in expression 10 F.