C的实用笔记38——结构体的引入和定义

article/2025/10/15 4:25:38

1.为什么要用结构体?

0、原因:实际开发中,我们需要将不同类型的数据组合成一个整体,这就是结构体。结构体是自创的类型。

1、查找一名学生信息的两种方案:在EXCEL表格和数据库中经常有这种情况,比方说一个学生的信息可能包括:学号、姓名、性别、年龄、成绩、地址等。现在我们有两种方案来查找任意一名学生的信息,如图:

                                      

  1.  方案一:以行为一个整体(结构体),不用看其他行就能读取一个学生的所有信息。
  2. 方案二:以列为一个整体(数组),需要先按列查找(比方说先找学生学号),然后记住行号,需要看所有列才能读取一个学生的所有信息。

2.结构体变量的四要素

与普通变量的四要素完全相同。

1、结构体变量的类型:也就是结构体,它是我们自创的类型,简称构造类型。它的声明通常不放在函数中,书写的方式就像全局变量,因为它要尽可能让程序中的所有位置都能使用这个类型声明。结构体又有三部分:

  1. struct关键字:表示构造的是结构体。
  2. 结构体类型名:编程习惯是用大写开头,小写开头虽然不出错,就是看起来太low了。
  3. 结构体成员列表:成员列表也称为域表,通常我们称结构体成员列表(域表)中的每个成员为成员变量(域),成员变量之间用分号隔开。你可以定义许多成员变量,但并不是每一个选项在具体使用中会被派上用场,不要给成员变量赋值,虽然不出错,但是看起来太low了。成员列表中的成员变量可以是我们之前学过的任何类型的变量,比如整型、字符型、字符数组、各类指针、浮点型。甚至可以是结构体类型的成员变量。当然,成员列表中的变量可以是同一类型的,这时结构体看起来就像数组一样。
    struct Student				//struct是关键字,Student是自己取的结构体类型名
    {							//花括号中的是结构体成员列表int num;char name[32];char sex;int age;double score;char addr[50];
    };							//从此以后,我们构造了一个结构体,它是 struct Student 类型。

1、结构体的知识点:

  1. 结构体声明时,末尾加分号;
  2. 结构体这个构造类型,决定了结构体变量占用空间的大小,系统会在程序运行或编译阶段给你静态分配好内存。这个类型占用多少内存当然需要用sizeof来测一下,留在第2小节(结构体内存分配)中讲。
  3. 与int a; 中 类型名是int一个道理,这里struct Student 在概念上就相当于 int。

2、结构体变量的名字:是结构体变量定义时候的名字,与 int a; 中变量名是a一个道理,留在本节第3部分讲

3、结构体变量的地址:显然这就是指向结构体变量的指针,留在第4小节(结构体指针)中讲

4、结构体变量的值:这里指的是结构体变量中成员变量的值,留在本节第4、5、6部分讲

3.结构体变量的定义

1、标准的定义方式:结构体声明和结构体变量定义分开写。

  1. 由于结构体是自定义的构造类型,所以需要先声明结构体,然后拿它来定义结构体变量。
    #include <stdio.h>
    struct Student
    {int num;char name[32];char sex;int age;double score;char addr[50];
    };
    int main(int argc, char const *argv[])
    {struct Student stu1;		//stu1就是struct Student类型的结构体变量
    }

2、见怪不怪的定义方式:

  1. 声明结构体,同时定义结构体变量:后面照样可以定义其他结构体变量,但这个方法尽量少用
    #include <stdio.h>
    struct Student
    {int num;char name[32];char sex;int age;double score;char addr[50];
    } stu2, stu3;					//尽量少用
    int main(int argc, char const *argv[])
    {struct Student stu1;	
    }

  2. 声明结构体时不写类型名,必须同时定义结构体变量:少用,因为后面无法再拿它来定义其他结构体变量
    #include <stdio.h>
    struct					//不写结构体类型名
    {int num;char name[32];char sex;int age;double score;char addr[50];
    } stu2, stu3;			//同时在这里定义结构体变量,不要使用这种方法

4.结构体变量中有许多成员变量,如何引用?

数组引用数组元素的方式有:数组下标法、数组名偏移后取星花。但是这些明显都不适用于结构体。

1、用点运算符来访问结构体变量中的成员变量(域):

  1. 单级引用(成员列表中没有构造类型变量):结构体变量名.成员变量名
    #include <stdio.h>
    #include <string.h>
    struct Student
    {int num;char name[32];char sex;int age;double score;char addr[50];
    };
    int main(int argc, char const *argv[])
    {struct Student stu1; stu1.num = 64031; 					//点运算符访问结构体变量中的成员变量strcpy(stu1.name, "Li Hua");stu1.sex = 'M'; stu1.age = 24;stu1.score = 94;strcpy(stu1.addr, "杭州");printf("学号:%d,名字:%s,性别:%c,年龄:%d,分数:%lf,地址:%s\n", \stu1.num, stu1.name, stu1.sex, stu1.age, stu1.score, stu1.addr);return 0;
    }

  2. 二级引用(成员列表中有结构体变量):结构体变量名.成员变量名.成员变量名
    #include <stdio.h>
    #include <string.h>
    struct Day
    {int year;int month;int day;
    };
    struct Student
    {int num;char name[32];char sex;int age;double score;char addr[50];struct Day birth;					//结构体的成员列表中还有结构体变量
    };
    int main(int argc, char const *argv[])
    {struct Student stu1; stu1.num = 64031; strcpy(stu1.name, "Li Hua");stu1.sex = 'M'; stu1.age = 24;stu1.score = 94;strcpy(stu1.addr, "杭州");stu1.birth.year = 1999;				//点运算符二级引用stu1.birth.month = 12;stu1.birth.day = 1;printf("学号:%d,名字:%s,性别:%c,年龄:%d,分数:%lf,地址:%s,生日:%d年%d月%d日\n", \stu1.num, stu1.name, stu1.sex, stu1.age, stu1.score, stu1.addr, \stu1.birth.year, stu1.birth.month, stu1.birth.day);return 0;
    }

5.结构体变量的初始化

        结构体变量的初始化和数组的初始化方法几乎一模一样,也分为全部初始化和部分初始化,都是用花括号来实现。

1、全部初始化:定义结构体变量时用花括号赋值,花括号内的数据与结构体成员列表一一对应,数据用逗号分隔。

#include <stdio.h>
//#include <string.h>			由于是初始化,就不需要用strcpy修改字符串
struct Student
{int num;char name[32];char sex;int age;double score;char addr[50];
};
int main(int argc, char const *argv[])
{struct Student stu2 = {64066,"Li Fang",'M',24,90,"大连"};            //结构体变量的全部初始化printf("学号:%d,名字:%s,性别:%c,年龄:%d,分数:%lf,地址:%s", \stu2.num, stu2.name, stu2.sex, stu2.age, stu2.score, stu2.addr);return 0;
}

2、部分初始化:只能按照顺序给结构体变量的前几个成员变量初始化,不允许用空格跳过中间某个变量

#include <stdio.h>
//#include <string.h>			由于是初始化,就不需要用strcpy修改字符串
struct Student
{int num;char name[32];char sex;int age;double score;char addr[50];
};
int main(int argc, char const *argv[])
{struct Student stu2 = {64066,"Li Fang",'M',24,};               		//结构体变量的部分初始化printf("学号:%d,名字:%s,性别:%c,年龄:%d,分数:%lf,地址:%s", \stu2.num, stu2.name, stu2.sex, stu2.age, stu2.score, stu2.addr);return 0;
}

6.4和5中哪一种方法确定结构体变量的值比较好?

1、需要分情况:看起来好像定义结构体变量时就初始化比较简单,但是要分情况,因为有的时候一开始没法确定结构体变量中成员变量的值,就是需要通过点运算符来进行访问。

7.结构体变量相互赋值的条件

1、知识点:总的来说就是结构体相同,也就是结构体变量的类型相同

  1. 结构体类型名一致
  2. 结构体成员列表一致

8.习题

习题1:输入两个学生的信息,找出成绩好的学生,并显示他的信息。

  1. 思路:
    构造一个与学生信息有关的结构体类型1: struct Student{......};
    1. 用构造体类型1,定义两个结构体变量stu1和stu2,初始化或者通过点运算符确认结构体变量的值
    2. 定义一个与stu1和stu2相同类型的结构体变量max,它表示成绩好的同学,暂时认为stu1成绩好: struct Student max = stu1;
    3. 判断,stu1.score是否小于stu2.score,3.1 如果是,那么,认为stu2是成绩好的同学: max = stu2;
    4. 打印max同学的信息

  2. 代码:
    #include <stdio.h>
    #include <string.h>
    struct Student
    {int num;char name[32];char sex;int age;double score;char addr[50];
    };
    int main(int argc, char const *argv[])
    {struct Student stu1; struct Student stu2 = {64066,"Li Fang",'M',24,90,"大连"};struct Student max;stu1.num = 64031; strcpy(stu1.name, "Li Hua");stu1.sex = 'M'; stu1.age = 24;printf("请输入%s的成绩:\n", stu1.name);scanf("%lf", &stu1.score);strcpy(stu1.addr, "杭州");max = stu1;if(stu1.score < stu2.score){max = stu2;}printf("成绩比较好的是:\n");printf("学号:%d,名字:%s,年龄:%d,分数:%lf,地址:%s\n", \max.num, max.name, max.age, max.score, max.addr);return 0;
    }


http://chatgpt.dhexx.cn/article/Yp1KPdxd.shtml

相关文章

7.IDA-创建结构体

结构体分类 结构体的一个显著特点在于&#xff0c;结构体中的数据字段是通过名称访问&#xff0c;而不是像数组那样通过索引访问。不好的是&#xff0c;字段名称被编译器转换成了数字偏移量。结果&#xff0c;在反汇编代码清单中&#xff0c;访问结构体字段的方式看起来与使用…

结构体的初步认识以及其内存的计算

目录 前言 结构体的定义 结构体的自引用 结构体的初始化 结构体内存的计算 前言 我们知道&#xff0c;通过不同的数据类型我们可以表达不同意义的数据&#xff0c;如长度宽度面积只需要定义一个 int 类型的数据就可以符合大部分的需求。但是&#xff0c;有些东西自存在就是一…

IDA创建结构体方法

1. ida是最好用的逆向分析工具 2.问题 如果你在使用IDA分析时遇到大量的结构体指针偏移形式的变量&#xff0c;肯定想根据自己的分析重命名结构体各项。 3.定义结构体 这是需要先找到结构体初始化的地方 这里记录了每一项的偏移量&#xff0c;记录了结构体总大小Ox110uLL。 …

手把手教你写单片机的结构体

手把手教你写单片机的结构体 摘要&#xff1a;听说还有好多学单片机的小伙伴不会用结构体&#xff1f;指针和结构体是学单片机必须要掌握的&#xff0c;如果你C语言掌握的不牢&#xff0c;单片机根本学不到精髓&#xff0c;只能完成一些低级的项目。看得懂结构体并且能够灵活运…

STM32基于Flash对结构体读写暨再认识结构体内存分配

目录 前言 认识结构体内存分布 模拟结构体搬运 实现FLASH的结构体读写 前言 记录本篇主要是记录我进行stm32学习中利用stm32的flash&#xff08;闪存&#xff09;读写结构体的总结。 认识结构体内存分布 结构体&#xff0c;主要要来存放我们的自定义类型的数据&#xff0c;结…

单片机的结构体

手把手教你写单片机的结构体 FROM8号线攻城狮 公众号 电子信息工程硕士在读&#xff0c;分享单片机、嵌入式linux、物联网等知识&#xff0c;致力于打造最硬核的嵌入式技术公众号。 半碗鸡汤&#xff0c;半碗杂粮。 摘要&#xff1a;听说还有好多学单片机的小伙伴不会用结构…

windows下mysql初始密码设置

转载自&#xff1a;http://blog.csdn.net/ofreelander/article/details/50802780 1.my-default.ini 改名my.ini 在解压的目录下面复制my-default.ini一份改名字为 my.ini。 2.打开 Windows 环境变量设置, 新建变量名 MYSQL_HOME , 变量值为 MySQL 安装目录路径, 在 环境变量 …

MYSQL修改初始化密码的方法

解决方法之一&#xff1a; “ ALTER USER rootlocalhost identified by 123456 ; ” 最近安装了mysql&#xff0c;在使用“ set password for rootlocalhostpassword(123456);”时会遇到 “ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that…

Centos下安装mysql查看初始密码并修改密码

题记&#xff1a;当我们在centos成功安装了mysql后&#xff0c;需要查看初始密码&#xff0c;大概率也需要自己修改密码。 一&#xff0c;查看mysql历时密码 cat var/log/mysqld.log二&#xff0c;进入到mysql mysql -u root -p按回车&#xff0c;然后再password:输入刚才所…

MySQL设置初始密码—注意版本mysql-8.0.30

MySQL设置初始密码—注意版本mysql-8.0.30 第一步&#xff1a;使用管理员模式下的命令行&#xff0c;进入mysql的所在文件下的bin目录; 第二步&#xff1a;输入命令mysql -u root -p; 第三步&#xff1a;这里第一次不用输入密码; 第四步&#xff1a; ALTER USER rootlocalhost…

安装mysql的初始密码在哪里

mysql初始密码是多少 介绍怎么找到mysql安装的root的初始密码 mysql初始密码是多少 介绍怎么找到mysql安装的root的初始密码 怎么给mysql设置用户名和密码 登录数据库 “命令提示字符”窗口录入&#xff0c; 录入cd C:\mysql\bin 并按下回车键&#xff0c;将目录切换为 cd C:\m…

关于MySQL初始化密码忘记的问题

本文章可以解决MySQL密码忘记的问题&#xff01;&#xff01;&#xff01; 1、到mysql安装的bin目录下运行PowerShell 2、在命令行输入 mysql -u root -p 登录 mysql&#xff0c;可以随意输入一个密码&#xff0c;返回”ERROR 1045 (28000): Access denied for user rootlocal…

mysql安装,以及初始化密码

1.首先下载 mysql安装包&#xff0c; 我这里下载的mysql 5.7(免安装版) https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-winx64.zip 然后解压到你自己的目录中&#xff0c;我这里为 D 盘下&#xff1a; 此处&#xff0c;下下来的压缩包里面&#xff0c; data 目…

mysql初始没有密码怎么设置

由于本人是win7的忠实用户&#xff0c;最近被win10所吸引索性换了系统&#xff0c;还是改不了恋旧的习惯。所以用的mysql还是5.6。进入正题 在装完mysql并且配置完环境变量之后发现密码为空 1.首先进入到你安装的目录下&#xff0c;这里我的是E盘 2.之后输入mysql -u root -p …

1、数据库-MySql

什么是数据库 数据库(DataBase,简称DB) 概念&#xff1a;长期存放在计算机内&#xff0c;有组织&#xff0c;可共享的大量数据的集合&#xff0c;是一个数据"仓库" 作用&#xff1a;保存&#xff0c;并能安全管理数据(如:增删改查等)&#xff0c;减少冗余… 数据…

C++中字符串大小写字母转换

最近在学习 STL&#xff0c;string 也是 STL 中的一种容器&#xff0c;遇到一个字符串中字母大小写转换的例子&#xff0c;这里就顺便总结一下在C中常用的字符串大小写转换方法&#xff0c;有需要的可以参考。代码如下&#xff1a; 1、char[]类型&#xff0c;调用库函数 // …

大小写字母转换(java大小写字母转换)

苹果4SQQ密码大小写字母怎么转换不&#xff1f;苹果4SQQ密码大小写字母 每次要输密码,当时在电脑上设置的密码,可以改变大小写,但是到了手机上,我不知道怎么换大小写,那位朋友告诉下 苹果手机输入法怎么改字母的大小写 (很高兴为您解答,有帮助请给好评,谢谢! ) 大小写转换-键盘…

英文字母大小写转换

从键盘输入一个大写英文字母&#xff0c;将其转换味小写字母后&#xff0c;再显示到屏幕上&#xff08;显示字符后要输出一个换行&#xff09; 输入格式要求&#xff1a;提示信息&#xff1a;"Press a key and then press Enter:" 程序运行实例如下&#xff1a; P…

Java 字符串中的大小写字母转换

Java 实现字符串中字母大小写转换函数 实现思路&#xff1a;将字符串中的每个字符取出&#xff0c;判断该字符是不是大写字母&#xff0c;如果是的话则该字符32&#xff08;ASCII码&#xff09;并进行强制转换&#xff0c;转换为char&#xff0c;然后在通过字符串的合并操作进…

大写字母转换成小写字母

大写字母转换成小写字母 大写字母转换成小写字母1.示例&#xff1a;2. 解题思路3. 代码展示及分析3.1 ASCII码操作字符串转换大小写3.2 位运算 4. 运行结果 大写字母转换成小写字母 题目&#xff1a; 实现函数 ToLowerCase()&#xff0c;该函数接收一个字符串参数 str&#xf…