C language struct keywords

Source: Internet
Author: User
C language struct keywords

Struct is a magic keyword. It packs associated data into a whole for ease of use.

In network protocols, communication control, embedded systems, and driver development, what we often want to transmit is not a simple byte stream (char array), but a combination of multiple types of data, it is a struct.

Experienced developers often store all the content to be transmitted in a char array in sequence, and transmit network packets and other information through pointer offset. This programming method is complex and error-prone. Once the control mode and communication protocol change, the program must be modified very carefully, which is very error-prone. In this case, you only need a struct. At ordinary times, we require that the number of function parameters should be no more than 4. If the number of function parameters is greater than 4, errors are very easy to use (including the meaning and order of each parameter are easy to make mistakes ), efficiency will also be reduced (related to the specific CPU, ARM chip is very careful about processing more than four parameters, please refer to the relevant information for details ). At this time, we can use struct to compress the number of parameters.

1. What is the size of the empty struct?

The memory size occupied by the struct is the sum of the memory occupied by its members (for memory alignment of the struct, see the preprocessing chapter ). This is easy to understand, but what about the following?
Struct student

{

} Stu;

What is the value of sizeof (Stu? Test it on Visual C ++ 6.0.

Sorry,
It is not 0, but 1.Why? Think about it. If we think of struct student as a model, can you create a model without any volume?

Obviously not. So does the compiler. The compiler determines that any data type has its size and uses it to define a variable that can allocate space to determine the size. In this case, the compiler naturally assumes that any struct has a size, even if it is null. If the struct is really empty, why is its size suitable?

Assume that there is only one char data member in the structure, and the size is 1 byte (the memory alignment is not considered here ). that is to say, data of the non-empty struct type must occupy at least one byte space, while data of the null struct type cannot occupy a larger space than that of the smallest non-empty struct type. This is troublesome. The size of the empty struct cannot be 0 or greater than 1. What should I do? Is defined as 0.5 bytes? However, the minimum unit of memory address is 1 byte. How can we handle 0.5 bytes? The best way to solve this problem is to compromise. The Compiler naturally thinks that you construct a struct data type to package some data members, and the smallest data member needs one byte, the compiler reserves at least one byte space for each struct type data. Therefore, the size of the empty struct is located at 1 byte.

The design of the transmitted packets by an excellent program designer is a good example for reference:
Struct commupacket
{
Int ipackettype; // Message Type flag
Union // one of the three messages is sent each time.
{
Struct structa packeta;
Struct structb packetb;
Struct structc packetc;
}
};
During packet transmission, the entire struct commupacket is directly transmitted.
Assume that the original form of the sending function is as follows:
// Psenddata: the first address of the byte stream to be sent. ilen: The length to be sent.
Send (char * psenddata, unsigned int ilen );
The sender can directly call sendcommupacket, an instance of struct commupacket, as follows:
Send (char *) & sendcommupacket, sizeof (commupacket ));

Assume that the original form of the receiving function is as follows:
// Precvdata: the first address of the byte stream to be sent. ilen: The length to be received.
// Return value: the actual number of bytes received
Unsigned int Recv (char * precvdata, unsigned int ilen );
The receiver can directly make the following calls to save the received data to a recvcommupacket instance in struct commupacket:

Recv (char *) & recvcommupacket, sizeof (commupacket ));
Then determine the Message Type for corresponding processing:
Switch (recvcommupacket. ipackettype)
{
Case packet_a:
... // Class A Message Processing
Break;
Case packet_ B:
... // Class B Message Processing
Break;
Case packet_c:
... // Class C Message Processing
Break;
}
The most noteworthy of the above procedures is
Send (char *) & sendcommupacket, sizeof (commupacket ));
Recv (char *) & recvcommupacket, sizeof (commupacket ));
Forced type conversion in: (char *) & sendcommupacket, (char *) & recvcommupacket, get the address first, and then convert it to the char type pointer, so that you can directly use the function for processing byte streams.
Using this forced type conversion, we can also facilitate programming. For example, to initialize the memory of sendcommupacket to 0, we can call the standard library function memset () as follows ():
Memset (char *) & sendcommupacket, 0, sizeof (commupacket ));

Ii. Flexible Array

Maybe you have never heard of the concept of flexible array, but it does exist.

In c99, the last element in the structure can be an array of unknown size, which is called a flexible array member, but the flexible array member in the structure must be at least one other member. Flexible array Members allow the structure to contain an array of variable sizes. The size of the structure returned by sizeof does not include the memory of the flexible array. The structure containing flexible array members uses the malloc () function to dynamically allocate memory, and the allocated memory should be larger than the size of the structure to adapt to the expected size of the flexible array.

How to use flexible arrays? Take the following example:

Typedef struct st_type

{


Int I;


Int A [0];

} Type_a;

Some compilers may report errors and cannot compile them. You can change them:

Typedef struct st_type

{


Int I;


Int A [];

} Type_a;

In this way, we can define a variable length struct. Only 4 is obtained using sizeof (type_a), that is, sizeof (I) = sizeof (INT ). The array with zero elements does not occupy space. Then we can perform the variable length operation. Use the following expression to allocate memory to the struct:
Type_a * P = (type_a *) malloc (sizeof (type_a) + 100 * sizeof (INT ));


In this way, we allocate a piece of memory for the struct pointer p. You can use p-> item [N] to easily access variable-length elements.

However, at this time, we use sizeof (* P) to test the size of the struct, and found that it is still 4. Isn't it weird? Didn't we allocate space for this array?
Don't worry. Remember the model we mentioned earlier ". When defining this struct, the size of the model has determined the memory size that does not contain the flexible array. Flexible arrays are compiled by non-staff and do not occupy the structure. This is just to say that when using a flexible array, you need to treat it as a member of the struct. In addition, the flexible array has nothing to do with the struct, but it is just "Selling sheep and dogs" and cannot be a formal member of the struct.

It should be noted that c89 does not support such a thing. c99 adds it as a special case to the standard. However, c99 supports incomplete type, instead of zero array, which is equivalent to int item [0]. This form is invalid, and c99 supports the same form as int item []; some compilers only support int item [0]; as non-standard extensions, and have such non-standard extensions before c99 is released. After c99 is released, some compilers combine the two into one.

Of course, since the above uses the malloc function to allocate memory, you must use the free function to release the memory:
Free (P );


After the above explanation, I believe you have mastered this seemingly mysterious thing. But it doesn't matter if you don't know it. This is rarely used.

Iii. Differences between struct and class

In C ++, the struct keyword and the class keyword can be used in general, but there is only one small difference. Struct members are public by default, while Class Members are private. Many people think it is easy to remember. Do you usually use public to modify a struct? Since the struct keyword and the class keyword can be used universally, you should not consider that the structure cannot contain functions. Many documents have written here that all the differences between struct and class in C ++ have been given. In fact, it is not true. Note that:
Struct in C ++ maintains full compatibility with struct in C (which complies with the original intention of C ++-"A Better C"). Therefore, the following operations are legal:
Struct structa
{
Char;
Char B;
Int C;
};
Structa A = {'A', 'A', 1}; // assign the initial value directly when defining
That is, struct can assign an initial value to the member variable {} directly during definition, while the class cannot, the author emphasizes this point in the classic bibliography thinking C ++ 2nd edition.

Iv. byte order

When it comes to struct, we have to talk about the byte sequence. Let's take a look at an instance first. How can we see it?

 

#include <iostream.h>#pragma pack(8)struct example1{short a;long b;};struct example2{char c;example1 struct1;short e;    };#pragma pack()int main(int argc, char* argv[]){example2 struct2;cout << sizeof(example1) << endl;cout << sizeof(example2) << endl;cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2) << endl;return 0;}

The output result is 8, 16, 4. Why? Are you correct? Let's start learning the content in the byte order.

 

1. Nature
Struct is a composite data type. Its components can be both basic data types (such as int, long, float, and so on) variables, it can also be a data unit of some composite data types (such as array, struct, Union, etc.For struct, the compiler automatically alignment member variables to improve the computing efficiency. By default, the compiler allocates space for each member of the struct according to its natural (natural alignment) condition. Each member is stored in the memory in the declared order. The address of the first member is the same as that of the entire structure.Natural alignment (natural alignment) is the default alignment, which refers to Alignment Based on the largest member of the struct.
For example:
Struct naturalalign
{
Char;
Short B;
Char C;
};
In the above struct, short is the largest in size and the length is 2 bytes. Therefore, char members A and C in the struct are aligned in units of 2. sizeof (naturalalign) the result is 6;
If changed:
Struct naturalalign
{
Char;
Int B;
Char C;
};
The maximum size is int, and its length is 4 bytes. Therefore, char members A and C in the struct are aligned in units of 4, and the result of sizeof (naturalalign) is 12;

2. Specify the peer
Generally, you can use the following method to change the default peer condition:
1) using the pseudo command # pragma pack (n), the compiler will align according to n Bytes;
2) use the pseudo command # pragma pack () to cancel the custom byte alignment.

Note: If the value of N specified in # pragma pack (n) is greater than the size of the largest member in the structure, the structure does not take effect, and the structure is still bounded by the member with the largest size.
For example:
# Pragma pack (N)
Struct naturalalign
{
Char;
Int B;
Char C;
};
# Pragma pack ()
When N is 4, 8, or 16, the alignment is the same, and the sizeof (naturalign) result is 12. When N is 2, it plays a role, making sizeof (naturalalign) Result 8.
In the VC ++ 6.0 compiler, we can specify its peer mode, and choose projetct> setting> C/C ++ menu in sequence, specify the peer mode in struct member alignment.
In addition, through _ attribute (aligned (N), the struct member can be aligned on the N-byte boundary, but it is rarely used, therefore, we will not explain it in detail.

The instance mentioned above should have been solved as well. Let's analyze it. It doesn't mean it will always be done now. It's a good memory and won't let it go. No, yesfinger (codeword is not easy) O (symbol _ blank) O ~

Line 1 in the Program # pragma pack (8) although the ing is specified as 8, since the maximum size of members in struct example1 is 4 (long variable size is 4 ), therefore, struct example1 is still 4-byte, and the size of struct example1 is 8.
Struct example2 contains struct example1. the maximum size of simple data members contained in struct example1 is 2 (short variable E), but it contains struct example1, in struct example1, the maximum member size is 4, and struct example2 should also be bounded by 4. # The peer bound in Pragma pack (8) does not work for struct example2 either, therefore, the output result is 16;
Because the members in struct example2 are 4-aligned, the char variable C should be followed by three null values, and the latter is the memory space of the member struct1, the output result of 20 rows is 4.

Now let's look at a small program and end this section.

 

#include <iostream.h>struct structA{int iMember;char *cMember;};int main(int argc, char* argv[]){structA instant1,instant2;char c = 'a';instant1.iMember = 1;instant1.cMember = &c; instant2 = instant1;cout << *(instant1.cMember) << endl;*(instant2.cMember) = 'b';cout << *(instant1.cMember) << endl;return 0;}

Output result: a B
Tell me why, because the instant2 = instant1 value assignment statement uses the variable copy one by one, which enables the cmember in instant1 and instant2 to point to the same piece of memory, therefore, modifications to instant2 are also modifications to instant1.

In the C language, when the struct contains pointer members, be sure to use the value assignment statement to determine whether to direct the pointer members of the two instances to the same memory.

 

In C ++, when the struct contains pointer-type members, we need to override the copy constructor of struct and reload the "=" operator.

To be continued ....

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.