C语言结构体用法详解(包括定义、初始化、赋值、成员访问等细节)

C语言结构体用法详解(包括定义、初始化、赋值、成员访问等细节)

在现实生活中,我们经常需要用多个不同类型的数据来描述一个对象,比如要描述一个学生,需要记录他的姓名、学号、年龄、成绩等信息;要描述一个商品,需要记录它的名称、价格、库存等信息。

如果使用普通的变量来存储这些数据,不仅需要定义很多独立的变量,而且这些变量之间缺乏关联性,不利于数据的管理和使用。为了解决这个问题,C语言提供了结构体(Structure)这种复合数据类型。

结构体可以将多个不同类型的数据组织在一起,形成一个新的数据类型。这些数据可以是基本数据类型(如 int、float、char 等),也可以是其他的结构体类型。每个数据在结构体中被称为成员或者字段。通过结构体,我们可以将所有相关的数据打包成一个整体,更好地表达数据之间的逻辑关系。

结构体的定义

要使用结构体,需要先定义结构体类型,它的基本语法格式如下:

struct 结构体名称 {

成员类型1 成员名称1;

成员类型2 成员名称2;

...

成员类型n 成员名称n;

};

struct 是定义结构体的关键字,结构体名称用于标识这个新的数据类型,花括号内部包含了若干成员变量的声明。每个成员变量都有自己的类型和名称,它们之间用分号分隔。

下面通过一个具体的例子来说明结构体的定义和使用。假设我们要开发一个学生信息管理系统,需要存储学生的基本信息:

struct Student {

char name[50]; // 姓名

int id; // 学号

int age; // 年龄

float score; // 成绩

};

这里定义了一个名为 Student 的结构体类型,它包含 4 个成员。注意,为了和变量名、函数名进行区分,结构体名的首字母一般要大写。

结构体的使用

结构体是一种类型,而不是变量,不能赋值;定义了结构体类型后,还需要声明结构体变量才能使用。

声明结构体变量

声明结构体变量有两种方式:先定义类型再声明变量,或者在定义类型的同时声明变量。

// 方式 1:先定义类型,再声明变量

struct Student s1; //使用了已经定义的结构体类型 Student

// 方式 2:定义类型的同时声明变量

struct Student {

char name[50];

int id;

int age;

float score;

} s1, s2;

初始化结构体成员

结构体变量的成员可以在声明时初始化,也可以在声明后单独赋值。初始化时要注意成员的顺序必须与定义时的顺序一致。

// 声明时初始化

struct Student s1 = {"张三", 10001, 18, 85.5};

// 声明后单独赋值

struct Student s2;

strcpy(s2.name, "李四"); // 字符数组不能直接赋值,需要使用 strcpy

s2.id = 10002;

s2.age = 19;

s2.score = 92.5;

访问结构体成员

如果是结构体变量,可以使用点运算符.访问结构体成员;如果是结构体指针,则使用箭头运算符->访问结构体成员。请看下面的例子:

#include

#include

struct Student {

char name[50];

int id;

int age;

float score;

};

int main() {

struct Student s1 = {"张三", 10001, 18, 85.5};

struct Student *ptr = &s1;

// 使用点运算符访问成员

printf("姓名:%s\n", s1.name);

printf("学号:%d\n", s1.id);

// 使用箭头运算符访问成员

printf("年龄:%d\n", ptr->age);

printf("成绩:%.1f\n", ptr->score);

return 0;

}

输出结果:

姓名:张三

学号:10001

年龄:18

成绩:85.5

结构体变量之间的赋值

结构体变量之间可以直接赋值,这将复制所有成员的值,也即把一个结构体的内存直接拷贝给另一个结构体。

但是需要注意,这是一种浅拷贝,如果结构体中包含指针成员,赋值操作只会复制指针的值,而不会复制指针指向的数据,这种情况下需要手动进行深拷贝。

请看下面的例子:

#include

#include

struct Student {

char name[50];

int age;

float score;

};

int main() {

struct Student stu1 = {"张三", 18, 92.5};

struct Student stu2;

// 结构体变量赋值

stu2 = stu1;

// 修改 stu2 的成员

strcpy(stu2.name, "李四");

stu2.age = 20;

printf("stu1:%s, %d, %.1f\n", stu1.name, stu1.age, stu1.score);

printf("stu2:%s, %d, %.1f\n", stu2.name, stu2.age, stu2.score);

return 0;

}

输出结果:

stu1:张三, 18, 92.5

stu2:李四, 20, 92.5

结构体的嵌套定义

结构体还可以嵌套定义,即一个结构体的成员可以是另一个结构体,这种特性使得我们可以构建更复杂的数据类型。请看下面的代码:

struct Date {

int year;

int month;

int day;

};

struct Student {

char name[50];

int age;

struct Date birthday; // 结构体嵌套

float score;

};

// 嵌套结构体的初始化

struct Student stu = {

"张三",

18,

{2005, 8, 15}, // 嵌套的结构体成员也用花括号

92.5

};

使用 typedef 重命名

在实际编程中,为了简化代码,我们经常使用 typedef 关键字为结构体类型定义一个新的类型名,这样在声明变量时就可以省略 struct 关键字。请看代码:

typedef struct Student {

char name[50];

int age;

float score;

} Stu; // 定义别名 Stu

// 使用别名定义变量,不需要再写 struct

Stu stu1 = {"张三", 18, 92.5};

Stu stu2;

结构体类型的大小

需要注意的是,结构体的大小不一定等于所有成员大小的简单相加。由于内存对齐的原因,编译器可能会在成员之间插入一些填充字节。如果需要了解结构体的实际大小,可以使用 sizeof 运算符:

#include

struct Test {

char c; // 1 字节

int i; // 4 字节

double d; // 8 字节

};

int main() {

printf("结构体大小:%zu 字节\n", sizeof(struct Test));

return 0;

}

输出结果可能是:

结构体大小:16 字节

虽然成员大小加起来是 13 字节,但由于内存对齐,实际的结构体大小是 16 字节。这种内存对齐机制是为了提高程序的运行效率,但同时也会占用更多的内存空间。

总起来说,结构体是一种自定义的、复合的数据类型,而不是变量。变量可以直接使用,而数据类型还需要声明变量才能使用。理解这一点非常重要,这是结构体的本质。

结构体在C语言编程中有着广泛的应用,通过合理使用结构体,我们可以更好地组织和管理复杂的数据。在开发较复杂的程序时,结构体常常与其他高级特性(如动态内存分配、文件操作等)结合使用,构建更复杂的数据结构和算法。

相关推荐

泰国红牛多少钱一瓶(泰国红牛价格)
mobile365体育投注官网

泰国红牛多少钱一瓶(泰国红牛价格)

📅 07-14 👁️ 5540
电信去哪里充值流量卡便宜(电信充值流量卡哪里便宜?Top 8充值推荐!)
游戏火锅怎卖多少一盒
365bet手机版下载

游戏火锅怎卖多少一盒

📅 07-07 👁️ 4993
老本行意思
365bet手机版下载

老本行意思

📅 08-19 👁️ 6958
中国十大融资平台(中国融资网)
mobile365体育投注官网

中国十大融资平台(中国融资网)

📅 07-08 👁️ 2130
原来《精绝古城》中的雪莉杨, 身上藏着这样的大秘密
Bet体育365第二次提款要多久

原来《精绝古城》中的雪莉杨, 身上藏着这样的大秘密

📅 08-07 👁️ 6735
魔兽世界罪孽角斗士套装怎么获得
mobile365体育投注官网

魔兽世界罪孽角斗士套装怎么获得

📅 08-10 👁️ 7021
从此,世上再无摩拜
Bet体育365第二次提款要多久

从此,世上再无摩拜

📅 07-17 👁️ 335
为什么买奔驰的人越来越多
Bet体育365第二次提款要多久

为什么买奔驰的人越来越多

📅 06-29 👁️ 8906