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语言入门第十章----结构体的更多相关文章

  1. OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)

    OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...

  2. Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型

    Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...

  3. 【C语言】这种求结构体成员大小的方法,你可能需要了解一下~

    在C语言编程中,有时候需要知道某结构体中某成员的大小,比如使用堆内存来存储结构体中的某成员时,需要知道该成员的大小,才好确定所需申请的空间大小.求某结构体中某成员的大小,你会怎么做? 例子: type ...

  4. C语言_了解下结构体指针

    在C语言中几乎可以创建指向任何类型的指针,包括用户自定义的类型.当然也可以指向结构体,先看一个小案例: #include <stdio.h> #include <string.h&g ...

  5. C语言博客作业-结构体

    一.PTA实验作业 6-2 按等级统计学生成绩 1. 本题PTA提交列表 2. 设计思路 定义i,count存放不及格人数 for i=0 to n-1{ 判断 score的值的范围 if 100&g ...

  6. Go语言规格说明书 之 结构体类型(Struct types)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  7. C++学习(二十五)(C语言部分)之 结构体2

    基本概述: int double char; 定义一个学生类型 int Student 姓名 性别 年龄 简单地说 结构体是一个可以包含不同类型的结构,他是一个自定义的类型. struct 结构体标识 ...

  8. 【转】C语言中不同的结构体类型的指针间的强制转换详解

    C语言中不同类型的结构体的指针间可以强制转换,很自由,也很危险.只要理解了其内部机制,你会发现C是非常灵活的. 一. 结构体声明如何内存的分布, 结构体指针声明结构体的首地址, 结构体成员声明该成员在 ...

  9. go语言的排序、结构体排序

    原文:https://studygolang.com/articles/1598 晚上准备动手写点 go 的程序的时候,想起 go 如何排序的问题.排序 sort 是个基本的操作,当然搜索 searc ...

随机推荐

  1. winform学习(6)控件的对齐、比例、定位操作

    窗体控件的常用操作 选中一个控件,按住Ctrl再点选另一个控件(此时编辑的是第二个控件,当使用框选选中多个控件时,编辑的是黑色锚点的控件) 代码中的居顶和居底: 控件标识符.BringToFront( ...

  2. monkey工具使用(未完待续)

    monkey命令详解: 转自:http://blog.csdn.net/jlminghui/article/details/38238443 http://www.cnblogs.com/wfh198 ...

  3. js判断非127开头的IP地址

    js验证回送地址,IP地址不能以127开头 回送地址(127.x.x.x)是本机回送地址(Loopback Address) var ipNotStartWith127 = function(ip) ...

  4. 16进制 32进制 base64之间的区别

    Base64: 包含大写字母(A-Z),小写字母(a-z),数字(0-9)以及+/; Base32: 而Base32中只有大写字母(A-Z)和数字234567: Base16: 而Base16就是16 ...

  5. 类欧几里得模板 p5170

    //类欧几里得的模板题 p5170 //求这三个式子: //第一个跟后两个没关联 //后两个跟其余两个都有关联: #include<cstdio> #include<algorith ...

  6. Codeforces 1315B Homecoming (二分)

    After a long party Petya decided to return home, but he turned out to be at the opposite end of the ...

  7. RedHat7 / CentOS 7 忘记root密码修改

    摘自:https://blog.csdn.net/bubbleyang/article/details/91360856 进入互动式命令环境 开机出现 grub boot loader 开机选项菜单时 ...

  8. C# 之 代码实现延时

    Task.Delay();异步实现 using System;using System.Threading.Tasks; namespace csharpYS{ class Program { sta ...

  9. 隐藏pyqt中调用matplotlib图片中的工具栏

    方法: # pyqtgraph使用matplotlib import pyqtgraph.widgets.MatplotlibWidget as mw a_plt = mw.MatplotlibWid ...

  10. CSS-文本溢出省略号表示

    前提条件是所引用的元素是块级元素,因为使用了WebKit的CSS扩展属性,该方法适用于WebKit浏览器及移动端 单行溢出处理: .text-overflow{ overflow: hidden; t ...