C 语言编程 — 构造数据类型 — 结构体(struct)

article/2025/10/15 3:36:19

目录

文章目录

  • 目录
  • 结构体
  • 声明一个结构体类型
  • 定义一个结构体类型的变量
  • 定义一个结构体类型的指针变量
  • 结构体的成员
  • 结构体的内存分布

结构体

结构体(Structure)是一种由不同类型的数据成员组成的数据类型。通过定义结构体,我们可以将多个不同的数据类型组合成一个单独的数据类型。

使用结构体,需要先声明类型,然后再定义类型的变量。

声明一个结构体类型

使用 struct 关键字来定义一个结构体类型:

struct tag { membermembermember...
} variable-list ;
  • tag:结构体类型名。
  • member:结构体所包含的成员,使用标准的变量定义语句,比如:int i
  • variable-list(可选):结构体变量,可以一次性指定一个或多个结构体类型的变量。

定义一个结构体类型的变量

  1. 直接定义:在声明结构体类型的同时定义结构体变量,如果后面不再需要定义其他新的结构体变量,那么我们可以在定义时不给出结构体类型名称。这种方式书写简单,但是因为没有结构体类型名称,所以后面就没法用该结构体类型定义新的变量。
struct {int a;char b;double c;
} s1;
  1. 间接定义:先声明定义结构体类型,再另外的定义结构体变量。
// 声明
struct SIMPLE
{int a;char b;double c;
};// 定义
struct SIMPLE t1, t2[20], *t3;

注意,在上述的两个示例中,第一个和第二声明被编译器当作两个完全不同的类型,即使他们的成员列表是一样的。

  1. 别名定义:我们可以同时使用关键字 struct 和 typedef 来声明一个结构体类型,并未其赋予一个 “别名”,后续使用该 “别名” 定义结构体变量时,就可以不重复的书写 struct 关键字了。
typedef struct
{int a;char b;double c; 
} Simple2;  // NOTE:因为前面有 typedef,此时的 Simple2 是一个别名,而不是变量。// 现在可以用 Simple2 作为类型,定义一个新的结构体变量
Simple2 u1, u2[20], *u3;

NOTE:在实际的编程中,我们经常会使用 *_s 后缀来命名一个结构体类型,而是用 *_t 后缀来命名一个结构体类型的别名(也称之为自定义一个新的数据类型)。e.g.

typedef struct student_s {char	*name;int		num;int		age;char	group;float	score;
} student_tstudent_t stu1;
sizeof(student_t)
  1. 初始化结构体类型的变量(整体赋值):仅限于定义结构体变量的时候。
#include <stdio.h>/*** 声明 Books 结构体类型;* 定义 book 结构体变量;* 初始化 book 结构体变量;*/
struct Books {char    title[50];char    author[50];char    subject[100];int     id;
} book = {"is book", "fanguiju", "C", 123};int main() {printf("Book's title: %s\nauthor: %s\nsubject: %s\nid: %d\n", book.title, book.author, book.subject, book.id);return 0;
}
  1. 初始化结构体类型的变量(分别赋值):在使用过程中只能对成员逐一赋值,并使用 ‘.’(结构体成员访问运算符)对结构体的成员进行访问:
#include <stdio.h>
#include <string.h>/* 声明 Books 结构体类型 */
struct Books {char    title[50];char    author[50];char    subject[100];int     id;
};int main() {/* 定义 book 结构体变量 */struct Books book1;/* 初始化 book 结构体变量 */strcpy(book1.title, "C Programming");  // book1.title 是字符串类型,需要使用 strcpy() 接口,而不能直接赋值。strcpy(book1.author, "Nuha Ali");strcpy(book1.subject, "C Programming Tutorial");book1.id = 123;/* 访问结构体成员 */printf("Book's title: %s\nauthor: %s\nsubject: %s\nid: %d\n", book1.title, book1.author, book1.subject, book1.id);return 0;
}

定义一个结构体类型的指针变量

  1. 定义结构体 Books 的指针变量:
struct Books* struct_pointer;
  1. 将结构体变量的内存地址赋值到指针变量:
struct_pointer = &book1;
  1. 指针变量使用 -> 运算符来访问结构体成员。
struct_pointer->title;

因为结构体指针变量 struct_pointer 本质是一个内存地址,跟结构体变量不同,不可以直接使用成员访问运算符 .,而是使用 -> 运算符。

#include <stdio.h>
#include <string.h>struct Books {char    title[50];char    author[50];char    subject[100];int     id;
};void printBook(struct Books* book) {printf("Book's title: %s\nauthor: %s\nsubject: %s\nid: %d\n", book->title, book->author, book->subject, book->id);
}int main() {struct Books book1;strcpy(book1.title, "C Programming");strcpy(book1.author, "Nuha Ali");strcpy(book1.subject, "C Programming Tutorial");book1.id = 123;printBook(&book1);return 0;
}

结构体的成员

结构体的成员可以是大多数数据类型,包括可以是其他结构体,也可以是指向本身结构体类型的指针,这种指针的应用通常是为了实现一些更高级的数据结构,如:链表、树等。

// 包含其他结构体。
struct COMPLEX {char string[100];struct SIMPLE a;
};// 包含指向本身结构体类型的指针。
struct NODE {char string[100];struct NODE *next_node;
};

如果两个结构体互相包含,则需要对其中一个结构体进行声明,同时还要注意语句的顺序,否则会出现编译错误:

// 声明 B
struct B;// 声明 A
struct A{struct B *partner;  // 包含 B//other members;
};struct B {struct A *partner;  // 包含 A//other members;
};

结构体的内存分布

理论上讲,结构体的各个成员在内存空间中是连续存储的,和数组非常类似,比如结构体变量 stu1 的内存分布如下图所示,共占用 4 + 4 + 4 + 1 + 4 = 17 个字节。

在这里插入图片描述

但是在编译器的具体实现中,各个成员之间可能会存在缝隙,对于 stu1 的成员变量 group 和 score 之间就可能存在 3 个字节的空白填充。这样算来,stu1 其实占用了 17 + 3 = 20 个字节。

在这里插入图片描述


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

相关文章

C语言结构体和其他构造数据类型详解

结构体和其他构造数据类型 结构体 “结构”是一种构造类型&#xff0c;它是由若干“成员”组成的。 每一个成员可以是一个基本数据类型或者又是一个构造类型。 结构既然是一种“构造”而成的数据类型&#xff0c;那么说明和使用之前必须先定义它&#xff0c;也就是构造它。 结…

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

1.为什么要用结构体&#xff1f; 0、原因&#xff1a;实际开发中&#xff0c;我们需要将不同类型的数据组合成一个整体&#xff0c;这就是结构体。结构体是自创的类型。 1、查找一名学生信息的两种方案&#xff1a;在EXCEL表格和数据库中经常有这种情况&#xff0c;比方说一个…

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…