【C Language】Conclusion: C Structures

31 阅读3分钟

structure

a user-defined data type

definition

can be used to group items of possibly different types into a single type.

Syntax

content

结构体类型变量定义

1.在定义结构体时定义其类型变量
    struct structure_tag{
        // members
    }variable1,variable2,...;
2.定义结构体类型后再独立定义其类型变量
  
// structure declared beforehand
   struct structure_tag variable1,variable2,...;
   

访问结构体变量成员

使用访问操作符

structure_name.member1;
strcuture_name.member2;
访问嵌套式结构体成员
str2.str1.a;

初始化结构体变量成员

1. 定义变量时初始化
  • 默认
struct s s = {0}; // ... are initialized to 0

  • 指定初始化
    • 访问操作符
        structure_name.member1=v1;
      
    • 使用初始化列表
      • 使用默认顺序初始化列表/隐式初始化

           struct s s = {v1,v2,...};
        
      • 使用自定义初始化列表/显式初始化

           struct s s = {.mem1=v1,.mem2=v2,...};
        

给结构体起别名/简化其类型名称

typedef
   typdef struct {
        // members
    }s_tag;
example
// C Program to illustrate the use of typedef with
// structures
#include <stdio.h>

// defining structure
typedef struct {
    int a;
} str1;

// another way of using typedef with structures
typedef struct {
    int x;
} str2;

int main()
{
    // creating structure variables using new names
    str1 var1 = { 20 };
    str2 var2 = { 314 };

    printf("var1.a = %d\n", var1.a);
    printf("var2.x = %d\n", var2.x);

    return 0;
}

嵌套式结构体

1. 嵌入式嵌套结构体
// defining structure
typedef struct {
    int a;
    typedef struct {
        int x;
    } str2;
} str1;



2.独立/分离式嵌套结构体
//
// defining structure
typedef struct {
    int a;
} str1;

// parent
typedef struct {
    int x;
    str1 s1;
} str2;

访问嵌套式结构体成员
str2.str1.a;

结构体指针

// defining structure
struct structure_tag{
    int x;
};

struct structure_tag s_tag;
struct structure_tag* sp=&s_tag;

typedef struct {
    int x;
 
} str2;

str2 str_name;
str2* sp=&str_name;
访问结构体指针指向结构体变量的成员方式

sp->mem1;

// C program to illustrate the structure pointer
#include <stdio.h>

// structure declaration
struct Point {
    int x, y;
};

int main()
{
    struct Point str = { 1, 2 };

    // p2 is a pointer to structure p1
    struct Point* ptr = &str;

    // Accessing structure members using structure pointer
    printf("%d %d", ptr->x, ptr->y);

    return 0;
}

自我参考的结构体

syntax
struct structure_name {
    data_type member1;  
 data_type member2;  
  struct structure_name* str;   
}
例子
// defining structure
struct structure_tag{
    int x;
    struct sturcture_tag *next;
} str2;

str2 str_v;
str2* sp=&str_v;


// access members
sp->x // str_v.x

//2


// C program to illustrate the self referential structures
#include <stdio.h>

// structure template
typedef struct str {
    int mem1;
    int mem2;
    struct str* next;
}str;

// driver code
int main()
{
    str var1 = { 1, 2, NULL };
    str var2 = { 10, 20, NULL };

    // assigning the address of var2 to var1.next
    var1.next = &var2;

    // pointer to var1
    str *ptr1 = &var1;

    // accessing var2 members using var1
    printf("var2.mem1: %d\nvar2.mem2: %d", ptr1->next->mem1,
           ptr1->next->mem2);

    return 0;
}

结构体内存对齐规则

  • 结构体内首个成员与偏移量0(地址0)对齐;
  • 结构体内其余成员需要跟根据自身的对齐数,找到其对齐数的倍数进行对齐;(两个成员之间用padding填充)
  • 嵌套结构体实质上与上面一条的规则一致;
  • 结构体的总内存大小由依据成员中最大的对齐数的整倍数决定;
计算结构体总大小的步骤

s1. 第一个成员在0处对齐 s2. 顺着第2个成员根据规则2找到它的对齐数的整倍数处进行对齐,依此类推进行操作; s3.遇到结构体嵌套问题,就先根据s1.步骤计算出子结构体的大小,根据其大小在母结构体中找到子结构体的对齐数的整倍数进行操作即可。 s4.最后,相加或得出总大小。加以验证得出最终结果。

packing
  1. Using #pragma pack(1)

  2. Using __attribute((packed))__

// C program to illustrate structure padding and packing
#include <stdio.h>

// structure with padding
struct str1 {
    char c;
    int i;
};

struct str2 {
    char c;
    int i;
} __attribute((packed)) __; // using structure packing

// driver code
int main()
{

    printf("Size of str1: %d\n", sizeof(struct str1));
    printf("Size of str2: %d\n", sizeof(struct str2));
    return 0;
}