当前位置: 首页 > news >正文

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
 
 
2. 解引用访问:(*指针).成员名(指针场景基础用法)
 
如果拿到的是结构体指针,需先通过 * 解引用获取指针指向的变量,再用点号访问成员(注意括号不能少, * 优先级低于 . ):
 
printf("姓名:%s\n", (*p).name);  // 解引用p,等价于st1.name
printf("年龄:%d\n", (*p).age);   // 输出:20
 
 
3. 指向符访问:指针->成员名(指针场景简化用法)
 
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); // 也正确,直接传变量地址
 
 
2. 值传递: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语言面向对象编程的基础雏形,掌握它后,后续处理数组、链表、文件操作中的复杂数据会更轻松。建议多修改代码(比如添加“成绩”成员、修改传参逻辑),加深理解~
 

http://www.dtcms.com/a/582655.html

相关文章:

  • 住房城乡建设部门户网站苏州建设公司有哪些
  • 软件工程综合实践3实验报告——校园二手交易平台系统(黑龙江大学)
  • 设计制作网站板面网站建设优化开发公司哪家好
  • “职场心态与心穷
  • 网站怎么做微信支付宝wordpress占用cpu过高
  • 郑州网站推广营销百度搜索引擎竞价排名
  • 班级网站建设思路手机模板网站模板下载
  • Rust 练习册 :Nucleotide Codons与生物信息学
  • 东坑网站仿做麻涌镇做网站
  • stm32的gpio模式到底该怎么选择?(及iic,spi,定时器原理介绍)
  • 【MySQL】触发器、日志、锁机制 深度解析
  • 电商网站后台艺术设计
  • 【湖北政务服务网-注册_登录安全分析报告】
  • 酒店网站模板设计方案网站页面设计需求文档
  • Databend 十月月报:存储过程正式可用,数据流程全面自动化
  • 湖南大型网站建设公司登陆国外网站速度慢
  • 百度恶意屏蔽网站wordpress 渗透框架
  • 算法数学---差分数组(Difference Array)
  • 石家庄城乡建设局网站服装定制品牌有哪些
  • PrettyZoo:优雅易用的 ZooKeeper 可视化管理工具
  • Trae下架Claude,但Vibe Coding之路才刚刚开始
  • 哪些行业网站推广做的多上海制作网站开发
  • 二叉树的前序遍历详解(图文并茂,C语言实现)
  • 彩票网站开发需要多少钱2020 惠州seo服务
  • 建设部网站施工合同版本网络营销推广策划书
  • Codeforces Global Round 30 (Div. 1 + Div. 2)
  • pugixml使用说明
  • 贵阳市建设厅官方网站南京企业网站开发公司
  • 原创文章对网站的好处抢注域名网站
  • 一本通网站1122题:计算鞍点