网址:Linux嵌入式ARM开发教程第一阶段_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili https://www.bilibili.com/video/av15875305/?spm_id_from=333.788.videocard.1
一、C语言基础与数据类型
1.GCC概述
GCC最初的全名是GNU C Compiler(开源社区)
变成GNU Compiler Collection
翻译官 翻译组织
文件后缀名gcc
.c
gcc -o output
gcc -o 输出的文件名 输入文件名
2.c语言的编译过程
预处理
cpp -o a.i 001.c
替换
【gcc -E】
编译
/usr/lib/gcc/i686-linux-gnu/4.6/cc1
【gcc -S】
汇编
as -o a.o a.s
【gcc -c】
链接
/usr/lib/gcc/i686-linux-gnu/4.6/collect2
【gcc -o】
gcc -o build 001.c
3.c语言常见错误举例
预处理错误
#include "name"(一般自定义的) 从当前目录开始寻找
#include <name>(一般库的) 从系统文件中寻找
not find
gcc -I跟查找头文件的目录
编译错误
链接错误
4.预处理的使用
#include 包含头文件
#define 宏 替换,不进行语法检查
#define 宏名 宏体 加括号
#define ABC 5+3
print("%d\n",ABC*5) 5+3*5
条件编译
#ifdef
#else
#endif
预定义宏(系统定义的宏)
__FUNCTION__ 函数名
__LINE__ 行号
__FILE__ 文件名
printf("the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__); 查看函数与调试
5.条件预处理举例
调试版本
发行版本
条件编译
#ifdef ABC1
#else
#endif
gcc -D:
gcc -DABC1 == #define ABC1
6.发展开下的#、##
# 字符串化
## 连接符号
#define ABC(x) #x
#define ABC(x) day##x
#include <stdio.h>
#define ABC(x) #x
#define DAY(x) myday##x
int main()
{
int myday1 = 10;
int myday2 = 20;
printf(ABC(ab\n));
printf(“the day is %d\n”,DAY(1));
return 0;
}
7.c语言常用关键字及运算符操作
【重点】
掌握c语言的常用关键字及其应用场景,使用技巧
掌握位运算的典型操作
掌握常用的逻辑操作
【难点】
when to do? how to do? why to do?
熟悉常用运算符的典型操作,总结什么时候使用什么运算符
【实验考核】
关键字:编译器预先定义了一定意义的字符串
int a;
32个关键字
sizeof:编译器给我们查看内存空间容量的一个工具
int a;
printf("the a is %d\n",sizeof(a));("the a is %lu\n")
return
返回的概念
8.基本数据类型
int
long、short
unsigned、signed
float、double
void
C操作对象:资源/内存(内存类型的资源,LCD缓冲、LED灯)
C语言如何描述这些资源的属性?
资源属性【大小】
限制内存(土地)的大小,关键字
int a; charc;
sizeof(a) = 4;
char
硬件芯片操作的最小单位:
bit 1 0
软件操作的最小单位:8bit == 1B
4Mbit Kbit/s与KB/s
应用场景:
硬件处理的最小单位
char buf[xx[; int buf[x];
ASCll码表 8bit == 256
错误: char a = 300; a++
int
大小:根据编译器来决定 TC2.0
编译器最优的处理大小:
系统一个周期,所能接受的最大处理单位,int
32bit 4B int
16bit 2B int
int a; char a;
整型常量
char a=300; 300l 300L
2B 65535
int a = 65535;
进制表示
十进制 八进制 十六进制 二进制
3bit 8进制
111 0x7 int a=010; 8
4bit 16进制 int a=0x10; 16
long、short
特殊长度的限制符
unsigned、signed
无符号:数据
有符号:数字
内存空间的最高字节是符号位还是数据
unsigned int a;
char a;
>>右移操作
char a = -1; 0xff
a>>1
unsigned char b = -1;
b>>1
float、double
大小
float 4B
double 8B
内存存在形式
0x10 16
0001 0000 16
1.0
0001 0000 (x)
浮点型常量
1.0 1.1 double
1.0f float
void
void a;占位,语义符
void fun();
9.自定义数据类型
C编译器默认定义的内存分配不符合实际资源的形式
自定义 = 基本元素的集合
struct、union、enum、typedef(数据类型的别名)
struct
元素之间的和
struct myabc{
unsigned int a;
unsigned int b;
};
int i;
struct myabc mybuf;
顺序有要求的
union
共用起始地址的一段内存
技巧型代码
union myabc{
char a;
int b;
}
union myabc abc
int a;
enum
enumerate 一一列举
被命名的整型常数的集合
#define MON 0
#define TUE 1
#define WED 2
enum abc{MON = 100, TUE, WED}
enum abc a1=800;
printf("the a1 is %lu:%d\n",sizeof(a1),a1);
printf("the %d\n",MON);
enum 枚举名称{常量列表};
enum week{
Monday = 0, Tuesday = 1, Wednesday = 2,
Thursday, Friday,
Saturday,Sunday
};
typedef: xxx_t
数据类型的别名
int a =170;
int b =3600;
len_t a = 170;
time_t b = 3600;
int a; a是一个int类型的变量
typedef int a; a是一个int类型的外号
a_t myxize;
二、逻辑结构、类型修饰符与运算符
1.逻辑结构
if、else
switch、case、default
do、while、for
continue、break、goto
CPU顺序执行程序
分支
循环
if(条件表达式)
xxx
else
yyy
switch(整型数字){
case1:
break;
default;
}
for: 次数
while: 条件
goto在一个函数中进行跳转
2.类型修饰符
auto、register、static、const、extern、volatile
对内存资源存放位置的限定
资源属性中位置的限定
auto
默认情况--->分配的内存可读可写的区域
auto int a;相当于int a;
auto long b;
register(可用于访问频繁的变量)
register int a;
限制变量定义在寄存器上的修饰符
定义一些快速访问的变量
编译器会尽量的安排CPU的寄存器去存放这个A,如果寄存器不足时,A还是放
在存储器中。
&这个符号对register不起作用
内存(存储器) 寄存器
static
静态
应用场景:
修饰3种数据
1)函数内部的变量
int fun()
{
int a; ===> static int a;
}
2)函数外部的变量
int a; ===> static int a;
int fun()
{
}
3)函数
int fun(); ===> static int fun();
extern
外部申明
const
常量的定义
只读的变量
const int a = 100;
volatile
告知编译器编译方法的关键字,不优化编译
修饰变量的值的修改,不仅仅可以通过软件,也可以通过其他方式(硬件外部的用户)
int a = 100;
while(a==100);
mylcd();
f1:LDR R0, a
f2:CMP R0, #100
f3:JMPeq f1 ----> 软件优化为 JMPEQ f2
f4:mylcd();
3.运算符
算术操作运算
逻辑运算
位运算
赋值运算
内存访问符号
很多CPU不支持乘法除法
int a = b*10; CPU可能多个周期,甚至要利用软件的模拟方法去实现乘法
int a = b+10; CPU一个周期可以处理
%求模
0 % 3 = 0 1%3 = 1 2%3=2 3%3=0
n%m=res[0 - m-1]
取一个范围的数:
eg.给一个任意的数字,得到一个1到100以内的数字?
(m% 100)+1 ===>res;
得到m进制的一个个位数
循环数据结构的下标
逻辑运算
真 假
返回结果就是1 0
存在预判断,先看左边,如果不符合,就不继续执行
A || B != B || A
A && B
int main()
{
int a =10;
int res;
res = ((a != 10) || printf("=====\n"));
printf(“the res is %d\n”,res);
return 0;
}
!
对比位运算中取反
int a =0x0;
!a if(!a){}
~a 0xffff
4.位运算
<< >>
& | ^
~
左移:乘法*2 二进制下的移位
m<<1; m*2
m<<n; m*2*n
4: 00100
8: 01000
int a = b*32; ===> b<<5
[数字、数据]
-1*2 -2:
8bit
右移
m>>n m/(2*n)
符号位问题
int a; a>>n
unsigned int a; a>>n
int a = xxx
while(a){
a = a>>1;
}
printf("---------\n");
&:屏蔽
int a = 0x1234
a & 0xff00; 屏蔽低8bit,取出高8bit
&:取出
&:清零器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 & 0 1 1 1 1 1 31 注意不要 a & 31
a = a & ~(0x1<<5); ===> a = a & (~(0x1<<n))
^:
1 ^ 1 = 0 0^0=0
1^0=1
int fun()
{
int a = 20;
int b = 30;
a = a^b;
b = a^b;
a = a^b;
a = 30 b = 20
}
~
0xf0 ~ 0xffff ff0f 32bit
5.赋值运算
+= -= &= |=
6.内存访问符号
()
限制符 (a+b)*c
函数访问
int fun();
[]
数组
内存访问的ID符号
a[1] a[2]
{}
函数体的限制符
struct abc{xxx};
-> .
& *