文章

C 结构体

C 结构体

结构是一种将多个相关变量组合到一个位置的方法。 结构中的每个变量都称为结构的成员。

array 不同,结构可以包含许多不同的数据类型(intfloatchar 等)。

创建结构

您可以使用 struct 关键字创建结构,并在花括号内声明其每个成员:

1
2
3
4
struct MyStructure {   // 结构声明
    int myNum;           // 成员(int 变量)
    char myLetter;       // 成员(char 变量)
}; // 用分号结束结构

想要访问这个结构,需要创建一个该结构类型的变量。

创建变量时,需要用到struct关键字,后面跟结构的名称,再跟着结构变量的名称:

1
2
3
4
5
6
7
8
9
struct myStructure {
    int myNum;
    char myLetter;
};

int main() {
    struct myStructure s1;
    return 0;
}

访问结构成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 创建一个名为 myStructure 的结构
struct myStructure {
    int myNum;
    char myLetter;
};

int main() {
    // 创建一个名为 s1 的 myStructure 结构变量
    struct myStructure s1;
    // 创建一个名为 s2 的 myStructure 结构变量
    struct myStructure s2;

    // 为不同的结构变量赋值
    s1.myNum = 13;
    s1.myLetter = 'B';

    s2.myNum = 23;
    s2.myLetter = 'X';

    // 打印值
    printf("s1 number: %d\n", s1.myNum);
    printf("s1 letter: %c\n", s1.myLetter);

    printf("s2 number: %d\n", s2.myNum);
    printf("s2 letter: %c\n", s2.myLetter);

    return 0;
}

初始化结构

  • 定义时按顺序赋值
1
struct myStructure s1 = {10, 'a'};
  • 定义后逐个赋值
1
2
3
4
struct myStructure s1;

s1.myNum = 10;
s1.myLetter = 'a';
  • 定义时乱序赋值(C风格)
1
struct myStructure s1 = {.myNum = 10, .myLetter  ='a'};
  • 定义时乱序赋值(C风格++)
1
struct myStructure s1 = {myNum:10, myLetter:'a'};

复制结构

s1结构变量的值赋给s2

1
2
3
4
5
6
7
8
9
struct myStructure {
    int myNum;
    char myLetter;
    char myString[30];  // String
};

struct myStructure s1 = {13, 'B', "Some text"};
struct myStructure s2;
s2 = s1;

结构中的字符串

请记住,C 中的字符串实际上是一个字符数组,所以不能像以下方式那样直接复制:

1
2
3
4
5
6
7
8
int main() {
    struct myStructure s1;

    // 错误做法:尝试直接给字符串赋值
    s1.myString = "Some text";

    return 0;
}

这个时候会编译报错:

1
2
3
4
.\c_structs.c: In function 'main':
.\c_structs.c:14:15: error: assignment to expression with array type
   14 |   s1.myString = "Some text";
      |  

这时候正确的做法是使用strcpy()函数去进行字符串赋值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <string.h>

int main() {
    struct myStructure s1;

    // 使用 strcpy 函数为字符串赋值
    strcpy(s1.myString, "Some text");

    // 打印值
    printf("My string: %s", s1.myString);

    return 0;
}

// 输出结果
// Some text

使用strcpy()函数时,必须要引用<string.h>头文件

或者在声明变量时就直接对字符串进行赋值,这样就省去了复制字符串的步骤:

1
2
3
4
5
6
7
8
9
int main() {
    // 创建一个结构变量并为其赋值
    struct myStructure s1 = {13, 'B', "Some text"};

    // 打印值
    printf("%d %c %s", s1.myNum, s1.myLetter, s1.myString);

    return 0;
}

修改值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
struct myStructure {
    int myNum;
    char myLetter;
    char myString[30];
};

int main() {
    // 创建一个结构变量并为其赋值
    struct myStructure s1 = {13, 'B', "Some text"};

    // 创建另一个结构变量
    struct myStructure s2;

    // 修改值
    s1.myNum = 30;
    s1.myLetter = 'C';
    strcpy(s1.myString, "Something else");

    // 打印值
    printf("%d %c %s\n", s1.myNum, s1.myLetter, s1.myString);

    // 将 s1 值复制到 s2
    s2 = s1;

    // 更改 s2 值
    s2.myNum = 60;
    s2.myLetter = 'X';
    strcpy(s2.myString, "Something other");

    // 打印值
    printf("%d %c %s\n", s2.myNum, s2.myLetter, s2.myString);

    return 0;
}

位域

位域就是一种在结构体中以二进制位为单位来存储数据的方式。

它允许我们为某个成员变量只分配若干位(bit),而不是通常的1字节、2字节或4字节。这在需要节省内存或与硬件寄存器直接对应时非常有用。

  • 基本语法
1
2
3
4
5
6
7
struct {
    unsigned int a : 3;  // a 占3位
    unsigned int b : 5;  // b 占5位
    unsigned int c : 2;  // c 占2位
    unsigned int   : 4;  // 空白占位
    unsigned int e : 4;  // e 占4位
};
  • unsigned int a : 3表示 a 这个成员只占 3 个二进制位,范围是 0 ~ 7。
  • 位域的基类型一般用 intunsigned int,也允许用 shortchar 等(依赖编译器实现)。
  • 位数 : n 必须小于等于该基类型所能存放的最大位数(如 int 通常是 32 位)。
本文由作者按照 CC BY 4.0 进行授权