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. 安装Docker:解决container-selinux >= 2.9问题

    1.安装Docker要求Centos内核版本高于3.10:通过uname  -r查看当前系统的内核版本 uname  -r 2.使用root登陆系统,确保yum包保持更新到最新: sudo yum  ...

  2. ubuntu刪除軟件

    1.打开一个终端,输入dpkg --list ,按下Enter键,终端输出以下内容,显示的是你电脑上安装的所有软件2.在终端中找到你需要卸载的软件的名称,列表是按照首字母排序的.3.在终端上输入命令s ...

  3. configure: error: no acceptable C compiler found in $PATH 解决

    在安装keepalived时报错 ./configure --prefix=/usr/local/ccbase/keepalived-2.0.15 && make && ...

  4. ES5 寄生式继承

    3 寄生式继承 组合继承存在调用两次父类构造的问题 原型继承存在不能实例化对象不能传参的问题 组合继承和原型继承都存在子类原有原型属性被覆盖的问题 因此推荐使用寄生式继承 /* 寄生式继承: 1 解决 ...

  5. 题解【洛谷P2279】[HNOI2003]消防局的设立

    题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有\(n\)个基地.起初为了节约材料,人类只修建了\(n-1\)条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成 ...

  6. 每天进步一点点------基础实验_12_有限状态机 :Moore型序列检测器

    /********************************************************************************* * Company : * Eng ...

  7. [HTTP]HTTP/1.1 协议Expect: 100-continue

    在追踪请求时发现了这么一个http头 基础知识背景:1)“Expect: 100-continue”的来龙去脉: HTTP/1.1 协议里设计 100 (Continue) HTTP 状态码的的目的是 ...

  8. CI 框架多表关联查询

    public function getCollectData($limit, $page, $search_user, $search_phone, $orderfield, $ordertype) ...

  9. Java进阶学习(2)之对象交互(下)

    访问属性 封闭的访问属性 private等访问权限控制是对类的,这意味着同一类的不同对象可以互相访问其成员 这是从代码层面去考虑的,意味着不同类文件 开放的访问属性 一个类文件就是一个编译单元 pub ...

  10. [代码记录] C语言链表

    #开始 · 简单的创建链表 #代码 #include<conio.h> #include<stdio.h> #include<stdlib.h> struct St ...