大话C语言:第38篇 结构体

1 结构体概述

实现世界中,我们经常需要表示多个属性的对象或者实体。例如,高校的大学生,他们拥有姓名、年龄、性别、学号等多个属性,每个属性需要用不同的数据类型定义。

/*
* 大学生对象中的属性,包括:
* 姓名,字符串类型
* 年龄,无符号整数
* 性别,字符类型
* 学号,无符号长整型
*/
char name[30];
unsigned short age;
char sex;
unsigned long num;

分散的数据难以独立表达大学生对象,因此,为了方便管理和操作,C语言发明了了结构体(struct)。结构体(struct)是C语言(也适用于C++、C#等语言)中一种重要的数据类型,它允许用户将不同类型的数据组合成一个整体,以便进行统一的管理和操作。结构体中的每个数据成员都称为结构体的成员,可以是任何基本数据类型或复合数据类型。

2 结构体声明

C语言中,结构体的声明使用struct关键字,后面跟着结构体的标签名(可选)和结构体成员列表,这些成员被包含在一对大括号{}中。结构体的声明可以有两种形式:带标签的声明和不带标签的声明。

2.1 带标签的结构体声明

如果需要重复使用结构体,需要声明带标签的结构体。语法格式:

struct 标签名或者结构体名
{
    数据类型 成员1;
    数据类型 成员2;
    ...
    数据类型 成员n;    
};

其中,标签名又称为结构体名。例如,定义学生结构体,

struct student
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
};

其中,student是结构体的标签名或者结构体名;name/age/sex/num/major是结构体成员,它们共同组成了结构体的成员列表。

2.2 不带标签的结构体声明

如果不打算重复使用结构体(匿名结构体),可以声明不代表标签的结构。语法格式:

struct
{
    数据类型 成员1;
    数据类型 成员2;
    ...
    数据类型 成员n;  
} 结构体变量1, ..., studentN;

其中,结构体没有标签或者结构体名,只有具体的结构体变量(结构体变量1, ..., studentN)。这种方式下不能在其他地方通过结构体标签或者结构体名来引用这个结构体类型。例如,两名大学生,一位是张三,一位是李四,

struct
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
} ZhangSan, LiSi;

其中,ZhangSanLiSi是具体的结构体变量,也就是具体学生;如果还想定义王五同学的话,无法用该结构体定义呢。

2.3 结构体别名声明

为了提高代码的可读性和可维护性,特别是在处理复杂的数据结构,可以为结构体定义别名。定义结构体别名使用关键字typedef,它为结构体定义一个新的名字。语法格式:

// 方式1:直接给结构体声明别名
typedef struct 标签名或者结构体名
{
    数据类型 成员1;
    数据类型 成员2;
    ...
    数据类型 成员n;    
} 新的标签名或者结构体名;

// 方式2:先声明结构体,再声明结构体别名
struct 标签名或者结构体名
{
    数据类型 成员1;
    数据类型 成员2;
    ...
    数据类型 成员n;    
};

typedef struct 标签名或者结构体名 新的标签名或者结构体名;

student结构体可以表示小学生、中学生或者大学生,如果明确指出某类学生的话,例如,大学生,可以通过结构体别名的方式:

// 方式1:直接给结构体声明别名
typedef struct student
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
} collegeStudent;

// 方式2:先声明结构体,再声明结构体别名
struct student
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
};
typedef struct student collegeStudent;

除了上述两种方式之外,传统方式是直接取别名,而不采用typedef,例如,

// 方式3:直接取别名(不采用typedef关键字)
struct 标签名或者结构体名
{
    数据类型 成员1;
    数据类型 成员2;
    ...
    数据类型 成员n;    
} 新的标签名或者结构体名;

// 具体代码示例
struct student
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
} collegeStudent;

注意,优先推荐采用方式1或者方式2。

3 结构体初始化

C语言中,结构体初始化方法有多种,包括:

  • 声明时初始化:在声明结构体变量时,可以直接对其进行初始化。语法格式:

// 声明结构体
struct 标签名或者结构体名
{
    数据类型 成员1;
    数据类型 成员2;
    ...
    数据类型 成员n;    
};

// 定义结构体变量并初始化
struct 标签名或者结构体名 结构体变量 = {成员1的值, 成员2的值, ..., 成员n的值};

代码示例:

#include <stdio.h>

struct student
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
};
  
int main() 
{  
    // 初始化结构体变量stu
    struct student stu = {"张三", 20u, 'm', 20240001ul}; 
    
    printf("该学生的基本信息:%s, %u, %c, %lu\n", stu.name, stu.age, stu.sex, stu.num);
    
    return 0;  
}
  • 使用指定初始化器:C99标准及以后中,可以使用指定初始化器(designated initializers)来初始化结构体的特定成员。语法格式:

// 声明结构体
struct 标签名或者结构体名
{
    数据类型 成员1;
    数据类型 成员2;
    ...
    数据类型 成员n;    
};

// 定义结构体变量并初始化
// 注意,成员顺序可以乱序
struct 标签名或者结构体名 结构体变量 = {.成员1=值, .成员2=值, ..., .成员n=值};

代码示例:

#include <stdio.h>

struct student
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
};
  
int main() 
{  
    // 初始化结构体变量stu
    struct student stu = {.age=20u, .num=20240001ul, .sex='m', .name="张三"};
    
    printf("该学生的基本信息:%s, %u, %c, %lu\n", stu.name, stu.age, stu.sex, stu.num);
    
    return 0;  
}
  • 使用赋值操作:在声明变量后使用赋值操作来设置结构体的成员。语法格式:

// 声明结构体
struct 标签名或者结构体名
{
    数据类型 成员1;
    数据类型 成员2;
    ...
    数据类型 成员n;    
};

// 定义结构体变量
struct 标签名或者结构体名 结构体变量;

// 逐个成员赋值
// 注意,可以部分成员赋值
// 如果是字符数组的话,需要采用拷贝函数进行赋值
结构体变量.成员1 = 值;
结构体变量.成员2 = 值;
...
结构体变量.成员n = 值;

代码示例:

#include <stdio.h>
#include <string.h>

struct student
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
};
  
int main() 
{  
    // 先定义结构体变量
    struct student stu;
    // 再对结构体成员逐个赋值
    // 注意,不能直接赋值
    // stu.name[] = "张三";
    if (strcpy(stu.name, "张三") != NULL)
    {
        stu.age = 20u;
        stu.sex = 'm';
        stu.num = 20240001ul;

        printf("该学生的基本信息:%s, %u, %c, %lu\n", stu.name, stu.age, stu.sex, stu.num);        
        return 0;
    }
    else 
    {
        printf("名字赋值失败\n");
        
        return -1;
    }
}

4 结构体成员的使用

结构体成员的访问与修改两种方式:

  • 如果是结构体变量,通过 . 操作成员

  • 如果是结构体指针变量,通过 -> 操作成员

#include <stdio.h>

struct student
{
    char name[30];  			// 姓名
    unsigned short age;		// 年龄
    char sex;							// 性别,m表示男,f表示女
    unsigned long num;		// 学号
};
  
int main() 
{  
    // 结构体变量stu
    struct student stu = {"张三", 20u, 'm', 20240001ul};
    printf("该学生的基本信息:%s, %u, %c, %lu\n", stu.name, stu.age, stu.sex, stu.num);
    
    // 修改部分成员信息
    stu.age = 23u;
    stu.num = 20240002ul;
    printf("该学生的基本信息:%s, %u, %c, %lu\n", stu.name, stu.age, stu.sex, stu.num);
    
    // 结构体指针stuPtr
    struct student *stuPtr = &stu;
    printf("该学生的基本信息:%s, %u, %c, %lu\n", stuPtr->name, stuPtr->age, stuPtr->sex, stuPtr->num);
    // 修改部分成员信息
    stuPtr->age = 25u;
    stuPtr->num = 20240003ul;
    printf("该学生的基本信息:%s, %u, %c, %lu\n", stuPtr->name, stuPtr->age, stuPtr->sex, stuPtr->num);
    
    return 0;  
}
  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值