Skip to content

结构体 struct

用于自定义数据结构

c
#include <stdio.h>

// 非常类似其他编程语言 类的概念
// 注意这是个语句, 不是一个块, 所以分号不能省略
struct User {
  unsigned int id;
  char * name;
  char * email;
};

int main() {
  // 按照顺序初始化所有字段
  struct User jerry = {
    1000,
    "jerry",
    "1000@example.com"
  };

  // .取值
  printf("id %d\n", jerry.id);
  printf("name %s\n", jerry.name);
  printf("email %s\n", jerry.email);

  // 初始化指定字段
  struct User tom = {
    .id = 1001,
    .email = "1001@example.com",
  };

  // .赋值
  tom.name = "tom";
  printf("id %d\n", tom.id);
  printf("name %s\n", tom.name);
  printf("email %s\n", tom.email);

  // 用指针指向结构体并用指针取值
  struct User *uptr = &tom;

  printf("\n");

  // 由于 . 的操作符优先级比 * 要高, 所以
  // 必须先解引用后再取值
  // 否则就是 *(uptr.id), 那意思就变成了
  // 给 uptr.id 这个整体解引用
  printf("id %d\n", (*uptr).id);

  // 所以可以使用 -> 操作符, 等同于 (*ptr).name
  printf("id %s\n", uptr->name);
}

联合体 union

c
#include <stdio.h>

union User {
  unsigned int id;
  char * name;
  char * email;
};

int main() {
  // 按照顺序初始化所有字段
  // 与结构体不同的是, 只能初始化一个字段
  union User tom = { 1000 };

  // 取值
  printf("id %d\n", tom.id);

  // 赋值
  tom.name = "tom";
  printf("name %s\n", tom.name); // tom
  printf("email %s\n", tom.email); // tom
}

结构体联合体的区别

  1. 内存分配方式不同

    • 结构体中的各个成员占用不同的内存空间, 总的内存大小是所有成员变量所占内存之和
    • 联合体的所有成员共享同一块内存空间, 其大小等于最大的成员变量所占的内存空间(所以只能初始化一个属性)
c
/***********************************************
假设在特定的系统中, int占 4 个字节, char占 1 个字节
那么这个结构体的大小为 4 + 1 = 5 个字节
但由于内存对齐等原因, 实际大小可能大于 5 个字节(8)
***********************************************/

#include <stdio.h>
struct ExmpStruct {
    int a;
    char b;
};

int main() {
  printf("size of exmp struct: %lu \n", sizeof(struct ExmpStruct));
  // output: size of exmp struct: 8
}
c
/***********************************************
假设在特定的系统中, int占 4 个字节, char占 1 个字节
联合体的所有成员共享同一块内存空间, 其大小等于最大的
成员变量所占的内存空间, 也就是 int 的大小, 也就是 4
***********************************************/

#include <stdio.h>

union ExmpStruct {
    int a;
    char b;
};

int main() {
  printf("size of exmp struct: %lu \n", sizeof(union ExmpStruct));
  // output: size of exmp struct: 4
}
  1. 数据存储方式不同

  2. 结构体:

    • 结构体可以同时存储所有成员的值, 各个成员的值是独立的, 互不影响
    • 可以在不同的时间修改不同成员的值
  3. 联合体:

    • 联合体在同一时间只能存储一个成员的值
    • 当给一个成员赋值时,其他成员的值会被覆盖
c
#include <stdio.h>

struct ExmpStruct {
  char *name;
  char *email;
};

union ExmpUnion {
  char *name;
  char *email;
};

int main() {
  struct ExmpStruct exmp_struct = {"tom", "tom@example.com"};
  union ExmpUnion exmp_union = {"tom"};

  // 取值
  printf("Struct: %s, %s\n", exmp_struct.name, exmp_struct.email);
  printf("Union: %s, %s\n", exmp_union.name, exmp_union.email);

  printf("\n");

  // 赋值
  exmp_struct.name = "TOM";
  exmp_struct.email = "tomtom@example.com";
  printf("Struct: %s, %s\n", exmp_struct.name, exmp_struct.email);

  exmp_union.name = "TOM";
  exmp_union.email = "tomtom@example.com";
  printf("Union: %s, %s\n", exmp_union.name, exmp_union.email);
}

Released under the MIT License.