一文攻破结构体-C语言

1 什么是结构体

1.1 结构体类型

结构体(structure)是由不同类型数据组成的组合型的数据结构,可以看做变量的集合。结构体也是一个数据类型,就像和 intchar一样的数据类型,只不过 int 等数据类型是系统已经声明好的,而结构体数据类型是由用户根据需要在程序中指定的,并且可以声明很多种。

1.2 结构体类型的声明

声明一个结构体类型的一般形式:

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

花括号内是该结构体所包括的子项,称为结构体的成员(member),成员可以是一种结构体类型(当前结构体类型或其他结构体类型)的变量。

注意:结构体类型的名字是由一个关键字 struct 和结构体名组合而成的(例如 struct Info)。结构体名是由用户指定的,又称为“结构体标记”(structure tag),以区别于其他结构体类型,即可以设计出许多种结构体类型,而并非只有一种。

struct Info
{int id;char name[10];int age;char sex;
};

1.3 定义结构体类型变量

(1)先声明结构体类型,再定义该类型的变量

struct Info info1, info2;
  • struct Info:结构体类型名
  • info1, info2:结构体变量名

(2)在声明类型的同时定义变量,但是这样定义的变量是全局变量

struct Info
{int id;char name[10];int age;char sex;
} info;

(3)不指定类型名而直接定义结构体类型变量

struct
{成员表列
} 变量名表列;

对于这种方式,将不能再以此结构体类型去定义其他变量。

(4)使用关键字 typedef 定义结构体变量

  • typedef:指定新的类型名来代替已有的类型名
  • 使用格式:typedef {已有的类型名} {新的类型名}
typedef struct Info
{int id;char name[10];int age;char sex;
} info;
  • 根据 typedef 的用法,可以得出以下代码段相当于 {已有的类型名}

    struct Info
    {int id;char name[10];int age;char sex;
    }
    
  • info 相当于 {新的类型名}

接下来,我们便可以使用结构类型 info 来定义结构体变量,如 info info1

1.4 结构体数据类型变量所占内存

在定义好了结构体变量后,系统会为之分配内存单元。不同的编译系统对结构体变量在内存中分配空间有不同的规定。

Visual C++ 中结构体变量所占内存大小就是其各个成员所占内存大小的和,如下这个结构体变量:

struct Info
{int id;char name[10];int age;char sex;
} info;

其成员变量所占的内存大小为 4 + 10 + 4 + 1 = 19,即理论上该结构体变量所占内存大小为 19,实际上其所占内存大小为 20。即当运行 sizeof(info) 时,其输出结果为 20

由于计算机对内存的管理是以“字”为单位的(许多计算机系统以 4 个字节为一个“字”)。如果在一个“字”中只存放了一个字符,虽然只占一个字节,但该“字”中的其他 3 个字节不会接着存放下一个数据,而是从下一个“字”开始存放其他数据,所以用 sizeof 运算符测量变量的长度时,其输出的所占内存大小是 4 的倍数。

2 操作结构体

2.1 结构体变量的初始化

(1)在定义结构体变量时对它的成员初始化

struct Info
{int id;char name[10];int age;char sex;
} info = {201807103142, "tianyvHon", 23, 'M'};

(2)通过引用的方式进行初始化

struct Info info = {.id = 201807103142;.name = "tianyvHon";.age = 23;.sex = 'M'
};

.name 隐含代表结构体变量 info 中的成员 info.name,如果有未被指定初始化的变量,那么数值型成员被系统初始化为 0,字符型成员被系统初始化为 \0,指针型成员被系统初始化为 NULL

2.2 访问结构体成员

结构体成员的访问有点不同于以往的任何变量,它是采用点号运算符·来访问成员的。比如,info.name就是引用 info结构体的 name成员,是一个字符数组,而info.gae则引用info结构体的age成员,是个整型。

(1)在程序中对结构体变量的成员赋值

struct Info
{int id;char name[10];int age;char sex;
} info;info.id = 1;
info.name = "tianyvHon";
info.age = 20;
info.sex = 'M';

(2)在程序中输出结构体变量的成员的值

struct Info
{int id;char name[10];int age;char sex;
} info = {201807103142, "tianyvHon", 23, 'M'};printf("%d\n", info.id);

2.3 操作结构体时需要注意的事项

(1)不能企图通过输出结构体变量名来达到输出结构体变量所有成员的值。

  • printf("%s\n", info);(错误)

(2)同类的结构体变量可以互相赋值

  • info1 = info2;

(3)可以引用结构体变量成员的地址,也可以引用结构体变量的地址

  • scanf("%d", &info.id);
  • printf("%o", &info);

(4)对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)

  • info2.age = info1.age;
  • info1.age++;

3 结构体数组

结构体数组与之前数值型数组的不同之处在于每个数组元素都是一个结构体类型的数据,它们分别包括各个成员项。

定义结构体数组的一般形式:

  • struct 结构体名

    {成员表列} 数组名[数组长度];

    struct Info
    {int id;char name[10];int age;char sex;
    } info[3];
    
  • 先声明结构体类型,然后以此类型定义结构体数组

    结构体类型 数组名[数组长度];

    struct Info
    {int id;char name[10];int age;char sex;
    };
    struct Info info[3];
    

初始化结构体数组:

  • 在定义数组的后面加上 = {初值表列}

    struct Info
    {int id;char name[10];int age;char sex;
    } info[3] = {1, "Hon", 20, 'M', 2, "Wong", 21, 'M', 3, "Tv", 22, 'M'};
    
    struct Info
    {int id;char name[10];int age;char sex;
    };
    struct Info info[3] = {1, "Hon", 20, 'M', 2, "Wong", 21, 'M', 3, "Tv", 22, 'M'};
    

4 结构体指针

结构体指针就是指向结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针。如果把一个结构体变量的起始地址存放在一个指针变量中,那么这个指针变量指向该结构体变量。

(1)指向结构体变量的指针

指针变量的基类型必须与结构体变量的类型相同。定义结构体变量指针的一般格式:struct Info *pi;

struct Info
{int id;char name[10];int age;char sex;
} info;struct Info *pinfo;      // 定义指向 struct Info 类型数据的指针变量 pinfo
pinfo = &info;         // pinfo 指向 info/*************************** 初始化结构体变量 ***************************/
// 第一种方式
info.id = 2022;
info.name = "tianyHon";
info.age = 23;
info.sex = 'M';// 第二种方式
(*pinfo).id = 2022;
(*pinfo).name = "tianyvHon";
(*pinfo).age = 23;
(*pinfo).sex = 'M';// 第三种方式
pinfo->id = 2022;
pinfo->name = "tianyvHon";
pinfo->age = 23;
pinfo->sex = 'M';
  • pinfo = &info;,将结构体变量 info 的起始地址赋给指针变量 pinfo

C 语言中,如果 p 指向一个结构体变量 info,有如下 3 种等价用法:

  • info.成员名
  • (*p).成员名
  • p->成员名

(2)指向结构体数组的指针

可以用指针变量指向结构体数组的元素。

struct Info
{int id;char name[10];int age;char sex;
};struct Info info[3] = {1, "Hon", 20, 'M', 2, "Wong", 21, 'M', 3, "Tv", 22, 'M'};
struct Info *pinfo;for (pinfo = info; pinfo < info + 3; pinfo++)
{printf("%1d %-20s %2d %2c\n", p->id, p->name, p->age, p->sex);
}
  • pinfo = info表示 pinfo 的初值为数组 info 序号为 0 的元素的起始地址。
  • pinfo++表示 pinfo 自加 1,执行 pinfo++ 之后 pinfo 的值等于 info + 1,意味着 pinfo 所增加的值为结构体数组 info 的一个元素所占的字节数(在 Visual C++ 中,理论上等于 19,实际上等于 20)。

注意点:

  • (++pinfo)->id:先使 pinfo 自加 1,然后得到 pinfo 指向的元素中的 id 成员值
  • (pinfo++)->id:先求得 pinfo->id 的值,然后再使 pinfo 自加 1,指向 info[1]
  • 指向结构体数组的指针是用来指向结构体类型的对象(结构体数组中的一个元素的起始地址,如 info[0]),而不应用来指向结构体数组元素中的某一成员,如 pinfo = info[1].name;(错误的使用方法),info[1].nameinfo[1] 元素中的成员 name 的首字符的地址。如果一定要将某一成员的地址赋给 pinfo,可以使用强制类型转换,即 pinfo = (struct Info *)info[0].name;

一文攻破结构体-C语言相关推荐

  1. 一文攻破共用体-C语言

    一文攻破共用体-C语言 1 什么是共用体 由几个不同的变量共享同一段内存的结构,称为"共用体"类型的结构. 例如,把一个短整型变量.一个字符型变量和一个实型变量放在同一个地址开始的 ...

  2. 一文攻破枚举类型-C语言

    一文攻破枚举类型-C语言 1 什么是枚举类型 枚举是一个基本的数据类型,它可以让数据更简洁.所谓"枚举"就是指把可能的值一一列举出来,变量的值只限于列举出来的值的范围内. 声明枚举 ...

  3. c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体

    枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...

  4. 一文了解结构体字节对齐

    结构体字节对齐详解 表述如有不正确的地方,欢迎批评指正. C++/C 常见的基本数据类型: bool short (short int) int long (long int) long long ( ...

  5. c语言 typeof 结构体,Go语言通过反射获取结构体的成员类型

    任意值通过 reflect.TypeOf() 获得反射对象信息后,如果它的类型是结构体,可以通过反射值对象(reflect.Type)的 NumField() 和 Field() 方法获得结构体成员的 ...

  6. c++ new一个结构体_C语言结构体,又一个纸老虎,纯干货讲解(附代码)

    来源:网络,排版整理:晓宇 微信公众号:芯片之家(ID:chiphome-dy)结构体的定义结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构.结构体和其他类型基础数 ...

  7. c语言sqlist结构体,c语言里 sqlist

    满意答案 cielkong 2018.08.12 采纳率:43%    等级:9 已帮助:463人 c语言里 sqlist?//定义顺序表L的结构体 typedef struct { Elemtype ...

  8. java发送c语言结构体_C语言中结构体直接赋值?

    在C语言中结构体变量之间可以进行赋值操作吗? 简单结构体的赋值 先说结论:一般来说,C语言中的结构体变量可以用另一个变量对其进行赋值或初始化.简单结构体(不包含指针成员)直接赋值没有问题. 我们先下面 ...

  9. c语言 结构体_C语言 技能提升 系列文章 (三)结构体

    今天,来跟大家聊一聊C语言中的结构体. 在C语言的各种数据类型中,结构体最特别,因为它是可以被程序员定义的,它的特点是非常的灵活. 定义 struct defined_name{ type_name ...

最新文章

  1. python处理pdf实例_Python实战-从菜鸟到大牛的进阶之路pdf_Python教程
  2. ViewState与Session 的重要区别
  3. 深入BCB理解VCL的消息机制
  4. ITK:优化简单的抛物面函数
  5. MFC中绘制高亮的图标 VC图标填充半透明色
  6. python开发客户端_python用700行代码实现http客户端
  7. html里面怎么ul加高度,div里面嵌套了ul,为什么div的高度小于ul高度
  8. websocket(二)--简单实现网页版群聊
  9. JavaScript中语句与函数的执行辨析
  10. 手把手教你如何逐步安装OpenStack
  11. 剑指offer 答案 python_【剑指offer】【python】面试题2~5
  12. 作为一个程序员,你居然不知道内存(DRAM)的工作原理,这样能跟上时代的进步吗?
  13. java无法双击打开.jar文件/jar包以压缩文件显示
  14. 【Linux】动静态库及gdb的使用
  15. 【房屋销售系统——开题报告 分享(仅供参考呀)】
  16. 7.scala初识 柯里化、隐式参数、隐式转换、视图边界、上界、下界、协变、逆变
  17. PCIe link up bug 分析
  18. Linux 不能命令补全,Linux 命令未自动提示补全
  19. 廖雪峰Git学习笔记(上)
  20. 官网删除「儿童性虐待内容检测方案」,但苹果仍未放弃该计划

热门文章

  1. 电脑屏幕保护怎么取消_怎么监控员工电脑?老板如何知道员工上班在干什么?...
  2. CVPR 2018 LSART:《Learning Spatial-Aware Regressions for Visual Tracking》论文笔记
  3. HDOJ 4699-Editor[栈]
  4. html多重边框,中间空白,CSS实现多重边框
  5. android设置通知在屏幕横幅显示,Android推送通知横幅未显示在某些设备中
  6. 【转】HashMap集合中key只能为引用数据类型,不能为基本类型
  7. django-内网项目上线测试部署步骤
  8. ASP.NET WebAPI 集成 Swagger 启用 OAuth 2.0 配置问题
  9. ie下js不执行的几种可能
  10. 数据结构录 之 单调队列单调栈。