《嵌入式Linux与物联网软件开发——C语言内核深度解析》一1.6 内存管理之结构体

简介: 本节书摘来自华章出版社《嵌入式Linux与物联网软件开发——C语言内核深度解析》一书中的第1章,第1.6节,作者朱有鹏 , 张先凤,更多章节内容可以访问云栖社区“华章计算机”公众号查看。 1.6 内存管理之结构体 1.6.1 数据结构这门学问的意义 数据结构就是研究数据如何组织(在内存中排布)、如何加工的学问。

本节书摘来自异步社区《嵌入式Linux与物联网软件开发——C语言内核深度解析》一书中的第1章,第1.6节,作者朱有鹏 , 张先凤,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.6 内存管理之结构体

1.6.1 数据结构这门学问的意义

数据结构就是研究数据如何组织(在内存中排布)、如何加工的学问。

1.6.2 最简单的数据结构:数组

为什么要有数组?因为程序中有好多个类型相同、意义相关的变量需要管理,这时候如果用单独的变量的话,会使得程序看起来比较杂乱;用数组更便于管理,而且定义简单、使用方便。

1.6.3 数组的优缺点

优点:数组定义简单,而且访问也很方便。

缺点:

数组中所有元素类型必须相同;
数组大小必须定义时给出,而且在大多数情况下,数组的空间大小一旦确定后就不能再改;
数组的空间必须是连续的,这就造成数组在内存中分配空间时必须找到一块连续的内存空间。所以数组不可能定义得太大,因为内存中不可能有那么多大的连续的内存空间,而解决这个问题的方法就是使用链表。我们这里先不讲,后面的章节会讲到。

1.6.4 结构体隆重登场

结构体发明出来就是为了解决数组的第一个缺点—数组中所有元素类型必须相同。有时候,我们在描述事物时,不得不从多个方面描述,如下面的例子。

    我们要管理3个学生的年龄(int类型),怎么办?
    第一种解法:用数组        int ages[3];
    第二种解法:用结构体    
        struct ages
        {
            int age1;
            int age2;
            int age3;
        };
        struct ages age;

在这个示例中,数组要比结构体好。但是不能说数组就一定比结构体好,如果元素类型不同时,就只能用结构体而不能用数组了。

    struct people
    {
        int age;               // 人的年龄
        char name[20];         // 人的姓名
        int height;            // 人的身高
    };

因为people的各个元素类型不完全相同,所以必须用结构体,没办法使用数组。

由上面的例子我们可以看出,结构体属于聚合数据类型,提供一种把各种相关且类型可能不同的数据组合到一起的手段。而数组是同种数据类型的集聚。结构体变量在被定义后,编译器在编译的时候会为所有成员分配空间。向函数传递结构时,实际上是传递结构成员的值,即都是值传递方式(包括用结构体变量作为函数参数以及函数返回值也是结构体变量的情况)。由此也可看出,结构体变量名代表的是整个结构体变量,而不像数组名代表地址。除了简单结构体外,向函数传递整个结构体变量存在很大的缺陷,因为当执行函数调用时,数据压栈需要开销(为什么会调用压栈,下节我们就讲)。这对于多成员结构或成员中有数组的结构,运行性能会严重恶化。解决的方案是,传递结构体变量的指针。向函数传递结构指针时,压栈的仅仅是结构体变量的地址,而使得函数调用非常快。传递结构体变量地址的另一个优点是,函数还可以修改被传递结构体变量的成员值。

1.6.5 题外话:结构体内嵌指针实现面向对象

总体来说,C语言是面向过程的,但是C语言写出的Linux系统是面向对象的。非面向对象的语言,其实也是可以使用面向对象的思想来编写程序的。只是说用面向对象的语言来实现面向对象的编程会更加简单一些,所以我们会觉得用C++、Java等面向对象语言来实现面向对象的开发更容易接受,而使用C语言来实现面向对象的开发相对不容易理解些,这就是为什么大多数人学过C语言却看不懂Linux内核代码。

    structs
    {
        int age;                  // 普通变量
        void (*pFunc)(void);      // 函数指针,指向void func(void)
                                  // 这类的函数
    };

使用这样的结构体就可以实现面向对象,这样包含了函数指针的结构体就类似于面向对象中的class,结构体中的变量类似于class中的成员变量,结构体中的函数指针类似于class中的成员方法。#

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
19天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
7天前
|
缓存 Java Linux
如何解决 Linux 系统中内存使用量耗尽的问题?
如何解决 Linux 系统中内存使用量耗尽的问题?
|
5天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
30 12
|
2天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
7天前
|
缓存 Linux
如何检查 Linux 内存使用量是否耗尽?
何检查 Linux 内存使用量是否耗尽?
|
16天前
|
算法 Linux 开发者
深入探究Linux内核中的内存管理机制
本文旨在对Linux操作系统的内存管理机制进行深入分析,探讨其如何通过高效的内存分配和回收策略来优化系统性能。文章将详细介绍Linux内核中内存管理的关键技术点,包括物理内存与虚拟内存的映射、页面置换算法、以及内存碎片的处理方法等。通过对这些技术点的解析,本文旨在为读者提供一个清晰的Linux内存管理框架,帮助理解其在现代计算环境中的重要性和应用。
|
18天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
52 4
|
19天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
22天前
|
存储 缓存 监控
|
1月前
|
存储 监控 算法
Java中的内存管理与垃圾回收机制解析
本文深入探讨了Java编程语言中的内存管理方式,特别是垃圾回收机制。我们将了解Java的自动内存管理是如何工作的,它如何帮助开发者避免常见的内存泄漏问题。通过分析不同垃圾回收算法(如标记-清除、复制和标记-整理)以及JVM如何选择合适的垃圾回收策略,本文旨在帮助Java开发者更好地理解和优化应用程序的性能。

相关产品

  • 物联网平台