The following questions are elaborated respectively.
Problem: Shift operation
When using the shift operator, two questions must be clear:
(1), in the right shift operation, whether the vacancy is filled with 0 or sign bit;
(2) What number can be shifted?
Answers and analysis:
"> > and"
Move right: variable name >; > shift bit number
Move left: variable name
After shifting, the bits at one end are "squeezed out" and the bits at the other end are filled with zeros. In C language, shift is not cyclic.
(1) The answer to the first question is simple, but it depends on different situations. If the shifted number is unsigned, fill in 0. If it is a signed number, then it is possible to fill in 0 or sign bit. If you want to solve the problem of filling the vacancy in the right shift operation, declare the variable as unsigned, so that the vacancy will be set to 0.
(2) The answer to the second question is also very simple: if you move n bits, the number of bits to be shifted must not be less than 0, but must be less than n ... In this way, all data will not be deleted in one operation.
For example, if integer data takes up 32 bits and n is integer data, then n <<3 1 and n.
Note that even if spaces are filled with sign bits, the right shift of signed integers is not equivalent to division. To prove this, we can think about-1>; & gt 1 cannot be 0.
Q: Segmented structure
Structure RPR _ ATD _ TLV _ Title
{
ULONG RES 1:6;
ULONG type:10;
ULONG RES 1:6;
ULONG length:10;
};
Bit segment structure is a special structure, which is more convenient than bitwise operator when it is necessary to access multiple bits of a byte or word bitwise.
The general form of bit structure definition is:
Structure bit structure name (
Data type variable name: integer constant;
Data type variable name: integer constant;
} bit structure variable;
Where: the integer constant must be a non-negative integer of 0~ 15, indicating the number of binary digits, that is, how many digits there are.
The variable name is optional and can be unnamed, and it is stipulated to arrange the needs.
For example, the bit structure is defined as follows.
Structure {
Unsigned Incon: 8; /*incon occupies 0~7***8 bits */
Unsigned txcolor: 4; /*txcolor takes up 0~3 bits of high byte ***4 bits */
Unsigned bgcolor: 3; /*bgcolor takes up 4~6 high bytes ***3 bits */
Unsigned blink:1; /*blink occupies the 7th bit of the high byte */
} ch
The access of bit structure members is the same as that of structure members.
For example, accessing the bgcolor member in the above bit structure can be written as:
ch.bgcolor
Bit structure members can be used with other structure members. Bit-by-bit access and setting, convenient &; rescue
For example:
Structural information {
char name[8];
int age
Structural address;
Floating salary;
Unsigned status:1;
Unsigned salary:1;
} workers; '
The structure of the above example defines a worker's information. There are two bit structure members, and each bit structure member has only one bit, so only one byte is needed but two pieces of information are saved. The first bit of this byte indicates the worker's status, and the second bit indicates whether the salary has been paid. It can be seen that using bit structure can save storage space.
Be careful not to exceed the limit.
Problem: Byte Alignment
In the process of programming with VC, I once called the structure defined in DLL, and found that the structure was out of order, so I couldn't read the correct value at all. Later, it was found that this was because DLL and calling program used different byte alignment options, so I would like to ask, what is byte alignment?
Answers and analysis:
About byte alignment:
1. When different structures use different definitions of byte alignment, it may make the interaction between them difficult.
2. When communicating across CPU, byte alignment can be used to ensure uniqueness, such as communication protocol and register structure when writing.
Three alignment methods:
1. Natural alignment: equal to the size of data type.
2. Specify the alignment method:
#pragma pack(8) // Specify Align as 8;
#pragma pack() // Restore to the original value
3. Actual calibration mode:
Actual alignment = minimum (sequential alignment, natural alignment)
For complex data types (such as structures, etc. ): Actual alignment is the maximum actual alignment of its members;
Actual alignment = maximum (actual alignment 1, 2, 3, ...)
Filling rules of compiler:
1, which is an integer multiple of the member Actual Align, and is preceded by padding.
Actual alignment of components = minimum value (actual alignment of structure, set alignment)
2. This structure is an integer multiple of the actual Align structure, and padding is added later.
Case study:
#pragma pack(8) // Specify Align as 8.
Structural test 1
{
char ch 1;
Dragon lo1;
char ch2
} test 1;
# Miscellaneous note package ()
at present
The alignment of STest 1 = 4, and the size of STest 1 = 12 (4 * 3).
The arrangement of test 1 in memory is as follows (FF is padding):
00 - - - 04 - - - 08 - - - 12 - - -
0 1 FF FF FF 0 1 0 1 0 1 0 1 0 1 FF FF FF
ch 1 - lo 1 - ch2
#pragma pack(2) // Specify Align as 2.
Structural test 2
{
char ch3
STest 1 test;
} test2
# Miscellaneous note package ()
Now, test the alignment of 1 = 2, the alignment of test 2 = 2, and the size of test 2 = 14 (7 * 2).
Test2 is arranged in memory as follows:
00 - - - 04 - - - 08 - - - 12 - - -
02 FF 0 1 FF FF 0 1 0 1 0 1 0 1 0 1 FF FF FF
ch3 ch 1 - lo 1 - ch2
Precautions:
1. Therefore, the compiler cannot be optimized for a specific platform. If efficiency is important, try not to use #pragma pack. If necessary, it is best to set it only where necessary.
2. If you need to add a package, you must add it to the header file that defines the structure. Don't rely on command line options, because if many people use header files, not everyone knows that they should be packaged. This is especially true when developing library files for others. If a library function uses struct as its parameter, when the caller and the library file developer use different pack, an error will occur, and this error is difficult to find.
3. In the header files provided by 3.VC and BC, except for the four-byte structure, pack is added, otherwise our Windows programs will not run normally.
4. Don't include other header files after #pragma pack(n). If you change the align value in the included header file, it will produce unexpected results.
5. Don't let multiple people define a data structure at the same time. This ensures a consistent packaging value. Question: Bitwise operators
Different from other high-level languages, C language fully supports bitwise operators. This is somewhat similar to bit manipulation in assembly language. The bitwise operators in C # are as follows:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Operator operation
————————————————————————————
& amp bit logic and
Bit logical OR
Bit logical exclusive OR
10 bit logic inversion
& gt& gt Move to the right
& lt& lt move left.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
note:
1. Bitwise operation is to detect, set or shift the actual bit in a byte or word. It only applies to character and integer variables and their variants, but not to other data types.
2. The result of relational operation and logical operation expression can only be 1 or 0. The result of bit operation can be 0 or a value other than 1. Pay attention to the difference between bitwise operators and logical operators. For example, if x=7, then x&; The value of&8 is true (the phase of two non-zero values is still non-zero), while x &;; The value of 8 is 0.
3. Use&; With & amp; , ~ and! Relationship between
The&,and ~ operators treat their operands as a sequence and operate bit by bit. For example:10&; 12 = 8, because "&"operator regards 10 and 12 as binary descriptions 10 and 1 00, so only when the same bits of the two operands are/kloc-0 at the same time. Similarly,1012 =14 (110), through complement operation, ~10 =-1(60 How much is a bit sequence? >: & amp& amp! An operator treats its operand as true or false, with 0 indicating false, and any non-zero value as true. They return 1 for true and 0 for false. For "&; & amp ""operators, if the value of the left operand can determine the value of the expression, then they don't calculate the right operand at all. Therefore, 10 is 0, because 10 is not 0; 10。 & kloc-0/2 is 1 because 10 and 12 are not zero; 10 12 is also 1 because 10 is not 0. Moreover, in the last expression, 12 is not calculated at all, and so is the expression 10 f ().