C/C++|物联网开发入门+项目实战|指针|嵌入式C语言高级|C语言内存空间的使用-数组-学习笔记(10)

news2025/1/16 6:51:17

参考:麦子学院-嵌入式C语言高级-内存空间

2-3 : C语言内存空间的使用-数组

内存分配的一种形式
在这里插入图片描述

数组的定义及初始化

定义一个空间:
1、大小
2、读取方式
数组名[]:升级为连续空间的名称, [m]的作用域只在申请的时候起作用
每个多大?数组名前定义数据类型,按int 还是char进行切割?
数组名是地址常量符号,地址常量标签;一定不要放在等号左边
char buff[100];
buf = “hello world!” //该语法错误,不能赋值给常量。
int a[100]; //空间申请的一种方式
数据会有越界问题
a[10] a是门牌号,是常量,a的属性已定。而指针是内存,可变。

数组空间的初始化

空间的赋值
按照标签逐一处理
int a[10]: [0-9]
a[0]= xx;
a[1]= yy;
程序员这样赋值,工作缗比较大,能不能让编译器进行一些自动处理,帮助程序员写如上的程序

空间的第一次赋值

->空间定义时,就告知编译器的初始化情况,空间的第一次赋值,初始化操作
int a[10] = 空间; //调用标准库或者逐一拷贝,和普通变量初始化有本质不同
c语言本身,CPu内部本身一般不支持大空间和大空间的拷贝
int a[10] = {10,20,30} //3个B,3个字节。
=====>拷贝的过程,CPU做了,a[0] = 10; a[1] = 20; a[2] = 0
和逐一赋值是一样的,{}代表空间的限制块

数组空间的初始化和变量的初始化李质不同,尤其在嵌入式的裸机开爱书,空间的初始化往往需要库函数的铺助。

char

char buf[10] = {‘a’,‘b’,‘c’} //a是8b,占1个B,共占3个字节
buf当成普通内存来看,没有问题
buf当成一个字符串来看,最后加上一个’\0’或者0
字符串的重要属性是,结尾一定有一个’\0’(内存中0的表示形式)

char buf[10] = {“abc”}; //编译器看到"“自动加0
char buf[10] = “abc”; //执行后,系统中有2个abc,一个是"abc”(常量),一个是buf的变量-字符串"abc",=号完成常量向变量去拷贝。buf可变,可操作。不能改变abc
本质区别于:char p = “abc”; //指向"abc"的指针,buf可变,但p不变
buf[2] = ‘e’ //可行, p[2] = ‘e’ //不行,出现段错误,因为p指向常量,不能修改
示例:

#include <stdio.h>

int main()
{
    printf("the x  is %x\n","abc");  //显示的是内存地址
    return 0;

}
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the x  is 409020

char buf[]=“abc”; //4个字节,因为还有0
char buf[10] = “abc”;
buf = “hello world!” //buf是常量标签,不能修改,故编译错误,标签不能变
第二次内存初始化,赋值?
逐一处理 buf[0] = ‘h’ ,…buf[n+1] = 0;

strcpy(工程禁用), strncpy(推荐)

一块空间,当成字符空间,提供了一套字符拷贝函数
在这里插入图片描述
字符拷贝函数的原则:
内存空间和内存空间的逐―赋值的功能的一个封装体,一旦空间中出现了0这个特殊体,则函数拷贝结束。
strcpy()
标准函数代码中会嵌入一些汇编语言,开发过程中效率进一步提高。
嵌入式开发工程师:根据CPU的体系结构不同以及CPU的能力,这段程序是可以改变的,能够更加优化。
char buf[10] = “abc”;
strcpy(buf,“hello world”); //完成复制,并自动加入"\0"结束标志
当"hello world*********"等待复制的字符串会一直copy,典型的内存泄漏,工程不能使用,只能用strncpy,控制复制长度,限制拷贝数量。

非字符串空间

字符空间
ASCII码编码来解码的空间,–》给人看
%s abc ‘a’ ‘b’ ‘c’
'\0’作为结束标志
非字符空间
数据采集 采集0x00-0xff 8bit
开辟一个存储这些数据的盒子,
定义时用
char buf[10]; ----》string
有歧义,怎么能保证完全是数据?
采集过来的只有位的概念,和符号无关,
必须定义为unsigned char buf[10]; ----》一定是最小data单位

unsigned char *p = sensor_ base;
strcpy(buf,p);//此方法这里不适用,看到\0才停止,存在非常不合理的风险,
所有,非字符串空间只管逐一拷贝,结束在哪里?只能是定义个数。
拷贝三要素:
 1、src
 2、dest
 3、个数(sizeof)

memcpy

int buf[10];
int sensor_buf[100];

memcpy(buf,sensor_buf,10sizeof(int)); //非单字节空间是,需sizeof
在这里插入图片描述

unsigned char buf1[10];
unsigned char sensor_buf[100];// 00 00 00 23 45 78
// strncpy(buf,sensor_buf,10) //拷贝不成功,因为数据00开头
memcpy(buf,sensor_buf,10*sizeof(unsigned char)); //10个字节(数据空间),对应10个内存单位,这里正好一一对应,书写规范要求带sizeof
先找对象(有无符号),再确定操作。

指针与数组

指针数组

建立与二维指针的关系,哪种好理解,记哪个
*a[100] //*代表a的属性
char *a[100];
sizeof(a) = 100 * 4; //一个地址4个字节
char **a;

数组名的保存

定义一个指针,指向int a[10]的首地址
定义一个指针,指向int b[5][6]的首地址
int *p1 = a; //这种写法是合理的,p指针定义读内存的方法是int,4个字节一组,读取,与原数据定义一致,2个内存读取的方式一样,就不会报警告或者错误。
int **p2 = b; //错误方法

示例代码

#include <stdio.h>

int main()
{
    int a[10];
    int b[5][6];

    int *p1 = a;

    int **p2 = b; //提示警告,因为二维数组与二维指针没有任何关系

}
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// 2.c: In function 'main':
// 2.c:10:16: warning: initialization from incompatible pointer type [enabled by default]

二维数组不是按基本的数据类型读内容,因为每行中的列不同,上例中,每移动一行的指针,内存跨度为4*6=24B,是一块一块的内存。
正确写法为:int (*p)[6]; //*p是整体,[6]每行二维数组的列数。
故示例中应改为:
int (*p2)[6] = b; //在内存中指针移动或指代的方式根据之前的int和之后的[]修饰
int b[2][3][4]
int (*p)[3][4];

2-4 : C语言内存空间的使用-结构体

字节对齐

出于CPU效率的考虑,牺牲一点空间换取时间的效率。
这样的解决方案又称为字节对齐,32bit对齐。

示例

#include <stdio.h>

struct  abc
{
    char a;
    int  b;
};

int main()
{
    struct  abc buf;

    printf("the buf is %lu\n",sizeof(buf)); //8个字节

};
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the buf is 8

打包顺序的影响

最终结构体的大小一定是4的倍数
结构体成员变量顺序不一致,也会影响他们的大小
可以由低2位对齐,满足效率要求。

示例

#include <stdio.h>

struct  abc
{
    char a;
    short e;
    int  b;
};

struct  my
{
    char a;
    int  b;
    short e;

};

int main()
{
    struct  abc buf1;
    struct  my  buf2;
    printf("the buf1 is %lu\n",sizeof(buf1)); //8个字节
    printf("the buf2 is %lu\n",sizeof(buf2)); //8个字节

};
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the buf1 is 8
// the buf2 is 12

内存分布图

内存的属性

1、大小
2、在哪里
int a; //默认方式进行最终的定位,放置的区域叫section(分段)的概念

编译—》汇编―–》链接
*.o build

#include <stdio.h>

int a;   //主函数体外,可看成是全局变量,存放位置离mian的空间较近
int main()
{
   //int a;  //临时的,当函数完成后,会销毁,存放位置也相对较高

   a = 0x10;

   printf("the a is %p\n",&a);

   printf("the main is %p\n",main);

   return 0;
};
// 局部变量:
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the a is    000000000064FE2C
// the main is 0000000000401500
// 全局变量:
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the a is    000000000040D3C8
// the main is 0000000000401500
内核空间    应用程序不许访问,看也不行

----------------3G
栈空间(局部变量)

运行时的堆空间(malloc申请的空间)

全局数据空间    (初始化的空间,未初始化) data bss
只读数据段  "hello world"                TEXT段
代码段      code(只读)                 TEXT段

0x0;

#include <stdio.h>

int b = 100;   //主函数体外,可看成是全局变量,存放位置离mian的空间较近
int fun()
{
    static int a = 100;

    return a++;
}
int main()
{
    static int a;
    unsigned char *p;
    a = 0x10;

    printf("the a is %p\n",&a);

    printf("the main is %p\n",main);

    p = (unsigned char *)main;

    printf("the p[0] is %x\n",p[0]);
    p[0] = 0x12; //操作这样属性的区域,会报错:segmentation fault
    printf("+++++ the p[0] is %x\n",p[0]);
    return 0;

};
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the a is 000000000040C030
// the main is 0000000000401519
// the p[0] is 55
// 无显示

示例代码:

#include <stdio.h>

int b = 100;   //主函数体外,可看成是全局变量,存放位置离mian的空间较近
int fun()
{
    static int a = 100;

    return a++;
}
int main()
{
    static int a;
    unsigned char *p;
    char *p1 = "helao world";
    a = 0x10;

    printf("the p1 is %s\n",p1);
    printf("the string address is %p\n","helao world");
    p1[3] = 'l';
    printf("the p1 is %s\n",p1);

    // printf("the a is %p\n",&a);
    // printf("the main is %p\n",main);

    // p = (unsigned char *)main;

    // printf("the p[0] is %x\n",p[0]);
    // p[0] = 0x12; //操作这样属性的区域,会报错:segmentation fault
    // printf("+++++ the p[0] is %x\n",p[0]);
    return 0;

};
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the p1 is helao world
// the string address is 0000000000409020
// 无显示
示例3
```C
#include <stdio.h>

// int b = 100;   //主函数体外,可看成是全局变量,存放位置离mian的空间较近
int fun()
{
    static int a = 100;

    return a++;
};
int main()
{
    static int a;
    unsigned char *p;
    //char *p1 = "helao world";
    const int b = 0x12345678; //b只读变量
    a = 0x10;
    char *p1 = &b;

    printf("the p1 is %x\n",p1);
    printf("the string address is %p\n","helao world");
    p1[3] = '0';
    printf("the p1 is %x\n",p1);
    return 0;
};

// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// 2.c: In function 'main':
// 2.c:17:16: warning: initialization from incompatible pointer type [enabled by default]
// the p1 is 64fe24
// the string address is 000000000040902E
// the p1 is 64fe24

// E:\temp>size 2.exe
//    text    data     bss     dec     hex filename
//   30936    2864    5136   38936    9818 2.exe

示例4:同样的字符串增加字符前后堆空间分布

#include <stdio.h>

// int b = 100;   //主函数体外,可看成是全局变量,存放位置离mian的空间较近
int fun()
{
    static int a = 100;

    return a++;
};
int main()
{
    static int a;
    unsigned char *p;
    char *p1 = "helao world";
    const int b = 0x12345678; //b只读变量
    a = 0x10;

    printf("the p1 is %s\n",p1);
    printf("12345678the string address is %p\n","helao world");  //对独一无二的字符串加上1234
    p1[3] = 'l';
    printf("the p1 is %s\n",p1);
    return 0;
};
//    text(代码)    data(数据)     bss(未初始化信息)     dec     hex filename
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the p1 is helao world
// the string address is 0000000000409020

// E:\temp>size 2.exe
//    text    data     bss     dec     hex filename
//   30952    2864    5136   38952    9828 2.exe

// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the p1 is helao world
// 1234the string address is 0000000000409020

// E:\temp>size 2.exe
//    text    data     bss     dec     hex filename
//   30952    2864    5136   38952    9828 2.exe

// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the p1 is helao world
// 12345678the string address is 0000000000409020

// E:\temp>size 2.exe
//    text    data     bss     dec     hex filename
//   30984    2864    5136   38984    9848 2.exe

在这里插入图片描述

示例分析

# E:\temp>size 2.exe
#    text    data     bss     dec     hex filename
#   30984    2864    5136   38984    9848 2.exe

# E:\temp>strings 2.exe  //显示双引号内的字符
# ffffff.
# ATUWVSH
# T$ E
# t5H9
# [^_]A\
# fff.
# D$ tv
# D$(H
# T$ H
# L$ H
# L$(H
# fffff.
# ATUWVSH
#  [^_]A\
# ......

static int a; 放在bss空间中,而默认值是auto。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/435574.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

太给力了,这款java表单设计器可提高办公协作效率!

随着办公自动化的快速发展&#xff0c;java表单设计器的应用价值和突出优势也逐渐成为企业提高办公效率的好帮手。传统的表单操作起来费时费力&#xff0c;效率不高&#xff0c;逐渐满足不了日益繁多的业务需求了&#xff0c;在广大用户的呼声和市场发展下&#xff0c;简洁、灵…

ESP32学习五-启动流程

一、简介 在ESP32的开发中&#xff0c;通常我们会从app_main函数中开始我们的代码开发。但是为什么是app_main呢&#xff1f;app_main又是从哪里被调用的&#xff1f;app_main之前又做了什么操作呢&#xff1f;今天我们就来详细分析一下。 官方参考文档&#xff1a;应用程序的启…

柔性作业车间生产调度中MK算例文本各行数字表示的含义以及算例的数据

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 MK算例其他MK02~MK10柔性作业车间数据 MK算例 Brandimarte给出了10组柔性作业车间的实例分别是MK01~Mk10&#xff0c;下方即为MK01的实例数据 10 6 26 2 1…

Kubernetes Operator开发

Kubernetes Operator开发 1.kubebuilder 创建项目 2.Crontroller开发与部署 开发环境准备 kubebuilder 介绍 CRD的开发与部署 Crontroller开发与部署 Operator功能设计 借助operator完成 和企业内部注册中心打通 这里以Traefiketcd的模式为例进行演示说明 在这里etcd provi…

现在学习云计算,还有出路吗?

现在学习云计算&#xff0c;还有出路吗&#xff1f; 当然有出路&#xff0c;现在正是学习云计算的好时机。只要你专业技术过关&#xff0c;有一定的项目经验&#xff0c;有的企业甚至接受应届生&#xff1b;其次是具备一定的职业素养&#xff0c;学历在大专及以上&#xff0c;年…

潇洒郎: git配置、拉取、提交代码

git配置拉取代码 git 配置全局变量 git config --global user.name "xuxiaosa" git config --global user.email "xuxiaosamigu.cn" 配置ssh key 1、打开git-bash 输入ssh-keygen 一直回车&#xff0c;会提示文件保存的地址 id_rsa,id_rsa.pub两个文…

谷粒商城二十二订单服务支付

我们支付暂时只开发支付宝&#xff0c; 按照正规的流程&#xff0c;我们的系统要接入支付宝&#xff0c;肯定是需要大量的审核过程&#xff0c;而且需要我们的项目上线。 那现在我们就想测试该怎么办&#xff1f;支付宝为我们提供了沙箱环境&#xff0c;我们可以在应用未上线之…

易观千帆 | 2023年3月银行APP月活跃用户规模盘点

易观&#xff1a;2023年3月手机银行服务应用活跃人数53289.05万&#xff0c;环比增长2.15%&#xff0c;同比增长8.87%。 2023年3月信用卡服务应用活跃人数10800.71万&#xff0c;环比增长1.87%&#xff0c;同比增长18.64%。 2023年3月城商行手机银行服务应用活跃人数3827.43万&…

【项目篇1】一个在线OJ系统

目录 一、前言&#xff1a;项目背景 功能1&#xff1a;能够管理题目 功能2&#xff1a;可以展示题目列表 功能3&#xff1a;题目详情页 功能4&#xff1a;可以令用户提交代码&#xff0c;并验证提交的情况 注意事项&#xff1a; 功能5&#xff1a;反馈运行的结果 二、项…

不同的场景上线时钟同步系统需要注意些什么

时钟同步系统一般都是用在学校或者医院的环境当中&#xff0c;一般时钟同步系统由硬件和软件相组成。对于局域网部署&#xff0c;通常使用NTP协议。对于广域网部署&#xff0c;通常需要考虑网络延迟和安全性等因素。此外&#xff0c;时钟同步系统在不同的使用场景当中的需求也不…

Vite详解

目录 前言一、Vite简介1. Vite组成2.为什么选 Vite? 二、Vite的优缺点1.vite优点2.vite缺点 三、使用Vite创建Vue3项目1. 创建 vite 的项目2.项目的结构 前言 构建工具 Vite&#xff0c;目前只有vue3才可以使用Vite&#xff0c;如果本文对你有所帮助请三连支持博主。 一、V…

雷达人体存在感应器成品,静止存在感控方案,雷达触发联动技术应用

随着社会经济的不断发展和科技水平的不断提高&#xff0c;智能感应类产品越来越多的应用到我们生产与生活之中。 小到家里边的感应灯、单位里的自动门&#xff0c;大到安防报警等诸多领域&#xff0c;都能体验到它给我们带来的便利性与安全性。 雷达人体感应器可以精准探测人体…

fs文件系统模块

一、什么是 fs 文件系统模块 fs 模块是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性&#xff0c;用来满足用户对文件的操作需求。 例如&#xff1a; fs.readFile() 方法&#xff0c;用来读取指定文件中的内容 fs.writeFile() 方法&#xff0c;用来…

计算机网络模型、网络传输、封装分用的详细讲解

文章目录 计算机网络前言1. 初始网络2. 网络通信相关知识2.1 TCP/IP五层网络模型2.2 OSI七层模型 3. 网络传输3.1 封装3.2 分用3.3 数据传输的中间过程 计算机网络 前言 在互联网诞生之前&#xff0c;人们通过发电报等方式进行通信&#xff0c;这种方式是非常不稳定的&#x…

读写锁的原理与实现

文章目录 什么是读写锁生产消费模型 VS 读写模型 读写锁的pthread库接口读者&&写者模式 模拟实现读写锁思路1——用两个锁来实现&#xff08;读者优先&#xff09;模拟实现 思路2——两个条件变量一个锁&#xff08;写者优先&#xff09;模拟实现 可以看看之前写的文章…

d2l Nadaraya-Waston核回归

注意力机制里面的非参数注意力汇聚 目录 1.目标任务 2.数据生成 2.1构造原始数值 3.非参数注意力汇聚 4.对注意力机制的理解 1.目标任务 使用y_train(有噪声),拟合y_truth(没噪声)。给你所有的y_train&#xff0c;构造注意力权重生成拟合曲线。 2.数据生成 n_train 50…

五款高效易用的项目管理软件,提升团队工作效率

项目管理软件是为了协助团队或公司便捷和高效地完成工作任务和管理项目而专门设计的软件工具。有了它&#xff0c;团队成员可以共享资源&#xff0c;跟踪项目进度和成果&#xff0c;识别问题并及时解决。与传统的手工方式相比&#xff0c;项目管理软件可以提高工作效率和生产力…

Centos7上安装vscode和ssh

Centos7上安装vscode和ssh 一.前言二.Centos7上安装vscode三&#xff0c;Centos7上配ssh3.1 查看是否安装ssh环境3.2 配置ssh配置文件3.3 启动ssh服务 一.前言 在用linux环境编译项目的时候&#xff0c;比较习惯用ubuntu环境&#xff0c;而对centos环境的一些命令工具使用的比…

外链是什么意思,什么是外链

外链就是指在别的网站导入自己网站的链接。导入链接对于网站优化来说是非常重要的一个过程。导入链接的质量间接影响了我们的网站在搜索引擎中的权重。外链是互联网的血液&#xff0c;是链接的一种。没有链接的话&#xff0c;信息就是孤立的&#xff0c;结果就是我们什么都看不…

计算机网络笔记(方老师408课程)(持续更新)

文章目录 前言互联网概述互联网发展的三个阶段互联网标准化机构 互联网的组成边缘部分的通信方式核心部分的交换方式 我国计算机网络的发展计算机网络的类别计算机网络的性能速率、带宽、吞吐量时延时延带宽积往返时间RTT&#xff08;Round-Trip Time&#xff09;利用率非性能特…