C语言进阶——(嵌入式开发)

引入:内存(RAM),ROM,FLASH的概念

  对于我们嵌入式而言,我们的开发空间经常是有限的,我们需要更深入理解内存,控制自己代码的内存大小是很有必要的。

一:RAM的定义:

RAM :随机存取存储器(random access memory,RAM)又称作“随机存储器”。

是与CPU直接交换数据的内部存储器,也叫主存(内存)。它可以随时读写,而且速度很快,通常作为操作系统或其他正在运行中的程序的临时数据存储媒介。

在整个程序中凡是需要进行修改的量都存放在内存(RAM)中。(也就是变量)

二:FLASH定义:

FLASH :Flash 存储器(FLASH EEPROM)又称闪存,快闪。它是EEPROM的一种。它结合了ROM和RAM的长处。不仅具备电子可擦除可编辑(EEPROM)的性能,还不会断电丢失数据同时可以快速读取数据。它于EEPROM的最大区别是,FLASH按扇区(block)操作,而EEPROM按照字节操作。FLASH的电路结构较简单,同样容量占芯片面积较小,成本自然比EEPROM低,因此适合用于做程序存储器。

在程序中,一般来说进过const修饰的常量存储在flash中。(也就是常量)

三:ROM定义:

ROM (Read Only Memory)程序存储器

ROM全称Read Only Memory,顾名思义,它是一种只能读出事先所存的数据的固态半导体存储器。ROM中所存数据稳定,一旦存储数据就再也无法将之改变或者删除,断电后所存数据也不会消失。其结构简单,因而常用于存储各种固化程序和数据。

一般rom是程序存储的位置,断电不会丢失数据。

                                   

一:变量和常量

一:常量

一:基本定义

    常量:一般比较小(只读不写),一般存储到FLASH里面。

//常量的命名
const int i=0;
const int j=0;
//常量一般都保存到flash里面

二:常量存放

 常量一般存放到flash中,当较少时也可以被直接存入到内存里面进行读取。

注:当一个常量已经被const修饰,那么在程序里面就不能对其进行修改值了,当我们进行修改的时候,程序会报错。

二:变量(变量一定在内存中占有空间

一:基本定义

    变量:可以不断的进行修改(又读又写),一般存储到内存(RAM)里面。

//变量的命名
int i;//volatile int i
int j;//volatile int i
//变量又全局变量和局部变量的区分

二:变量的存放

  变量存放到内存(RAM)中。

当我们定义三个变量会发现

//定义三个变量
volatile int a;
volatile char c;
volatile int arr[4];

他们的地址存放

内存排布:

c 0x2000 000c0x2000 000d0x2000 000e0x2000 000f
a 0x2000 00080x2000 00090x2000 000a0x2000 000b

————————其中一个int类型的变量大小为4个字节,char为一个字节——————————

补充:在读取内存的时候,程序以每次读写四个字节的效率最高,有些硬件甚至只支持一次读四个。所以当一块连续的空间,存放有一个char类型的数据,他后面的三位数据实际上是浪费掉的。

char  a;浪费浪费浪费

我们使用size of函数读取的也是四个字节而不是一个字节。(后面结构体部分还会进行补充)

二:指针

一:基本定义

    指针也就是内存地址,指针变量是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的。

二:指针的大小

   指针变量的大小:取决于物理内存的大小,其中32位单片机来说,他的指针变量大小不管是int类型还是char类型它的大小都是4个字节。即指针变量大小不固定。

(不难得出在64位处理器上,指针变量的大小就是16个字节)

在我们经常使用的stm32单片机里面指针变量的大小都是4个字节。

//在同一处理器下,指针变量的大小是一致的
volatile int *;//整型
volatile short *;//短整型
volatile char *;//字符
volatile struct p//结构体
{
} *;
//在stm32平台下,所有的指针变量都是4个字节大小

三:简单的类比

类比:
char c;   size of(c)      1
int c;      size of(c)     4

int *p;    size of(p)     4
char *p;  size of(p)    4  只要是指针大小一定是4

int *p;    size of(*p)     4
char *p;  size of(*p)     1   

区别:p是指针变量所以他的大小永远都是4
但是*p 是一个char或者int 类型的量,他的大小就不固定了。

区别:p是指针变量所以他的大小永远都是4

但是*p 是一个char或者int 类型的量,他的大小就不固定了。

三:常用的四个关键字

一:volatile关键字(易怒的也就是别来招惹我)

  作用:防止变量被编译器优化,和避免直接走cpu而不调用寄存器

一:防止被程序优化

int main()
{
   int i;
   i=1;//按照正常的C语言编译,这个i=1实际上是没意义的,最终结果肯定是i=2;
   i=2;
}

  在编译器运行的时候,这个i=1是无意义的,这个结果会被直接优化掉,如果我们只看结果的话,那么这个结果倒无所谓,但是如果我们需要i=1;这个中间数据来触发一些中断什么的,那么被优化以后程序就会出问题,这个时候我们加上volatile这个关键字就可以避免这个问题。

int main()
{
    volatile int i;
   i=1;//按照正常的C语言编译,这个i=1实际上是没意义的,最终结果肯定是i=2;
   i=2;
}

二:防止cpu不调用寄存器数据

  也就是说i的数值变化只经过cpu而不经过内存,这样可以加快程序运行的速度。那为什么我们放着运行速度快的不用呢,还要加volatile这个关键字呢。原因就在于这对普通的软件开发可能不会有什么影响,但是对于嵌入式开发来说,不能及时反馈寄存器的值这是致命的

二:static关键字(静止的也就是降低变量的作用域)

   静态变量static(这样这个变量的工作范围就在这个文件里面,不会影响其他的文件)也就是限制作用域。(原因是如果你重复定义一个变量会报错重复定义

int ;整个项目都可以调用

static int 只有当前文件夹可以调用。

三:const关键字

    本意就是这个变量可以直接放置到flash上面,可以节省一下内存(用来解决内存不够)

当你定义了const 以后这个量就变成了常量,这样程序里面你要是修改他就会报错。

const int i=10;
int main()
{

   //i=99;此时就会报错,因为他是常量

}

四:extern关键字

extern 可调用外部变量。,在模块化编程里面让其他模块程序来调用这个变量。

在头文件里面extern 这个变量,另外一个文件#include这个头文件即可。

四:结构体

   结构化的好处:程序更加紧凑,具有更强的逻辑.(使用基本的类型创造一种新的类型)。

实例:打印一个学生全部信息。定义一个结构体后面就可以,也就是避免重复造车。

使用基本的类型创造一种新的类型。

struct person

{

int name;

int age;

};

struct cmpany{

char *name;

char worker[100];


}

  只有变量才占内存,我们创造出来新的类型,类型不占内存,只有用这些类型定义的变量才会占空间。指针大小永远都是4

注意:按照我们正常的想法来说,应该结构体里面有一个char和一个int,char一个字节,int四个字节正常水平来看这个结构体一大小应该是五个字节二应该是六个字节,但是编译器跑下来他的大小都是八个字节。那么原因是什么呢?

struct person1

{

char name;

int age;

};
struct person1

{

char name;
char a;

int age;

};

这就是我们上文说的有些硬件只支持四位四位的读取,这样的读取效率最高。

在读取内存的时候,程序以每次读写四个字节的效率最高,有些硬件甚至只支持一次读四个。所以当一块连续的空间,存放有一个char类型的数据,他后面的三位数据实际上是浪费掉的。但是如果同时给他几个char类型的数据他又会自动补上去。就是很奇妙。

char  a;浪费浪费浪费

也就是说,当1-4个char他占用的都是四个字节大小,5-8个都是八个字节大小。

后续:下一节更新各个变量的赋值(见主页另外一篇文章)。

  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面只是目标目录 ├─第1章-Shiro权限实战课程介绍 │ 1-1Shiro权限实战课程介绍.mp4 │ 1-2权限控制和初学JavaWeb处理访问权限控制.mp4 │ ├─第2章-大话权限框架核心知识ACL和RBAC │ 2-1权限框架设计之ACL和RBAC讲解.mp4 │ 2-2主流权限框架介绍和技术选型讲解.mp4 │ ├─第3章-ApacheShiro基础概念知识和架构讲解 │ 3-1Shiro核心知识之架构图交互和四大模块讲解.mp4 │ 3-2用户访问Shrio权限控制运行流程和常见概念讲解.mp4 │ ├─第4章-Springboot2.x整合ApacheShiro快速上手实战 │ 4-1SpringBoot2.x整合Shiro.mp4 │ 4-2快速上手之Shiro认证和授权流程实操上集.mp4 │ 4-3Shiro认证和授权流程和常用API梳理下集.mp4 │ ├─第5章-详细讲解ApacheShirorealm实战 │ 5-1Shiro安全数据来源之Realm讲解.mp4 │ 5-2快速上手之Shiro内置IniRealm实操.mp4 │ 5-3快速上手之Shiro内置JdbcRealm实操.mp4 │ 5-4ApacheShiro自定义Readl实战.mp4 │ 5-5深入Shiro源码解读认证授权流程.mp4 │ ├─第6章-Shiro权限认证Web案例知识点讲解 │ 6-1Shiro内置的Filter过滤器讲解.mp4 │ 6-2Shiro的Filter配置路径讲解.mp4 │ 6-3Shiro数据安全之数据加解密.mp4 │ 6-4Shiro权限控制注解和编程方讲解.mp4 │ 6-5Shiro缓存模块讲解.mp4 │ 6-6ShiroSession模块讲解.mp4 │ ├─第7章-ApacheShiro整合SpringBoot2.x综合案例实战 │ 7-10使用ShiroLogout和加密处理.mp4 │ 7-1Shiro整合SpringBoot2.x案例实战介绍.mp4 │ 7-2基于RBAC权限控制实战之Mysql数据库设计.mp4 │ 7-3SpringBoot2.x项目框架和依赖搭建.mp4 │ 7-4案例实战之权限相关服务接口开发.mp4 │ 7-5案例实战之用户角色权限多对多关联查询SQL.mp4 │ 7-6案例实战自定义CustomRealm实战.mp4 │ 7-7项目实战之ShiroFilterFactoryBean配置实战.mp4 │ 7-8前后端分离自定义SessionManager验证.mp4 │ 7-9API权限拦截验证实战.mp4 │ ├─第8章-权限控制综合案例实战 │ 8-1实战之自定义ShiroFilter过滤器上集.mp4 │ 8-2实战之自定义ShiroFilter过滤器下集.mp4 │ 8-3性能提升之Redis整合CacheManager.mp4 │ 8-4性能提升之Redis整合SessionManager.mp4 │ 8-5ShiroConfig常用bean类配置.mp4 │ ├─第9章-大话分布应用的鉴权方 │ 9-1单体应用到分布应用下的鉴权方介绍.mp4 │ 9-2Shiro整合SpringBoot下自定义SessionId.mp4 │ ├─第10章-Shiro课程总结 │ 10-1Apacheshiro从入门到高级实战课程总结.mp4 │ 10-2高级工程师到架构师-解决问题思路+学习方法.mp4 │ └─课件资料.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值