C语言入门第十章----结构体
C语言结构体从本质上讲是一种自定义的数据类型,只不过这种数据类型比较复杂,是由int、char 、float等基本类型组成的,你可以认为结构体是一种聚合类型。
在实际开发中,我们可以将一组类型不同的、但是用来描述同一件事物的变量放到结构体中。例如:在小学生有姓名、年龄、身高、成绩等属性,学了结构体后,我们就不需要再定义多个变量了,把他们都放到结构体中即可。
=====什么是结构体===
结构体是一种集合,它里面包含了多个变量或数组,他们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员。
结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据。
像int 、float 等是由C语言本身提供的数据类型,不能再进行分拆,我们称之为基本数据类型,而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称之为复杂数据类型或构造数据类型。
理论上讲结构体的各个成员在内存中是连续存储的,和数组非常类似,但是在编译器的具体实现中,各个成员之间可能会存在缝隙。
===成员的获取和赋值
结构体和数组类似,也是一组数据的集合,整体使用没有太大的意义。数组使用下表[] 获取单个元素,结构体使用点号.获取单个成员。获取结构体成员的一般格式为
===需要注意的是:结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间,结构体变量才包含了实实在在的数据,需要内存空间来存储。
====结构体数组====
所谓结构体数组,是指数组中的每个元素都是一个结构体。在实际应用中,C语言结构体数组常被用来表示一个拥有相同数据结构的群体。
====结构体指针(指向结构体的指针)===
当一个指针变量指向结构体时,我们就称它为结构体指针。C语言结构体指针的定义形式一般为: struct 结构体名 *变量名;
注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是挣个集合本身,要想取得结构体变量的地址,必须在前面加&。
====获取结构体成员===
通过结构体指针可以获取结构体成员,一般形式为:(*pointer).memberName
或者 pointer -> memberName
第一种写法中,.的优先级高于*,(*pointer)两边的括号不能少。
===结构体指针作为函数参数===
结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针。如果结构体成员较多,尤其是成员为数组时,传送的时间和空间开销会很大,影响程序的运行效率。所以最好的办法就是使用结构体指针,这时由实参传向形参的只是一个地址,非常快速。
====C语言枚举类型(enum 关键字)====
在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用。
#define 命令虽然能解决定义的问题,但也带来了不小的副作用,导致宏名过多,代码松散,看起来总不舒服。C语言提供了一种枚举(Enum) 类型,能够列出所有可能的取值,并给他们取一个名字。
枚举类型的定义形式为:
需要注意的两点是:
1)枚举列表中的Mon、Tues 这些标识符的作用范围是全局的,严格来说是main()函数内部,不能再定义与他们名字相同的变量。
2) Mon、Tues 这些名字都被替换成了对应的数字,这意味着,Mon、Tues等都不是变量,它们不占用数据区的内存,而是直接被编译到命令里面,放到代码区,所以不能用&取得他们的地址。
====C语言共用体(union)关键字
通过前面的讲解,我们知道结构体是一种构造类型或复杂类型,它可以包含多个类型不同的成员。在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(union),它的定义格式为:union 共用体名{ 成员列表 };
结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响,而共用体的所有成员占用同一段内存,修改一个会员会影响其余所有会员。
结构体占用的内存大于等于所有成员占用的内存的总和,成员之间可能会存在缝隙,共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
共用体也是一种自定义类型,可以通过它来创建变量。
====C语言位域(位段)====
有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。基于这种考虑,C语言提供了一种叫做位域的数据结构。
C语言标准规定,位域的宽度不能超过它所依附的数据类型的长度。通俗的讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,:后面的数字不能超过这个长度。
我们可以这样认为,位域技术就是成员变量所占用的内存中选出一部分位宽来存储数据。
====C语言位运算详解====
所谓位运算,就是对一个BIT位进行操作。在《数据在内存中的存储》一节中讲到,比特是一个电子元器件,8个比特构成一个字节,它已经是粒度最小的可操作单元了。
C语言提供了六种位运算符:
按位与,按位或,按位异或,取反,左移,右移
===& 是按照内存中的二进制位进行运算的,不是数据的二进制形式,其他位运算符也一样。
C语言入门第十章----结构体的更多相关文章
- OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)
OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...
- Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型
Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...
- 【C语言】这种求结构体成员大小的方法,你可能需要了解一下~
在C语言编程中,有时候需要知道某结构体中某成员的大小,比如使用堆内存来存储结构体中的某成员时,需要知道该成员的大小,才好确定所需申请的空间大小.求某结构体中某成员的大小,你会怎么做? 例子: type ...
- C语言_了解下结构体指针
在C语言中几乎可以创建指向任何类型的指针,包括用户自定义的类型.当然也可以指向结构体,先看一个小案例: #include <stdio.h> #include <string.h&g ...
- C语言博客作业-结构体
一.PTA实验作业 6-2 按等级统计学生成绩 1. 本题PTA提交列表 2. 设计思路 定义i,count存放不及格人数 for i=0 to n-1{ 判断 score的值的范围 if 100&g ...
- Go语言规格说明书 之 结构体类型(Struct types)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...
- C++学习(二十五)(C语言部分)之 结构体2
基本概述: int double char; 定义一个学生类型 int Student 姓名 性别 年龄 简单地说 结构体是一个可以包含不同类型的结构,他是一个自定义的类型. struct 结构体标识 ...
- 【转】C语言中不同的结构体类型的指针间的强制转换详解
C语言中不同类型的结构体的指针间可以强制转换,很自由,也很危险.只要理解了其内部机制,你会发现C是非常灵活的. 一. 结构体声明如何内存的分布, 结构体指针声明结构体的首地址, 结构体成员声明该成员在 ...
- go语言的排序、结构体排序
原文:https://studygolang.com/articles/1598 晚上准备动手写点 go 的程序的时候,想起 go 如何排序的问题.排序 sort 是个基本的操作,当然搜索 searc ...
随机推荐
- new和delete的深层次剖析(C++)
c++ 是公司开发最常用的语言之一, 那new和delete 这两个函数是所有开发者即爱又恨的函数.由new 和delete引发的bug , coredump , 让多少程序员加了多少班. 1. 遇到 ...
- Docker on startup: “No activity detected on VM, aborting”
windows下安装的docker,切换到linux,一直处于重启中,最后报No activity detected on VM, aborting错误 上网百度一下这个错误,基本上没人遇到过,最后在 ...
- C++ split分割字符串函数
将字符串绑定到输入流istringstream,然后使用getline的第三个参数,自定义使用什么符号进行分割就可以了. #include <iostream> #include < ...
- codeforces A. Zoning Restrictions Again
A. Zoning Restrictions Again ou are planning to build housing on a street. There are n spots availab ...
- python专题知识追寻者对OS的理解
一 前言 OS(operating system)直接对操作系统进行操作的接口,功能真是非常强大:允许知识追寻者简要概括一下整体模块 如果要对文件进行读写可以使用os.open()方法 如果要对文件路 ...
- 爬虫(十一):selenium爬虫
1. selenium基础 selenium部分可以去看我写的selenium基础部分,由于链接太多了这里就不发出来了. 代理ip: 有时候频繁爬取一些网页.服务器发现你是爬虫后会封掉你的ip地址.这 ...
- 后台怎么区分接口要写在哪个service类中呢(根据service服务区分)
1,明确页面要实现什么功能,则页面对应的controller要写对应的controller方法 2,这个功能最终要由谁实现完成,在对应的service中药实现这个功能 3,这个接口的实现就写在最终完成 ...
- 微信小程序使用wxParse实现接入富文本编辑
简介 微信小程序中比如活动说明,简介这样的图文介绍说明页面,后台通常配置成富文本编辑框,由后台直接输入内容,然后在小程序界面展现. 但是富文本编辑提取到内容是html格式的,写法与小程序的wxml并不 ...
- 设备驱动基础学习--platform driver简单实现
platform是一条虚拟的总线.设备用platform_device表示,驱动用platform_driver进行注册,Linux platform driver机制和传统的device drive ...
- UVA 11464 偶数矩阵(递推 | 进制)
题目链接:https://vjudge.net/problem/UVA-11464 一道比较好的题目. 思路如下: 如果我们枚举每一个数字“变”还是“不变”,那么需要枚举$2^{255}$种情况,很显 ...