嵌入式 C学习(一)

C语言常用关键字及运算符

在这里插入图片描述

1. 关键字

在这里插入图片描述

定义:编译器 预先定义了一定意义的 字符串

1.1 数据类型

在这里插入图片描述
作用:限制内存的大小,如Int一般对应4个字节,char一般对应1个字节等。
C语言操作的对象:资源/内存,在开发板上内存类型的资源指,LCD缓存,LED灯等。

1.1.1 sizeof

  • sizeof的返回值用%lu接收,无符号长整型
  • sizeof:编译器给我们查看内存空间容量的一个工具

1.1.2 char

  • 硬件芯片操作的最小单位:bit
  • 软件操作的最小单位:byte
  • 一个char有8bit,最大值为255,硬件中使用注意不要越界
    错误示例char a = 300;

char:描述的是硬件能够操作的在软件上体现的最小单位
应用场景:硬件处理的最小单位

1.1.3 int

编译器最优的处理大小:系统一个周期,所能接收的最大处理单位,即int的大小。

  • 32位系统下的,int为4个字节
  • 64位系统下的,int为8个字节
  • 在宏定义中如:define F_CPU 12000000U表示该常数用无符号整形方式存储
  • define F_CPU 12000000L表示该常数用长整型方式存储
1 对于整数来说,缺省后缀的都视为int,比如55,88,1234567
2 对于浮点数来说,缺省后缀的都视为double比如:2.344,88.9534,123456.78901

所以,如果缺少后缀L又超过int范围的,就会造成数据溢出,如定义int a=66530L即可不会报错。

1.1.4 unsigned、signed

区别:内存空间的最高字节是符号位还是数据位

1.2 自定义数据类型

在这里插入图片描述
使用自定义数据类型的原因:C编译器默认定义的内存分配不符合实际资源的形式
自定义:基本元素的集合
比如以下情况
操作看门狗时,我们需要配置这四个寄存器它是在一起的,但是没有一个基本数据类型能一起包含这么大的空间,所以会定义一个结构体来把这4个int数据类型包含进去。

在这里插入图片描述

1.3 逻辑结构

在这里插入图片描述
while:一般在需要判断某个条件时使用
for:一般在需要体现循环多少次的时候使用
goto:一般在编写内核时同一个函数中才能使用。

1.4 类型修饰符

在这里插入图片描述
作用:对资源属性中位置的限定,比如栈、堆等。

1.4.1 auto

在这里插入图片描述

1.4.2 register

作用:限制变量定义在寄存器上的修饰符,可以用来定义一些快速访问的变量
缺陷:如果定义register int a,编辑器只是尽量的安排CPU的寄存器去存放这个a,如果寄存器不足时,a还是放在存储器中
注意:此时&这个符号对于register是非法的

1.4.3 volatile

作用:告知编译器编译方法的关键字,不优化编译

2. 运算符

在这里插入图片描述

2.1 算数运算符

在这里插入图片描述

2.1.1 关于乘法

有的CPU是无法处理乘法的,或者能处理效率一般不高,有的也会当做加法处理。

  • int a = b*10
    CPU可能多个周期,甚至要利用软件的模拟方法实现乘法
  • int a = b+10
    CPU一个周期可以处理

2.1.2 关于取模的几个作用

  1. 取一个范围的数:
    在这里插入图片描述
  2. 得到M进制的一个个位数
  3. 循环数据结构的下标

2.2 逻辑运算

在这里插入图片描述

  • A || BB || A 不相等
    C语言对或语句的处理是为了提高效率,如果A正确,就不会执行B,因为已经有一个正确,结果就是正确的。同理右边B正确就不会再执行A
  • A && B
    此处同上含义,如果A是错误的,程序返回就是0,不会再执行B的内容

2.3 位运算

在这里插入图片描述

2.3.1 “<<” 相关问题

  • 左移一位,代表原数乘以2,因此m << n,结果为m*2^n
  • 所以对于硬件里的编程,乘法运算如果是2的倍数时计算机是比较喜欢的,如int a = b*32,计算机会翻译成b << 5
  • 对于负数的左移是同样成立的:
    在这里插入图片描述

2.3.2 “>>” 相关问题

右移与符号变量有关,如下变量的定义,CPU对右移的处理情况时不同的:

int a;		a>>n
unsigned int a;        a>>n

比如在处理如下循环的时候,此时虽然定义的是有符号的数,但是它是正数,所以最高位是0,不断右移的过程能使a最后为0,从而退出循环。

int a = 10;
while(a){
	a = a >> 1;
}

而对于如下循环,a定义为有符号的负数,它在右移过程中,最高位补的是1,所以它右移永远不能成为0,从而无法退出循环:

int a = -10;
while(a){
	a = a >> 1;
}

2.3.3 “&” 相关问题

在这里插入图片描述
作用:起到屏蔽某些位,起初某些位的作用
如下情况,&起到的作用是屏蔽低8bit,取出高8bit:

int a = 0x1234;
a & 0xff00;  //屏蔽低8bit,取出高8bit

2.3.3 “|” 相关问题

作用:按位设置为高电平的方法

在这里插入图片描述
“|” 在硬件中的使用:
1. 如设置一个资源的bit5为高电平,其他位不变

int a;
a = (a | (0x1 << 5))

2. 清除寄存器的第n位

int a = a & ~(0x1 << n);

2.3.4 “^” 相关问题

异或的基本结果是:相同为0,不同为1

在这里插入图片描述
异或在硬件中的使用,不引入第三个变量交换两个值:

int a = 20;
int b = 30;

a = a ^ b;
b = a ^ b;
a = a ^ b;

简单理解为:b = a ^ b ^ b = a ^ 1,
a = a ^ b ^ a = 1 ^ b = b

2.4 赋值运算和内存访问符号

在这里插入图片描述

发布了22 篇原创文章 · 获赞 5 · 访问量 472

猜你喜欢

转载自blog.csdn.net/RedValkyrie/article/details/105248428