黑马程序员——c语言基础:结构体(高级)

C语言中结构体在实战中的高级用法 结构体可以嵌套在其他结构体中,形成复合结构。这对于表示更复杂的数据结构很有用。结构体位域允许你在一个结构体中指定每个成员占用的位数。这对于节省内存空间和处理硬件寄存器等场景很有用。结构体和指针可以相互配合使用,允许对结构体进行动态分配和动态访问结构体成员在内存中的存储通常受到对齐和填充的影响。你可以使用特定的编译指令(例如)来控制对齐和填充。 阅读详情

1.结构体数组

 结构体数组:

    数组的元素也可以是结构类型的。因此可以构成结构型数组。结构数组的每一个元素都是具有相同结构类型的结构变量。

 结构体数组定义:

    1)定义结构体的同时,定义数组

    struct Student{

        int age;

        char *name;

        int s_no;

        float score;

    } stu[5];

    2)先定义结构体,再定义数组

    struct Student boy[5];

 

 结构体数组的初始化

    1)定义的同时初始化

    2)先定义后初始化


结构体数组的初始化和遍历举例:

#include <stdio.h>


int main(int argc, const char * argv[]) {

    // 1.定义结构体数组的时候,进行初始化

    struct Student{

        char name[20];

        int age;

    } boys[3] ={{"zhangsan",12},{"lisi",23},{"wangwu",34},};

    

    // 2.定义的同时进行初始化

    struct Student girls[2] = {{"lucy",21},{"lily",32}};

    

    // 3.先定义后初始化,整体赋值

    struct Student ds[2];

    ds[0] = (struct Student){"wangwei",19};

    

    // 4.先定义后初始化,部分赋值

    struct Student stu[2];

    stu[0].age = 23;

    

    // 结构体数组的遍历

    for (int i = 0; i < 3; i ++) {

        printf("name : %s, age :%d\n",boys[i].name, boys[i].age);

    }

    

    return 0;

}


应用1:利用定义好的结构体数组,1、计算学生平均成绩和不及格人数。2、打印80-100分学生的成绩和姓名

#include <stdio.h>


int main(int argc, const char * argv[]) {

    // 定义结构体

    struct stu{

        int num;

        char *name;

        char sex;

        float score;

    };

    

    // 定义结构体数组

    struct stu boy[5] ={

        {101,"Li ping",'F',45},

        {102,"Zhang ping",'M',62.5},

        {103,"He fang",'F',92.5},

        {104,"Cheng ling",'M',87},

        {105,"Wang ming",'M',58},

    };

    

    // 定义变量

    float sumScore = 0; // 总成绩

    float avgScore = 0; // 平均成绩

    int bjg = 0; // 不及格人数

    

    for (int i = 0; i < 5 ; i ++) {

        sumScore += boy[i].score; // 总分累加

        if (boy[i].score < 60) { // 如果分数低于60

            bjg ++; // 不及格人数+1

        }

        if (boy[i].score >= 80 && boy[i].score <= 100) { // 如果分数在80-100之间

            printf("score = %.2f name = %s\n",boy[i].score, boy[i].name); // 打印成绩和姓名

        }

    }

    

    // 计算平均分

    avgScore = sumScore / 5;

    

    // 打印学生平均成绩和不及格人数

    printf("学生的平均成绩为%.2f 不及格学生人数为%d\n",avgScore, bjg);

    return 0;

}


应用2:用结构体实现通讯录,让用户从键盘输入要保存的姓名和电话,然后打印出来。

#include <stdio.h>

#define LEN 3

int main(int argc, const char * argv[]) {

    

    // 定义一个结构体

    struct list{

        char name[21];

        char number[12];

    };

    

    // 定义一个结构体数组

    struct list l[LEN];

    

    // 提示用户输入

    printf("请输入联系人,格式:姓名 电话号码\n");

    

    // 接收并保存用户输入数据

    for (int i = 0; i < LEN; i ++) {

        scanf("%s %s", l[i].name, l[i].number);

    }

    

    // 输出通讯录

    for (int i = 0; i < LEN; i ++) {

        printf("姓名:%s 电话:%s\n", l[i].name, l[i].number);

    }

    return 0;

}



2.结构体指针

 结构体指针: 用来存放结构体变量地址的指针变量。

 结构体指针的定义

    struct 结构体名 *指针变量名;

 结构体指针间接访问成员值

    其一般形式为: (*结构体指针变量).成员名  或为: 结构体指针变量 ->成员名

应用举例:

#include <stdio.h>


int main(int argc, const char * argv[]) {

    

    // 先定义一个结构体变量

    struct Car{ // Car 是结构体名

        int wheels;

        int speed;

    } car1; // car1是结构体变量名

    

    // 初始化car1

    car1 = (struct Car){4,180};

    

    struct Car *p = NULL; // 定义一个结构体指针变量p并初始化为NULL

    

    p = &car1; // 结构体指针变量p指向了结构体变量car1

    

    // 用结构体指针间接访问结构体变量的成员值

    printf("car1 的轮子数为%d,速度为%d",(*p).wheels, p ->speed);

    

    return 0;

}



3.结构体嵌套

 结构体的嵌套:

    结构体定义中,结构体的成员又是另外一个结构体变量

 结构体嵌套的注意事项:

    1)结构体定义中可以嵌套其他结构体类型的变量,不可以嵌套自己这个类型的变量。

    2)可以嵌套自己类型的指针。

应用举例:

#include <stdio.h>


int main(int argc, const char * argv[]) {

    // 定义了一个Date的结构体

    struct Date{

        int year;

        int month;

        int day;

    };

    

    // 定义了一个Student结构体

    struct Student{

        char *name;

        int age;

        float score;

        // struct Student stu; // 错误的,嵌套了自己这个类型的变量

        // struct Student *stu; // 嵌套了当前类型的指针,是可以的

        struct Date birthday; // 嵌套了其他结构体类型的变量

    };

    

    // 对嵌套的结构体进行初始化

    struct Student gam = {"gamhunter", 25, 99.99, {1989,11,11}};

    

    // 对嵌套的结构体进行访问

    printf("姓名:%s,年龄:%d,成绩:%.2f,生日:%d-%02d-%02d\n", gam.name, gam.age, gam.score, gam.birthday.year, gam.birthday.month, gam.birthday.day);

    

    

    // 结构体嵌套自身的指针

    struct Person {

        char *name;

        int age;

        struct Person *child; // 嵌套自己类型的指针

    };

    

    // 初始化嵌套自身指针的结构体

    struct Person child = {"kimy", 4, NULL}; // 定义并初始化kimy

    struct Person father = {"林志颖", 40, &child}; // 定义并初始化林志颖


    // 访问嵌套自身指针的结构体

    printf("%s的儿子是%s,儿子的年龄是:%d\n", father.name, (*father.child).name, father.child ->age);

    

    return 0;

}



4.结构体变量、成员及指针作为函数参数


注意:

用结构体变量及成员作为函数参数,实质上都是值传递

用结构体指针作为函数参数,实质上是地址传递


#include <stdio.h>


// 定义了一个结构体Car

struct Car {

    int wheels;

    int speed;

};


/**

 *  结构体变量的成员作为函数参数

 *

 *  @param n 轮子数

 */

void fixCar1(int n){

    n = 2;

}


/**

 *  结构体变量作为函数参数

 *

 *  @param n 轮子数

 */

void fixCar2(struct Car c){

    c.wheels= 2;

}


/**

 *  结构体指针作为函数参数

 *

 *  @param p 结构体指针

 */

void fixCar3(struct Car *p){

    p -> wheels = 2;

}

int main(int argc, const char * argv[]) {

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

    struct Car car1 = {4, 200};

    

    //1.结构体变量的成员作为函数参数

    fixCar1(car1.wheels);

    

    // 查看结构体变量成员有无变化

    printf("%d\n", car1.wheels); // 输出值还是4,结论:用结构体变量的成员值作为函数的参数,实质是值传递

    

    // 2.用结构体变量作为函数的参数

    fixCar2(car1);

    printf("%d\n", car1.wheels); // 输出值还是4,结论:用结构体变量的作为函数的参数,实质也是值传递

    

    // 3.用结构体指针作为函数参数

    struct Car *c = &car1;

    fixCar3(c);

    printf("%d\n", car1.wheels); // 输出值是2,结论:用结构体指针作为函数参数,实质是地址传递

    

    return 0;

}




黑马程序员——C语言基础教程笔记 黑马程序员——C语言基础教程笔记 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 文章目录黑马程序员——C语言基础教程笔记前言Day-11.C语言概论1.1 什么是C语言1.1.1 C语言特点1.1.2 学习C语言的理由1.1.3 发展方向1.1.4 C语言中的关键字2.3.Day-21.引入库2.读入数据总结 前言 研三了,作为一枚菜鸡硕,为了找工作,只好重刷C语言。以下笔记是我在“黑马程序员:http://yun. 阅读详情

相关推荐

从圆形到椭圆:CenterNet中高斯热图半径的自适应优化策略

本文深入探讨了CenterNet目标检测模型中高斯热图生成策略的优化,针对传统圆形高斯核在处理长宽比差异大目标时的局限性,提出了自适应椭圆高斯核的解决方案。通过数学推导和代码实战,详细阐述了如何根据目标边界框尺寸动态计算椭圆长短轴半径,生成更贴合目标几何形状的热图监督信号,从而有效提升模型,尤其是对无人机、车辆等不规则目标的定位精度。

alice7model的博客 985

c语言简易学生信息管理系统(初学)

c语言学生信息管理系统简易版

qq_74215357的博客 5785

Android Geckoview实战:5分钟搞定JS与原生交互(附完整Demo代码)

本文详细介绍了在Android应用中使用GeckoView替代系统WebView,构建稳定高效的JavaScript与原生代码交互桥梁的实战方法。通过WebExtension架构,文章提供了从环境配置、扩展开发到Android端集成的完整步骤,并附有可运行的Demo代码,帮助开发者快速解决混合应用中的兼容性问题。

u5v6w7的博客 936

万字长文剖析C语言结构体的高级用法

关注、星标公众号,直达精彩内容ID:txp学Linux作者:txp 前言 ...

李肖遥的专栏 2433

7.18 GART 与 GPUVM 对比:一颗 GPU 上两套页表的分工

本文横向对比AMD GPU上并存的GART与GPUVM两套页表。GART为内核专用,全局单一,线性单层结构,CPU同步直写;GPUVM为每进程48位地址空间,四级页表,含并发状态机,支持隔离与迁移。二者通过VMID区分,共享GMC硬件与PTE编码,分工互补。

图形/计算GPU的驱动与虚拟化技术分享园地 390

日常工作记录---在虚拟机中进行slam建图

   今天是10月24号,首先祝各位程序员们节日快乐!!!    最近一周由于实习的原因,对ROS的探索学习,停滞了一段时间,所以今天也就没什么大的进展,本篇文章仅仅记录一下,我在虚拟机中进行slam建图可行性验证的过程,本篇文章同样使用古月学院《如何在Gazebo中实现阿克曼转向车的仿真》的课程资料来进行验证    下面各条之间并没有严格的顺序关系,每一条都是独立的,都是我在验证过程中的经验或者记录:    1、在运行roslaunch bringup racecar_gazebo_rviz.lau

慕羽★的博客 4829

C高级-条件编译和结构体

【1】回顾指针相关和函数相关 【2】条件编译 (1)编译器根据条件的真假决定是否编译相关的代码, 常见的条件编译有两种方法: 一、根据宏是否定义,其语法如下: #ifdef …… #else …… #endif 实例: #define DEBUG #ifdef DEBUG printf(“The macro DEBUG is defined\n”); #else printf(“The m...

weixin_42399752的博客 684

如何在Windows上安装Node-RED?

Node-RED 是一款基于流程的可视化编程工具,专注于物联网(IoT)和自动化应用的快速开发,其核心特点是通过拖拽节点构建数据流网络,实现低代码/无代码编程。

猿小白的博客 1173

C++泛型函数学习

1 模板 1.1 模板的概念 1.2 函数模板 1.2.1 函数模板语法 1.2.3 函数模板案例 1.2.4 普通函数与函数模板的区别 1.2.5 普通函数与函数模板的调用规则–可以发送函数重载 1.2.6 模板的局限性 1.3 类模板 1.3.1 类模板语法 1.3.3 类模板中成员函数创建时机 1.3.5 类模板与继承 C++提高编程 本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨...

hkk1151043545的博客 4314

C#使用OpenCvSharp+微信模型识别多个二维码

本文介绍了一个基于OpenCvSharp和微信开源二维码检测器的多二维码识别项目。该项目通过C# WinForm实现,主要功能包括:加载图片、识别图片中的多个二维码并显示识别结果。核心代码使用了OpenCvSharp.WeChatQRCode类,通过预训练的caffe模型(detect.prototxt/detect.caffemodel和sr.prototxt/sr.caffemodel)进行二维码检测和解码。识别结果包括每个二维码的编号、内容及位置信息。项目适用于批量二维码识别场景,部署简单,识别效果良

遇见--专栏 123

K-Core, K-Shell & K-Crust傻傻分不清楚

K-Core(K-核)就是所有大于等于K的K-Shell的并集;K-Crust(K-皮)就是所有小于等于K的K-shell的并集。

欢迎订阅 -- 小源笔迹 2256

黑马程序员 — C语言基础(一)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------

iyaochao的专栏 574

[VCS]VCS checkpoint简介以及其在SoC验证加速中的作用

VCS checkpoint是Synopsys VCS提供的快照/恢复机制,可显著加速SoC验证。其核心是在仿真关键节点(如完成初始化后)保存系统状态,后续测试可直接从该点恢复,避免重复执行冗长的初始化阶段(如boot、DDR训练等)。该技术特别适用于多测试用例共享同一初始状态的场景,通过分离初始化与功能验证流程,可提升回归效率3-5倍。需注意处理DPI-C状态同步、版本管理及存储优化等问题,结合UVM和自动化脚本可实现更高效的验证流程。典型应用可节省数百万cycle的重复仿真时间。

元直的博客 778

《黑马程序员C++》课程笔记总结

我的小站——半生瓜のblog 黑马程序员C++视频——黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难 笔记列表&对应视频 基础部分(1-83)——如果你准备学习C++,并且有C语言的基础,我希望你能简单的过一遍知识点。 核心部分(84-146)——C++核心编程部分-内存分区模型-引用-函数提高-类与对象-文件操作 案例1(147-166)——职工管理系统——C++实现职工管理系统 进阶部分(167-263)——C++提高编程部分-泛型编程-STL 案例2(264-281)—.

半生瓜のblog 19万+

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

黑马程序员——C语言基础——结构体相关练习

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 今天整理了C语言基础学习过程中对结构体的一些知识,下面是代码片段:

Elors的博客 1625

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

笔记——C语言基础讲义(黑马程序员)

在程序设计中,为了方便处理数据把具有相同类型的若干变量按有序形式组织起来——称为数组。数组就是在内存中连续的相同类型的变量空间。同一个数组所有的成员都是相同的数据类型,同时所有的成员在内存中的地址是连续的。数组属于构造数据类型: 一个数组可以分解为多个数组元素:这些数组元素可以是基本数据类型或构造类型。int a[10]; 按数组元素类型的不同,数组可分为:数值数组、字符数组、指针数组、结构数组等类别。int a[10];char s[10];

qq_44939870的博客 4628

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

黑马程序员——c语言基础之结构体

------- android培训、java培训、期待与您交流! ---------- C语言构造类型 构造数据类型是根据已定义的一个或多个数据类型用构造的方法来定义的。也就是说,一个构造类型的值可以分解成若干个“成员”和“元素”。每个“成员”都是一个基本数据类型或又是一个构造类型。   定义结构体的方法 一般形式: struct 结构名{ 成员表列 }; 注意:最后的“;”

zhang2292的博客 552

黑马程序员——iOS核心基础(13-14天)-黑马程序员-专题视频课程

C语言基础13-14天。其中包括预处理与结构体。

heima_cxy的博客 247

黑马程序员——C语言基础---结构体

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——- 一、概念 结构体是一种构造类型,它是由若干个成员组成的,每一个成员可以是一个基本数据类型或者又是一个构造类型。结构体可以把功能相同的数据组织起来,存在一起,用的时候方便,而且在调用函数时,若传递参数较多,传一个结构体相对简单。

kingwang的博客 460

黑马程序员——C语言基础——结构体以及结构体指针实战

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 由于结构体和结构体指针比较重要,所以今天继续复习结构体相关知识。 再复习之余,再次尝试编写了一下视频教程中的一道结构体与结构体指针编程题。

Elors的博客 1016

黑马程序员C语言基础(第七天)内存管理

黑马程序员C语言基础(第七天)内存管理 文章目录内存管理作用域8.1.1 局部变量(auto自动变量)8.1.2 静态(static)局部变量普通局部变量和静态(static)局部变量的区别8.1.3 全局变量跨文件使用全局变量示例(没用头文件)跨文件使用全局变量示例(用头文件)8.1.4 静态(static)全局变量8.1.5 extern全局变量声明8.1.6 全局函数(普通函数)和静态函数(static函数)8.1.7 总结8.2 内存布局8.2.1 内存分区(text代码区、data区、bss区、栈

Dontla的博客 2908

黑马程序员——C语言基础---结构体1

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------                      第一讲    构造类型及结构体  1、C语言构造类型  构造数据类型:构造数据类型是根据已定义的一个或多个数据类型用构造的方法来定义的。 也就是说,一个构造类型的值可以分解成若干个“成员”或“元素”。每个“成员”都是一个基本数据类型或又是一个构造

lhp_heima的博客 666

黑马程序员——c语言基础:结构体(基础)

1. 结构体概念: 结构体是由一系列相同类型或不同类型的数据用构造方法构造的数据集合,也叫结构。 2. 结构体作用: 结构体可以把功能相同的数据组织起来,存在一起,用的时候方便,而且在调用函数时,若传递的参数较多,传一个结构体相对而言简单些,很多系统自带的函数必须用结构体。 3. 结构体的定义:     struct 结构体名{         成员列表;

gamhunter的博客 666

黑马程序员C语言提高课程配套课件:深入学习C语言的高级特性和应用技巧

黑马程序员C语言提高课程配套课件:深入学习C语言的高级特性和应用技巧 去发现同类优质开源项目:https://gitcode.com/ 项目核心功能/场景 提供C语言提高课程课件,助力编程技能提升。 项目介绍 在编程世界中,C语言一直是众多程序员心中的经典之选。它不仅拥有简洁明了的语法,更具备强大的功能和灵活的应用场景。为了帮助编程爱好者在C语言的旅程中更进一步,黑马程序员精心打造了一套C语言提高...

gitblog_06779的博客 330

黑马程序员——C语言之结构体

-------android培训、java培训、iOS培训、.Net培训、期待与您交流! ---------- 在实际问题中,一组数据往往具有不同的数据类型;例如在学生信息登记表中,姓名为字符型,学号为整型或字符型,年龄为整型,性别为字符型,成绩为整型或实型。因为数据类型不同,显然不能用一个数组来存放。 在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据。定义结构体的一般形

lucky2468的博客 617

黑马程序员——C语言基础---结构体、枚举

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-第一讲 结构体的概念和定义 我们可以将描述某个事物的一组变量定义为结构体。和数组类似,结构体也是集合变量,不同的是,结构体可以定义不同类型的变量。例如,我们可以定义一个人结构体Person ,该结构体变量中可以定义int 类型的年龄、字符串类型的姓名和布尔类型的婚否等。结构体的语法结构如下: struct 结

qq_27239329的博客 540
上一篇: 黑马程序员——c语言基础:结构体(基础)
下一篇: 黑马程序员——c语言基础:枚举和typedef
gamhunter
博客等级 码龄12年 15粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值