C语言结构体入门:定义、访问与传参全解析

在C语言中,结构体(struct)是处理复杂数据的核心工具------它能将不同类型的数据(如字符串、整数)封装成一个整体,特别适合描述真实世界中的实体(比如学生、员工、商品)。本文将通过"学生信息管理"的实例,从零讲解结构体的定义、三种访问方式,以及函数传参的两种常用形式,搭配完整代码演示,帮你快速掌握结构体核心用法。

一、结构体基础:如何定义一个"数据模板"

结构体的本质是自定义数据类型,我们先定义一个"学生"模板,包含姓名、年龄、性别、学号四个属性:

// 方式1:直接定义结构体类型

struct stu

{

char name[20]; // 姓名(字符串数组存储)

int age; // 年龄(整型)

char sex[5]; // 性别(字符串数组,兼容多字符)

char id[23]; // 学号(字符串数组,适配长学号)

};

// 方式2:用typedef给结构体起"别名"(更简洁)

typedef struct stu

{

char name[20];

int age;

char sex[5];

char id[23];

} stp1; // stp1是struct stu的别名,后续可直接用stp1定义变量

  • 关键点: typedef 的作用是简化类型名,避免每次定义变量都写 struct stu ,直接用 stp1 即可,代码更简洁(后文以别名方式为主演示)。

二、结构体变量的三种访问方式

定义结构体变量后,有三种常用方式访问其内部成员,核心区别在于是否使用指针。我们先定义变量和指针,再逐一演示:

// 定义结构体变量并初始化

stp1 st1 = {"龙傲天", 20, "男", "124124552"};

stp1* p = &st1; // 定义指针p,指向结构体变量st1的地址

  1. 直接访问:变量名.成员名(最直观)

通过"变量名 + 点号(.) + 成员名"直接访问,适合非指针场景:

printf("姓名:%s\n", st1.name); // 输出:龙傲天

printf("年龄:%d\n", st1.age); // 输出:20

printf("性别:%s\n", st1.sex); // 输出:男

printf("id:%s\n", st1.id); // 输出:124124552

  1. 解引用访问:(*指针).成员名(指针场景基础用法)

如果拿到的是结构体指针,需先通过 * 解引用获取指针指向的变量,再用点号访问成员(注意括号不能少, * 优先级低于 . ):

printf("姓名:%s\n", (*p).name); // 解引用p,等价于st1.name

printf("年龄:%d\n", (*p).age); // 输出:20

  1. 指向符访问:指针->成员名(指针场景简化用法)

C语言专门为结构体指针提供了简化语法 -> ,直接用"指针名 + -> + 成员名"访问,无需解引用,是指针场景的首选:

printf("姓名:%s\n", p->name); // 等价于(*p).name,更简洁

printf("年龄:%d\n", p->age); // 输出:20

三种方式效果对比

运行代码后,三种访问方式输出结果完全一致:

plaintext

姓名:龙傲天

年龄:20

性别:男

id:124124552

==========================

姓名:龙傲天

年龄:20

性别:男

id:124124552

==========================

姓名:龙傲天

年龄:20

性别:男

id:124124552

  • 总结:非指针用 变量.成员 ,指针用 指针->成员 (推荐), (*指针).成员 是等价写法但稍繁琐。

三、结构体函数传参:两种方式对比

结构体变量可作为函数参数传递,核心有两种方式:值传递和指针传递,我们通过两个函数演示差异。

  1. 指针传参:void ad1(stp1* p)

将结构体变量的地址(指针)传给函数,函数内部通过 -> 访问成员:

void ad1(stp1* p)

{

printf("姓名:%s\n", p->name);

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

printf("性别:%s\n", p->sex);

printf("id:%s\n", p->id);

}

// 调用方式:传入指针p或&st1

ad1(p); // 正确

ad1(&st1); // 也正确,直接传变量地址

  1. 值传递:void ad2(stp1 st1)

将结构体变量的"副本"传给函数,函数内部通过 变量.成员 访问:

void ad2(stp1 st1)

{

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

printf("年龄:%d\n", st1.age);

printf("性别:%s\n", st1.sex);

printf("id:%s\n", st1.id);

}

// 调用方式:直接传入结构体变量

ad2(st1);

两种传参方式核心区别

传参方式 优点 缺点 适用场景

指针传递 不拷贝数据,效率高;可修改原变量 需注意指针合法性(避免野指针) 结构体较大、需修改原数据

值传递 语法简单,不影响原变量 拷贝整个结构体,占用内存多、效率低 结构体较小、无需修改原数据

传参效果演示

调用两个函数后,输出结果与直接访问一致:

plaintext

============指针传参==============

姓名:龙傲天

年龄:20

性别:男

id:124124552

==========================

姓名:龙傲天

年龄:20

性别:男

id:124124552

四、完整可运行代码(含三种访问+两种传参)

#include <stdio.h> // 包含printf函数所需头文件

// 用typedef定义结构体并起别名stp1

typedef struct stu

{

char name[20];

int age;

char sex[5];

char id[23];

} stp1;

// 指针传参函数

void ad1(stp1* p)

{

printf("姓名:%s\n", p->name);

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

printf("性别:%s\n", p->sex);

printf("id:%s\n", p->id);

}

// 值传递函数

void ad2(stp1 st1)

{

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

printf("年龄:%d\n", st1.age);

printf("性别:%s\n", st1.sex);

printf("id:%s\n", st1.id);

}

int main()

{

// 定义并初始化结构体变量

stp1 st1 = {"龙傲天", 20, "男", "124124552"};

stp1* p = &st1; // 定义结构体指针

// 方式1:直接访问(变量.成员)

printf("==========直接访问==========\n");

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

printf("年龄:%d\n", st1.age);

printf("性别:%s\n", st1.sex);

printf("id:%s\n", st1.id);

// 方式2:解引用访问((*指针).成员)

printf("==========解引用访问==========\n");

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

printf("年龄:%d\n", (*p).age);

printf("性别:%s\n", (*p).sex);

printf("id:%s\n", (*p).id);

// 方式3:指向符访问(指针->成员)

printf("==========指向符访问==========\n");

printf("姓名:%s\n", p->name);

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

printf("性别:%s\n", p->sex);

printf("id:%s\n", p->id);

// 指针传参调用

printf("==========指针传参==========\n");

ad1(p);

// 值传递调用

printf("==========值传递==========\n");

ad2(st1);

return 0;

}

五、学习总结

  1. 结构体是"自定义数据类型",用于封装不同类型的关联数据,定义时可通过 typedef 起别名简化语法;

  2. 成员访问三剑客: 变量.成员 (非指针)、 (*指针).成员 (指针解引用)、 指针->成员 (指针简化,推荐);

  3. 函数传参二选一:指针传递(高效、可修改原数据)、值传递(简单、不影响原数据),优先用指针传递尤其是结构体较大时;

  4. 实操关键:初始化字符串用双引号,数组长度要预留足够空间(如姓名20位、学号23位),避免越界。

结构体是C语言面向对象编程的基础雏形,掌握它后,后续处理数组、链表、文件操作中的复杂数据会更轻松。建议多修改代码(比如添加"成绩"成员、修改传参逻辑),加深理解~

相关推荐
烤麻辣烫43 分钟前
黑马程序员苍穹外卖(新手)DAY6
java·开发语言·学习·spring·intellij-idea
whale fall1 小时前
【剑雅14】笔记
笔记
玩转C语言和数据结构2 小时前
C语言编程入门攻略(最新学习路线,适合新手小白)
c语言·c语言入门·c语言下载·c语言知识点总结·c语言自学·c语言教程·c语言怎么学
星空的资源小屋2 小时前
跨平台下载神器ArrowDL,一网打尽所有资源
javascript·笔记·django
Xudde.2 小时前
Quick2靶机渗透
笔记·学习·安全·web安全·php
Bona Sun2 小时前
单片机手搓掌上游戏机(十四)—pico运行fc模拟器之电路连接
c语言·c++·单片机·游戏机
AA陈超3 小时前
Git常用命令大全及使用指南
笔记·git·学习
无限进步_3 小时前
C语言数组元素删除算法详解:从基础实现到性能优化
c语言·开发语言·windows·git·算法·github·visual studio
松涛和鸣3 小时前
16、C 语言高级指针与结构体
linux·c语言·开发语言·数据结构·git·算法
麦麦在写代码4 小时前
前端学习5
前端·学习