【C语言】C语言期末突击/考研--结构体与C++引用

一、结构体--结构体对齐--结构体数组

1.1.结构体的定义、初始化、结构体数组

    有时候需要将不同类型的数据组合为一一个整体,以便于引用。 例如,一名学生有学号、姓
名、性别、年龄、地址等属性,如果针对学生的学号、姓名、年龄等都单独定义一个变量,那么在有多名学生时,变量就难以分清。为此,C语言提供结构体来管理不同类型的数据组合。
声明一个结构体类型的一般形式为:

struct        结构体名
                {成员表列};

例如,

struct  student
        {
                int num;char name[20];char sex;
                int age;float score;char addr[30];
        };

先声明结构体类型,再定义变量名。例如:

struct student        student1, student2;

接下来看例1.1。

【例1.1】 结构体的scanf读取和输出。

#include <stdio.h>
struct student{int num;char name[20];char sex;int age;float score;char addr[30];
}; //结构体类型声明,注意最后一定要加分号int main() {struct student s = {1001, "mumu", 'M', 20, 85.4, "Shenzhen"}; //定义及初始化struct student sarr[3];int i;printf("%d %s %c %d %f %s \n", s.num, s.name, s.sex, s.age, s.score, s.addr);for (i = 0; i < 3; i++) {scanf("%d%s %c%d%f%s", &sarr[i].num, sarr[i].name, &sarr[i].sex,&sarr[i].age, &sarr[i].score, sarr[i].addr);}for (i = 0; i < 3; i++) {printf("%d %s %c %d %f %s\n", sarr[i].num, sarr[i].name, sarr[i].sex,sarr[i].age, sarr[i].score, sarr[i].addr);}return 0;
}

    结构体类型声明要放在main函数之前,这样main函数中才可以使用这个结构体,工作中往往把结构体声明放在头文件中。注意,结构体类型声明最后一定要加分号,否则会编译不通。另外,定义结构体变量时,使用struct student来定义,不能只有struct或student,否则也会编译不通,sarr 是结构体数组变量。结构体的初始化只能在一开始定义,如果struct students={1001,"lele",'M' ,20,85.4,"Shenzhen"}已经执行,即struct student s已经定义,就不能再执行s=1001,"lele'",'M',20,85.4,"Shenzhen"}.如果结构体变量已经定义,那么只能对它的每个成员单独赋值,如s.num=1003.

    采用“结构体变量名.成员名”的形式来访问结构体成员,例如用s.num访问学号。在进行打印输出时,必须访问到成员,而且printf中的%类型要与各成员匹配。使用scanf读取标准输人时,也必须是各成员取地址,然后进行存储,不可以写成&s,即不可以直接对结构体变量取地址。整型数据(%d) 、浮点型数据(%f) 、字符串型数据(%S) 都会忽略空格,但是字符型数据(%c) 不会忽略空格,所以如果要读取字符型数据,那么就要在待读取的字符数据与其他数据之间加人空格。例1.1中代码的运行结果如图1.1所示,我们可以将运行结果保存到文本文档中。例如,每次运行程序时,在窗口中直接粘贴(通过ctrl v来粘贴),进而方便多次测试。 

 

1.2.结构体对齐

    结构体本身的对齐规则有好几条,比较难记,而且对于考研初试完全没有必要,考研初试只需要记住一条,结构体的大小必须是其最大成员的整数倍!下面我们我们来通过例子来实战。
【例】结构体对齐

#include <stdio.h>struct student_type1{double score;//double是一种浮点类型, 8个字节浮点分为float和double,记住有这两种即可short age;
};struct student_type2{double score;int height;short age;
};struct student_type3{int height;char sex;short age;
};
int main(){struct student_type1 s1;struct student_type2 s2;struct student_type3 s3;printf("s1 size=%d\n",sizeof(s1));printf("s2 size=%d\n",sizeof(s2));printf("s3 size=%d\n",sizeof(s3));return 0;
}

上面的例子运行效果如下:

二、结构体指针与typedef的使用

2.1.结构体指针

    一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设置一个指针变量,用它指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。指针变量也可以用来指向结构体数组中的元素,从而能够通过结构体指针快速访问结构体内的每个成员。下面来看例1.1。
【例2.1】结构体指针的使用:

#include <stdio.h>
//结构体指针
struct student{int num;char name[20];char sex;
};
int main() {struct student s = {1001, "wangle", 'M'};struct student sarr[3] = {1001, "lilei", 'M', 1005, "zhangsan", 'M', 1007, "lili",'f'};struct student *p; //定义结构体指针int num;p=&s;printf("%d %s %c\n", p->num, p->name, p->sex);p=sarr;printf("%d %s %c\n", (*p).num, (*p).name, (*p).sex); //方式一获取成员printf("%d %s %c\n", p->num, p->name, p->sex); //方式 二获取成员printf("------------------------\n");p=p+1;printf("%d %s %c\n", p->num, p->name, p->sex);return 0;}

    由例2.1可以看到,p就是一个结构体指针,可以对结构体s取地址并赋给p,这样借助成员选择操作符,就可以通过p访问结构体的每个成员,然后进行打印。我们知道数组名中存储的是数据的首地址,所以可以将sarr赋给p,这样就可以通过两种方式访问对应的成员。使用(*p).num访问成员为什么要加括号呢?原因是“.” 成员选择的优先级高于“*”(即取值)运算符,所以必须加括号,通过*p得到sarr[0],然后获取对应的成员。 

 

2.2.typedef的使用

    前面定义结构体变量时使用的语句是struct students,以这种方式来定义结构体变量有些麻烦,即每次都需要写struct student。那么有没有简单一些的定义方式呢?答案是肯定的,可以选择使用typedef声明新的类型名来代替已有的类型名,请看例2.1。
【例2.2】 typedef 的使用:

#include <stdio.h>
//结构体指针
typedef struct student{int num;char name[20];char sex;
}stu,*pstu;typedef int INTEGER;int main(){stu s={1001,"wangle",'M'};pstu p;INTEGER i=10;p=&s;printf("i=%d,p->num=%d\n",i,p->num);return 0;
}

    使用stu定义结构体变量和使用structstudent定义结构体变量是等价的;使用INTEGER定义变量i和使用int定义变量i是等价的; pstu 等价于struct student*,所以p是结构体指针变量。

三、C++引用

3.1.C++的引用细则

    对于C++,首先新建源文件时,名字需要叫main.cpp,以cpp后缀结尾,不能像我们之前那样叫main.c。使用C++的引用呢,原因是很多数据结构都采用了这个做法,下面我们来看一下引用的便捷性。

int a; 
void modifynum(int &b)
{
        b=b+1;
}
调用: modifynum(a)


int *p=NULL;
void modify_ pointer(int *&p)
{
        p==q;
}
调用: modify_ pointer(p)

    如上面两个例子所示,我们在修改函数外的某一变量时, 使用了引用后,在子函数内的操作和函数外操作手法一致,这样编程效率较高,对于初学者理解也非常方便。那这种C++的写法,和C语言的代码又是如何对应的呢?下面我们来看一下代码对应关系。
【例3.1】在子函数内修改主函数的普通变量(是C++代码,新建项目要建为C++项目)

#include <stdio.h>void modify_num(int &b)
{b = b + 1;
}
int main() {int a=10;modify_ num(a);printf("after modify_ .num a= =%d\n",a);return 0;
}

上面的代码如果改为纯C,代码如下:
【例3.2】 在子函数内修改主函数的普通变量(纯C代码) 

#include <stdio.h>
void modify_num(int *b) {*b = *b + 1;
}int main() {int a = 10;modify_num(&a);printf("after modify_num a=%d\n", a);return 0;
}

 【例3.3】子函数内修改主函数的一级指针变量(这是是重要的!)

#include <stdio.h>
void modify_pointer(int* &p,int *q)
{p=q;
}
int main() {int *p = NULL;int i = 10;int *q = &i;modify_pointer(p, q);printf("after modify_ pointer *p=%d\n", *p);return 0;
}

上面的代码如果改为纯C,就需要使用到二级指针。二级指针我们没有讲解,因为对于考研初试是使用不到的,因此下面的代码不明白完全没关系,代码如下:

#include <stdio.h>
void modify_pointer(int **p,int *q)
{//相对于C++这里是int **p;*p=q;//这里的写法和例1.2中的是非常类似的
}
int main() {int *p=NULL;int i=10;int *q=&i;modify_pointer(&p,q);//相对于C++这里是&pprintf("after modify_ pointer *p= :%d\n",*p);return 0;
}

 

3.2.C++的布尔类型

    布尔类型在C语言没有,是C++的,有true和false,通过下面代码我们来理解一下它们:
【例3.4】 布尔类型也是有值的

#include <stdio.h>
//设置布尔值的好处是提升J代码的可阅读性
int main() {bool a=true;bool b= false;printf("a=%d,b=%d\n", a,b);return 0;
}

四、练习题及解析 

4.1.结构体--结构体对齐--结构体数组

4.2.结构体指针与typedef的使用

4.3.C++引用

 

致最后

    文章写到这里,本专栏的内容就告一段落啦,希望C语言能够带给您编程的快乐。天色将晚,余晖仍在,就在这样的时刻,我画上了本栏目的最后一个句点。 我推开窗,微风拂面,树影婆娑,恰如此刻我的心境平静而喜悦。今天和往常并没有什么不同,只是内心增添了一分不舍,不论对自己还是对未来都越发充满信心。这种信心来自于一直以来对美好生活的向往与追寻,更来自于在这段生命历程中所感受到的温暖与关爱。这将近十天来对C语言探索与磨练,在此时此地可以收获这样一份满足。最后感谢各位读者的阅读和支持,这些点滴感动我都会铭记于心。我依然会背上思想的行囊继续旅行,带上所有的感激和祝福。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/393961.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MYSQL】表操作

目录 查看当前数据库含有表查看表结构创建表插入&#xff08;新增create&#xff09;查询&#xff08;retrieve&#xff09;全列查询指定列查询查询列是表达式别名查询(as)去重查询(distinct)排序查询(order by)条件查询(where)比较/逻辑运算符使用 分页查询(limit) 一条语句各…

【若依项目-RuoYi】掌握若依前端的基本流程

搞毕设项目&#xff0c;使用前后端分离技术&#xff0c;后端springBoot&#xff0c;前端vue3element plus。自己已经写好前端与后端代码&#xff0c;但想换一个前端界面所以使用到了若依&#xff0c;前前后后遇到许多坑&#xff0c;记录一下&#xff0c;方便之后能够快速回忆。…

尚硅谷谷粒商城项目笔记——八、安装node.js【电脑CPU:AMD】

八、安装node.js 注&#xff1a; [!NOTE] 查看本机系统 官网选择node.js版本 1傻瓜式安装&#xff0c;注意选择路径 图一 图二 至此&#xff0c;nodejs安装完成&#xff01; 2环境配置 找到安装nodejs的路径新增 node_global 和node_cache文件夹 创建完两个空文件夹&#x…

如何快速入门 PyTorch ?

PyTorch是一个机器学习框架&#xff0c;主要依靠深度神经网络&#xff0c;目前已迅速成为机器学习领域中最可靠的框架之一。 PyTorch 的大部分基础代码源于 Ronan Collobert 等人 在 2007 年发起的 Torch7 项目&#xff0c;该项目源于 Yann LeCun 和 Leon Bottou 首创的编程语…

0207、创建场景状态的三个子类

VS使用的是3.5框架&#xff0c;会自带Linq这一行&#xff0c;Unity不支持&#xff0c;需要删除 一、创建三个场景 二、创建三个子类

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——5Webscoket节点的使用

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——5Webscoket节点的使用 ​ 有了前面几篇文章的铺垫&#xff0c;现在已经可以实现我到手测试那一步的 1.解读usb_websocket_display.launch.py ​ 首先进入这个目录/root/dev_ws/src/origincar/originca…

Java语言程序设计——篇十二

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…

ChatGPT能代替网络作家吗?

最强AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频百万播放量https://aitools.jurilu.com/ 当然可以&#xff01;只要你玩写作AI玩得6&#xff0c;甚至可以达到某些大神的水平&#xff01; 看看大神、小白、AI输出内容的区…

【枚举 图论】2242. 节点序列的最大得分

本文涉及知识点 枚举 图论知识汇总 LeetCode 2242. 节点序列的最大得分 给你一个 n 个节点的 无向图 &#xff0c;节点编号为 0 到 n - 1 。 给你一个下标从 0 开始的整数数组 scores &#xff0c;其中 scores[i] 是第 i 个节点的分数。同时给你一个二维整数数组 edges &…

logging日志实操入门

一、代码 import logging from logging.handlers import RotatingFileHandler # 配置日志 log_file_path ./logs/test.log file_handler RotatingFileHandler(log_file_path, maxBytes10, backupCount5)# 设置格式化器&#xff0c;以使日志更易读 formatter logging.Format…

Webstorm的下载与安装

Webstorm的下载 1 在浏览器的地址栏输入https://www.jetbrains.com/webstorm/&#xff0c;进入主页面 2 点击右上角的Download按钮&#xff0c;进入下载页面&#xff0c;如图所示 Webstorm的安装 按步骤逐步安装即可

SwiftUI 如何定制 Picker 视图当前选中行的背景颜色?

功能需求 有时我们希望可以定制 SwiftUI 中 Picker 视图当前选中行的背景色,这可以做到吗? 在上面的演示图中,我们随心所欲地变换着 SwiftUI 中 Picker 视图当前选中行的背景色。这是怎么做到的呢? 在本篇博文中,您将学到以下内容 功能需求1. 钩深极奥:修改 SwiftUI 原…

嵌入式学习之路 13(C语言基础学习——预处理命令)

编程流程 在进行程序开发时&#xff0c;通常遵循编辑源代码、编译、运行和调试这几个主要步骤。 编辑源代码&#xff1a;使用文本编辑器创建或修改程序的源代码&#xff0c;这是整个编程过程的起点。编译&#xff1a;将源代码转换为可执行文件的关键步骤。 预处理&#xff1a…

C#重要知识归纳总结

C#教程 C# 结构体&#xff08;Struct&#xff09; | 菜鸟教程C# 结构体&#xff08;Struct&#xff09; 在 C# 中&#xff0c;结构体&#xff08;struct&#xff09;是一种值类型&#xff08;value type&#xff09;&#xff0c;用于组织和存储相关数据。 在 C# 中&#xff0c…

微服务-实现nacos的集群和Gateway网关的实现、认证校验、解决跨域

1. nacos的集群模式 1.1 分析 nacos在企业中的使用100%都是集群模式。需要掌握nacos集群的搭建 nacos的数据存放在derby本地磁盘中&#xff0c;nacos集群模式会导致数据库数据不一致&#xff0c;使用加一层思想&#xff0c;修改nacos的数据库&#xff0c;使用mysql数据库&…

浅析中国蚁剑的木马加密流量

简介 在蓝帽杯 2022 初赛中&#xff0c;domainhacker 的流量分析题目聚焦于中国蚁剑这款 webshell 管理工具的流量特征。通过对比赛提供的数据包进行解析&#xff0c;本文将深入分析蚁剑在连接木马时产生的加密流量。 公司安全部门&#xff0c;在流量设备中发现了疑似黑客入侵的…

idea使用free流程,2024idea免费使用

1.先到官网下载&#xff0c;这里选择win系统的&#xff0c;点击下图的.exe https://www.jetbrains.com/idea/download/?sectionwindows 2.下载好后基本上就是一直点击“下一步”到直到安装好&#xff0c;安装好后先打开软件后关闭退出 3.下载配配套资料 链接: https://pan.ba…

MySQL内存模型与相关技术

MySQL实例的大概结构如下 如上图所示&#xff0c;InnoDB的存储引擎右多个内存块 维护所有进程/线程需要访问多个内部数据结构缓存磁盘上的数据&#xff0c;方便快速读取&#xff0c;且修改的数据缓存在此&#xff0c;满了后统一写入磁盘重做日志&#xff08;redo log&#xf…

5.3 需求分析

需求分析 软件需求定义分类练习题 需求工程需求获取练习题 需求分析状态转化图数据流图DFD顶层数据流图0层数据流图1层数据流图 练习题 需求规约需求定义方法 需求验证需求管理版本控制需求跟踪变更控制练习题 考试大概3分 软件需求 定义 软件需求&#xff1a;是指用户对目标…

【QT常用技术讲解】tableWidget右键菜单及多进程编程

前言 本文在QT项目的开发框架的基础上&#xff08;源代码&#xff09;增加tableWidget的右键菜单功能&#xff0c;并使用进程实现ping计算机的功能来讲解&#xff0c;本文不对进程间通信进行讲解。 概述 一个项目在开发过程中&#xff0c;通常面临着引入“第三方应用”&#x…