I. Preface:
1> the following instances are used:
Typedef struct {
Int;
Short B [2];
} Ex2;
Typedef struct EX {
Int;
Char B [3];
Ex2 c;
Struct EX * d;
} EX;
2> the structure of Type EX can be represented in the following figure:
3> you can declare it in the following ways:
Ex x = {10, "hi", {5, {-}}, 0 };
Ex * px = & x;
Ii. Access pointer
1. the right value of the expression px is:
Px is a pointer variable, but there is no indirect access operator here, so the value of this expression is the content of px.
2. The left value of the expression px is
1> it indicates that the old px value will be replaced by a new value.
Now consider the expression px + 1. This expression is not a valid left value because its value is not stored in any identifiable memory location.
2> right value of px + 1: If px points to an element of a structure array, this expression points to the next structure of the array. However, even so, this expression is still invalid because we cannot tell whether the next location in the memory stores one of these structural elements or something else.
Iii. Access Structure
You can use the * operator to perform indirect access to the pointer.
1. Expression * the right value of px is the entire structure pointed to by px.
Indirect access operations follow the arrow to access the structure. Therefore, the result of implementation display is the entire structure.
1> you can assign this expression to another structure of the same type. 2> You can also use it as the left operand of the vertex operator to access another specified member.
3> you can pass it as a parameter to the function, or return it as the return value of the function (however: This is not efficient)
2. The left value of the expression * px is:
1> here, the structure accepts a new value, or, more accurately, it accepts the new value of all its members. As the left value, the important thing is the position, not the value saved by this position.
2> the expression * px + 1 is invalid because * px results in a structure. The C language does not define addition operations between structures and integer values.
3> but * (px + 1), if x is an array element, this expression represents the structure behind it. However, x is a scalar, so this expression is actually invalid.
Four-structure storage allocation
How is the structure allocated in the memory?
1. the compiler allocates memory to each member one by one based on the list of members. Only when the storage member needs to meet the correct boundary alignment requirements can the member be used to fill in additional memory space.
2. the sizeof operator can obtain the overall length of a structure, including the bytes skipped due to boundary alignment.
3. To determine the actual location of a member in the structure, you can use the offsetof macro (stddef. h)
Offsetof (type, member );
Type is the structure type, member is the member name of the structure, and the expression structure is a sizeof_t value. Indicates the storage location of the specified member (from the starting location of the struct storage)
Eg:
# Include <stdio. h>
# Include <stdlib. h>
# Include <stddef. h>
Struct tiger {
Char;
Int B;
Char c;
};
Int main ()
{
Struct tiger x;
Int m;
M = offsetof (struct tiger, B );
Printf ("% d \ n", m );
}
The program output structure is 4
5. structure as function parameters
A structure scalar is a scalar that can be used in any scenario where other scalar values can be used. Therefore, it is legal to pass the structure as a parameter to a function, but this approach is often inappropriate.
1. The following procedure is used to operate an electronic cash income recorder. The following is a schema declaration.
Typedef struct {
Char product [PRODUCT_SIZE];
Int quantity;
Float unit_price;
Float total_amount;
} Transaction;
When a transaction occurs, you need to print the receipt.
Void print_receipt (Transaction trans)
{
Printf ("% s \ n", trans. product );
Printf ("% d @ % 2.f \
Total % 2. f \ n ", trans. quantity, trans. unit_price, trans. total_amount)
};
If current_trans is a Transaction structure, we can call the function as follows;
Print_receipt (current_trans );
Note:
This method can produce correct results, but its efficiency is very low, because the C language parameter value transfer call method requires that a copy of the parameter be passed to the function. If the PRODUCT_SIZE is 20 and both the integer and floating point types occupy 4 bytes on the machine we use, this structure occupies 32 bytes of space. To pass it as a parameter, 32 bytes must be copied to the stack and discarded later.
Method 2:
Void print_receipt (Transaction * trans)
{
Printf ("% s \ n", trans. product );
Printf ("% d @ % 2.f \
Total % 2. f \ n ", trans. quantity, trans. unit_price, trans. total_amount)
};
This function can be called using the following method:
Print_receipt (& current_trans );
Note:
This time, the pointer to the structure is passed to the function. The pointer is much smaller than the entire structure, so it is much more efficient to press it onto the stack. Another price to pass pointers is that indirect access must be used in functions to access the structure of members. The larger the structure, the higher the efficiency of passing the pointer to it to the function.
The defect in passing pointers to a function is that the function can now modify the structure variables of the calling program. If you do not want this, you can use the const keyword in the function to prevent such modifications. Now you can call it as follows:
Void print_receipt (Transaction const * trans );
2. Deal with the transaction: calculate the total amount to be paid. You want the comput_total_amount function to modify the total_amount Member of the structure. There are three methods to complete this task.
1> Method 1:
Transaction compute_total_amount (Transaction trans)
{
Trans. total_amount = trans. quantity * trans. unit_price;
Return trans;
}
You can call it in the following format:
Current_trans = compute_total_amount (current_trans );
A copy of the structure is passed as a parameter to the function and modified. Then a copy of the modified structure is returned from the function, so the structure is copied twice.
2> Method 2:
This method only returns the modified value instead of the entire structure.
Float compute_total_amount (Transaction trans)
{
Return trans. quantity * trans. unit_price;
}
However, this function must be called in the following way:
Current_trans.total_amount
= Compute_total_amount (current_trans );
This scheme is better than the scheme that returns the entire structure, but this technique is only applicable to calculating a single value. If the function is required to modify two or more members of the structure, the method is powerless. In addition, it still has the overhead of passing the entire structure as a parameter.
3> method 3: www.2cto.com
It is much better to pass a pointer.
Void compute_toatl_amount (Transaction * trans)
{
Trans-> total_amount = trans-> quantity * trans-> unit_price;
}
This function is called as follows:
Compute_total_amount (& current_trans );
Note:
In the program, the structure field total_amount is directly modified. It does not need to pass the entire structure as a parameter to the function or return the entire modified structure as a return value.
From tiger-john