Detailed explanation of custom types - structure

1.1 Structure type declaration

A structure is a collection of values ​​called member variables. Each member of the structure can be a variable of a different type

1.2 Declaration of structure

struct Stu  //Stu是结构体类型
{
    char name[20];//名字
    int age;//年龄
    char sex[5];//性别
    char id[20];//学号
}; //分号不能丢

Here we finish typing the semicolon in the VS compiler. The struct comes with it, so don’t worry.

1.3 Anonymous structure type

The anonymous structure type can be understood as a one-time item, and it cannot be used after it is used up

struct
{
    int a;
    char b;
    float c;
}s1;
struct
{
    char c;
    int a;
    double d;
}* ps;
int main()
{
    ps = &s1;
    return 0;
}

In this code we will find that the structure type is omitted

Warning: The compiler will treat this code as two completely different types, so it is illegal

1.4 Self-referencing of structures

//错误代码示例
struct Node
{
    int data;
    struct Node next;
};
//正确代码
struct Node
{
    int data;
    struct Node* next;
};

This type of self-reference is illegal, the type is Node, and it also contains its own members next is a code that never terminates

1.5 Structure memory alignment

struct s1
{
    char c1;
    int i;
    char c2;
};
printf("%d\n", sizeof(struct S1));

First master the structure alignment rules:

1. The first member is at the address whose offset is 0 from the structure variable.
2. Other member variables should be aligned to an address that is an integer multiple of a certain number (alignment number).
Alignment = Compiler's default alignment and the smaller value of the member size.
The default value in VS is 8
3. The total size of the structure is an integer multiple of the maximum alignment (each member variable has an alignment).
4. If a structure is nested, the nested structure is aligned to an integer multiple of its own maximum alignment number, and the
overall maximum alignment number (including the alignment number of the nested structure) Integer multiples.

Why does memory alignment exist?

Most of the references say something like this:

1. Platform reason (transplant reason):

Not all hardware platforms can access any data at any address; some hardware platforms can only access certain special addresses at certain addresses.

data of a certain type, otherwise a hardware exception is thrown.

2. Performance reasons:

Data structures (especially stacks) should be aligned on natural boundaries as much as possible.

The reason is that to access unaligned memory, the processor needs to make two memory accesses; while aligned memory access requires only one

ask.

In general:

The memory alignment of the structure is the practice of exchanging space for time

So the final sizeof is 12

1.6 Modify the default alignment number

之前我们见过了 #pragma 这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数

#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
    char c1;
    int i;
    char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
    char c1;
    int i;
    char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
    printf("%d\n", sizeof(struct S1));
    printf("%d\n", sizeof(struct S2));
    return 0;
}

结论:

结构在对齐方式不合适的时候,我么可以自己更改默认对齐数

1.7结构体传参

struct S
{
    int data[1000];
    int num;
};
struct S s = {
    
    {1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{
    printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
    printf("%d\n", ps->num);
}
int main()
{
    print1(s); //传结构体
    print2(&s); //传地址
    return 0;
}

上面的 print1 和 print2 函数哪个好些?

答案是:首选print2函数。

原因:

函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。
如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的
下降。

结论:

结构体传参的时候,要传结构体的地址

Guess you like

Origin blog.csdn.net/m0_74459304/article/details/129653456