文章目录
- 2-2: C语言常用关键字及运算符操作
- 关键字
参考: 麦子学院-嵌入式C语言高级
2-2: C语言常用关键字及运算符操作
[重点]
掌握C语言的常用关键宇及其应用场景,使用技巧
关键字
编译器:预先定义了一定意义的字符串,32个。
- sizeof
关键字,编译器给我们查看内存空间容量的一个,定义时已分配的空间。
#include <stdio.h>
int main()
{
int a;
printf("the a is %d",sizeof a);
// printf("the a is %d",sizeof(a));
return 0;
}
返回值:the a is 4
字符占用4字节内存空间(32位)。
2. return 返回值
C语言如何描述这些资源的属性那?
资源用性【大小】:数据类型,由编译器决定
限制内存(土地)的大小,关键字
3. 数据类型
操作对象:资源/内存{内存类型的资源,LCD缓存、LED灯}
char
硬件芯片操作的最小单位:
bit 1 0 高低位
软件操作的最小单位:8bit ==1B byte字节
4M 4Mbit Kbit/s KB/S
char a; bit a;
应用场景:
硬件处理的最小单位
char buf[xx]; int buf[x];
ASCII码表 8bit
盒子 可代表状态
1 2
2 4
3 8
4 16
5 32
6 64
7 128
8 256
9 512
10 1024
8bit == 256
溢出问题:char a =300; a++ 301
int
大小;一般不固定,根据编译器来决定。TC2.O就是2B
编译器最优的处理大小:
系统一个周期,所能接受的最大处理单位,int
32bit 4B int 正好能把一个周期的高速路走满
16bit 2B int 16位单片机
int a; char a;
int处理的数据量比char大,而且能够达到系统的最优处理大小,计数器,循环等;
char更多的是面向硬件开发。
==========================
整型常量(数字构成的字符串,int大小)
char a = 300; 300l 300L
2B 65535
int a = 66535; //超过2B,必须用4B
进制表示
10
十进制 八进制 十六进制 二进制
人与人 2进制衍生
101010
3bit 8进制
111 0x7
1000 0x8 //3位是7的循环
int a = 010; //0开头,8进制 代表十进制:8
12 001 010
4bit 16进制 int a=0x10; //0x开头,16进制 代表十进制:16
long,short
特殊长度的限制符,short表示32进制中的16进制,严格要求长度时才使用。
unsigned,signed
无符号 : 数据
有符号 : 数字
内存空间的最高字节是符号位还是数据
unsigned int a;
char a;
float.double
大小
float 4B
double 8B
内存存在形式
0x10 16
0001 10000 16
16
0001 0000 16
1.0
0001 0000 (X)
浮点型常量
1.0 1.1 double
1.0f float
void
void a;//申请变量名,声明标志
- 自定义数据类型
C编译器默认定义的内存分配不符合实际资源的形式
自定义=基本元素的集合
struct
元素之间的和,累加
struct myabc{
unsigned int a;
unsigned int b;
unsigned int c;
unsigned int d;
};
int i;
struct myabc mybuf;
顺序有要求
union
共用起始地址,技巧性代码
union myabc{
char a;
int b;
};
union myabc abc;
enum
enum
enumerate-―列举
被命名的整型常数的集合
#define MON 0
#define TUE 1
#define WED 2
相当于:enum abc{MOD=0,TUE,WED}
enum枚举名称{常量列表};常量集合,
enum week{
Monday = 0 ,Tuesday =1,Wednesday = 2,
Thursday,Friday,
Saturday,Sunday
};
示例代码:
#include <stdio.h>
//enum abc{MOD=100,TUE,WED};
enum abc{MOD=100,TUE,WED};
int main()
{
//enum abc a1 = MOD;
enum abc a1 = 800; //语义限制符,不强制,不在区间内也能编译,
printf("the a1 is %lu:%d\n",sizeof(a1),a1); //取3种里的任意一种
printf("the a is %d\n",WED);
return 0;
}
typedef
数据类型的别名
int a = 170;
int b = 3600;
len_t a = 170;
time_t b = 3600;
int a; //a是一个int类型的变量
typedef int a_t; //a是一个int类型的外号
a_t mysize;
xxx_t:typedef
- 逻辑结构
CPU顺序执行程序
分支—》选择
循环
if、else
switch{整形变量}
case 1:
break
default
多分支
do、while、for
for:次数
while:条件,某种环境下循环
continue、break,goto
goto函数内部跳转,不能再不同的函数之间跳转
4. 类型修饰符
对内存资源存放位置的限定
资源属性中位置的限定
auto
默认情况------->分配的内存可读可写的区域
auto int;
auto long b;
区城如果在{}内,代表位置是在栈空间
register
register int a;
限制变量定义在寄存器上的修饰符,主要是告诉别人a访问比较频繁。
定义一些快速访问变量,
编译器会尽量的安排CPU的寄存器区存放,如果寄存器不足时,a还是放在存储器中。
&这个符号对register不起作用,不合法,告诉不了地址
内存(存储器) 寄存器(CPU缓存器)
0x100 R0,R2,R5
示例代码:
#include <stdio.h>
int main()
{
register int a;
a = 0x10;
printf("the a is %d\n",&a);
return 0;
}
返回值:
E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
2.c: In function 'main':
2.c:9:5: error: address of register variable 'a' requested
static
静态
应用场景:
1)、修饰3种数据
int fun()
{
int a;====>static int a;
}
2)、函数外部的变量
int a; =====>static int a;
int fun()
{
}
3)、函数的修饰符
int fun();======>static int fun();
const
常量的定义 C语言软肋
只读的变量,不能显示的修改。指针可以修改,内存泄漏。
const int a = 100;
extern
外部申明,全局变量函数,与static相反
volatile
告知编译器编译方法的关键字,不优化编译,
和地址关系比较大,嵌入式底层,单片机,驱动开发中常用
int a = 100;
while ( a==100 );
mylcd();
[a] : a的地址
f1:LDR R0,[a]
f2:CMP r0,#100
f3:JMPeq f1 ----->JMPeq f2 //编译器优化后可能直接执行f2,漏掉了f1
f4:mylcd();
- 运算符
算术操作运算
+,-
,/
CPU性能不支持的话,可移植性会变差
int a = b10; CPU可能多个周期,甚至要利用软件的模拟方法去实现乘法,纯软情况下乘法可能不能实现。
int a = b+10; CPU一个周期可以处理
%:
0% 3=0 1%3 = 1 2%3=2 3%3=0 4%3=1 … .
%n = res[0 - m-1]
取一个范围的数:
eg.给一个任意的数字,得到一个1到100以内的数字?
( m % 100 )+1 =====>res;
得到M进制的一个个位数
循环数据结构的下标
逻辑运算
真,假,返回结果1 0
int a = -1;
if(a)
||、&&
位置不能交换
A || B —> B || A 不相等 A为真后,B不执行
A && B 同理,A为假后,B不执行。
示例:
#include <stdio.h>
int main()
{
int a = 10;
int res;
// res = (a == 10) || printf("==============\n"); //如果a==10为真,则以后没必要执行
res = (a != 10) || printf("==============\n");
printf("the main is %d\n",res);
return 0;
}
>,>=,<,<=
!逻辑取反
?: 三元
位运算
<<,>>
左移:乘法*二进制下的移位
mm<<1; m2
mm<<\n; m2*n
[数据、数字]
-1 *2 -2:
8bit
100000001 //原始的-1
111111110 //自动取反
111111111 === -1 原始和取反相加,得到实际存储的-1
1000 0010
1111 1101
1111 1110 ==== -2 //左移空位补0 左移乘以2
右移:跟符号变量有关,严格遵循符号位的操作符
int a; a>>n;
usigned int a a>>n;
死循环示例:
#include <stdio.h>
int main()
{
int a = 10;
// int a = -10; //补位都是1,进入死循环
while(a){
a = a>>1;
}
printf("++++++++++\n");
}
&,|,^
与,或,异或
&,|
A & 0—>0
&:屏蔽
int a = 0x1234;
a & 0xff00; 屏蔽低8bit,取出高8位
A & 1->A
& 取出 清零器,clr
|:
A | 0 ==== A;
保留
A | 1 ======1
设置为高电平的方法,设置set
设置一个资源的bit5为高电平,其他位不变
int a;
a = a | 1 0 0 0 0 0 ; a = (a |(0x1 <<5)); =====> a | (0x1 << n) ;
清除第五位
int a;
a = a & 011111 31 a & 31 31:32bit
a = a & ~(0x1<<5)======>a = a & (~(0x1<< n));
^,~
、~
1^1=0 0^0=0 1^0=1
算法AES SHA1
int fun()
{
int a = 20;
int b = 30;
xXXX----->
int c;c= a;a= b;b=c;
a =a^b; b =a^b; a = a^b;
a=30
b=20
}
~
0xf0 ~ 0xffff ff0f
思考:我们想资源456bit设置为101?
赋值运算
a|(0x1<<5)
~a
a=a+b
a+=b
a = a+b;
a+=b
al=(0x1<<5)
a &=~(0x1<<5)
6. 内存访问符号
()
限制符 (a+b)*c
函数访问符号
int fun();
fun();
[]
数组
内存访问的ID符号 a[1] a[2]
{}
函数体的限制符
struct abc{xxxx}的定义符号
.->
对连续空间自定义成员变量的访问方法,->地址访问
&,p
p取地址
a10 乘法