文章目录
- 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 乘法



















