《嵌入式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
相关文章
|
1月前
|
安全 Linux Shell
Linux上执行内存中的脚本和程序
【9月更文挑战第3天】在 Linux 系统中,可以通过多种方式执行内存中的脚本和程序:一是使用 `eval` 命令直接执行内存中的脚本内容;二是利用管道将脚本内容传递给 `bash` 解释器执行;三是将编译好的程序复制到 `/dev/shm` 并执行。这些方法虽便捷,但也需谨慎操作以避免安全风险。
|
6天前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
19 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
21天前
|
存储 监控 算法
Java中的内存管理与垃圾回收机制解析
本文深入探讨了Java编程语言中的内存管理策略和垃圾回收机制。首先介绍了Java内存模型的基本概念,包括堆、栈以及方法区的划分和各自的功能。进一步详细阐述了垃圾回收的基本原理、常见算法(如标记-清除、复制、标记-整理等),以及如何通过JVM参数调优垃圾回收器的性能。此外,还讨论了Java 9引入的接口变化对垃圾回收的影响,以及如何通过Shenandoah等现代垃圾回收器提升应用性能。最后,提供了一些编写高效Java代码的实践建议,帮助开发者更好地理解和管理Java应用的内存使用。
|
5天前
|
存储 缓存 NoSQL
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
13 0
|
1月前
|
缓存 Linux C语言
C语言 多进程编程(六)共享内存
本文介绍了Linux系统下的多进程通信机制——共享内存的使用方法。首先详细讲解了如何通过`shmget()`函数创建共享内存,并提供了示例代码。接着介绍了如何利用`shmctl()`函数删除共享内存。随后,文章解释了共享内存映射的概念及其实现方法,包括使用`shmat()`函数进行映射以及使用`shmdt()`函数解除映射,并给出了相应的示例代码。最后,展示了如何在共享内存中读写数据的具体操作流程。
|
1月前
|
Shell Linux API
C语言在linux环境下执行终端命令
本文介绍了在Linux环境下使用C语言执行终端命令的方法。首先,文章描述了`system()`函数,其可以直接执行shell命令并返回结果。接着介绍了更强大的`popen()`函数,它允许程序与命令行命令交互,并详细说明了如何使用此函数及其配套的`pclose()`函数。此外,还讲解了`fork()`和`exec`系列函数,前者创建新进程,后者替换当前进程执行文件。最后,对比了`system()`与`exec`系列函数的区别,并针对不同场景推荐了合适的函数选择。
|
2月前
|
Linux 调度
深入理解Linux虚拟内存管理(七)(下)
深入理解Linux虚拟内存管理(七)
44 4
|
2月前
|
存储 Linux 索引
深入理解Linux虚拟内存管理(九)(中)
深入理解Linux虚拟内存管理(九)
23 2
|
2月前
|
Linux 索引
深入理解Linux虚拟内存管理(九)(上)
深入理解Linux虚拟内存管理(九)
34 2
|
2月前
|
Linux
深入理解Linux虚拟内存管理(七)(中)
深入理解Linux虚拟内存管理(七)
30 2

相关产品

  • 物联网平台
  • 下一篇
    无影云桌面