[嵌入式专栏](系列一 、C语言)

文章目录

    • 1 . 概要
    • 2 . C语言语法
      • 2.1 关键字解释、
    • 3 . C语言运算符优先级
    • 4 . 本质理解
      • 4.1 内存
      • 4.2 语法
    • 5 . 语法应用
      • 5.1 示例
      • 5.2 指针
      • 5.3 结构体
    • 6 . 编译过程
      • 6.1 预处理
      • 6.2 编译
      • 6.3 汇编
      • 6.4 链接
    • 7 . 小结


【极客技术传送门】 : https://blog.csdn.net/Engineer_LU/article/details/135149485


1 . 概要

  • 深入浅出C语言,以下内容简洁,适合入门与加深理解

2 . C语言语法

auto break case char const continue default do
double else enum extern float for goto if
int long register return short signed sizeof static
struct switch typedef union unsigned void volatile while

2.1 关键字解释、

auto :声明自动变量
break:跳出当前循环
case:开关语句分支
char :声明字符型变量或函数返回值类型
const :声明只读变量
continue:结束当前循环,开始下一轮循环
default:开关语句中的“默认”分支
do :循环语句的循环体
double :声明双精度浮点型变量或函数返回值类型
else :条件语句否定分支(与 if 连用)
enum :声明枚举类型
extern:声明变量或函数是在其它文件或本文件的其他位置定义
float:声明浮点型变量或函数返回值类型
for:一种循环语句
goto:无条件跳转语句
if:条件语句
int: 声明整型变量或函数
long :声明长整型变量或函数返回值类型
register:声明寄存器变量
return :子程序返回语句(可以带参数,也可不带参数)
short :声明短整型变量或函数
signed:声明有符号类型变量或函数
sizeof:计算数据类型或变量长度(即所占字节数)
static :声明静态变量
struct:声明结构体类型
switch :用于开关语句
typedef:用以给数据类型取别名
unsigned:声明无符号类型变量或函数
union:声明共用体类型
void :声明函数无返回值或无参数,声明无类型指针
volatile:说明变量在程序执行中可被隐含地改变
while :循环语句的循环条件

  1. 常用关键字
    if for switch break unsigned char typedef struct
    对,常用的就只有几个,后面都是语法与逻辑的事情,那么教程到这里就为止了吗?NO,我们要从本质上理解C语言

3 . C语言运算符优先级

[嵌入式专栏](系列一 、C语言)_第1张图片

4 . 本质理解

首先要明白,我们为什么要学C语言,作者当初学C语言是为了点灯, 如果和我一样是嵌入式方向,则接下来看这篇文章的贴合度将达到100%,好了,废话不多说,直入正题。

4.1 内存

学C语言先不要管语法, 先让内存概念深入人心, 什么是内存 ?
这里举个“栗子”,地球上有70多亿人,每个人都属于大自然,我们从大自然中诞生,亦从大自然回归,每个人都属于大自然中的“内存”,我们最终回归大自然(相当于内存释放),而我们学习C语言,就能成为一个领域的世间主宰,掌控“亿万”内存,想必看到这里,大家对内存已经有了独特的认识。

4.2 语法

前面提到了主宰者,那身为主宰者怎么掌控这些内存 ?
没有功法加持,就很难灵活调用,岂不荒废了这一身牛逼的功力,所以有前辈创出了这顶级功法“C语言”!里面通过技能(语法)来操控世间万物(内存)。

5 . 语法应用

5.1 示例

int main(int argc,char* argv[]) {
	u8 i = 1;
	if (i == 1) {
		i = 2;
	}
	return 0;
}

语法极其简洁,可能有读者不太了解 “ int argc,char* argv[] ”:这里的内容意义,由于C语言是面向过程,系统级,当系统调用一个程序时,可以执行初期给定输入数据,其中前者是数据数量,后者是具体数据

5.2 指针

接下来我们直接看指针,部分人群看到指针语法以及应用有些许畏惧,不要畏惧!我们可以把指针玩弄于股掌之中,然后为什么C语言要设计出指针,是为了内存交互便利,从时间和空间上考虑

int main(int argc,char* argv[]) {
  u8 *p = null;
	u8 i = 1;
	
	p = &i;
	*P = 2;
	
	if (i == 1) {
		i = 2;
	}
	return 0;
	
}

指针语法也是极其简洁,相比上个示例也多了 &和* ,这里的&取地址,*取值,为什么要取地址,又为什么要取值,所有应用按上个示例那样操控变量不香吗,是的,不香,因为我们从时间和空间上考虑才能更好的晋升大道,例如我灵魂可以出窍到别人身上,那么我可以随意操控全部人怎么做一件事,而不需要我再口述和对方沟通怎么做,效率大大提高。


5.3 结构体

typedef struct {
	u8 i;
}T_str;

T_str T;

int main(int argc,char* argv[]) {
	u8 i = 1;
	if (i == T.i) {
		i = 2;
	}
	return 0;
}

这里抛出结构体,为什么C语言要设计这些奇形怪状的东西,直接全部 u8 数组不好吗,不好,因为一旦我们工程庞大,数据内存段定义分布,就不好管理了,为了更好掌控万物,我们一般高内聚,就像人的体内有N个细胞组成在一起

数组与结构体的差异在于,数组的连续段数据类型是相同的,而结构体可以不同数据类型组成连续段内存

typedef struct {
	u8 i;
}T_str;

T_str T;

int main(int argc,char* argv[]) {
  u8 *p = null;
	u8 i = 1;
	
	p = (u8 *)&T;
	*p = 2;
	return 0;
}

指针可以指向万物,那当然也可以指向结构体,指针无所不能。

6 . 编译过程

6.1 预处理

#define macro 1
void func() {
	u8 x = macro;
}	

预处理阶段时把宏macro替换为1

6.2 编译

u8 x = macro;
MOVS r0, #0x01

编译阶段把C语言转换成汇编内容

6.3 汇编

MOVS R0, #0x01
0x2001

汇编阶段把汇编指令根据当前平台转换成机器码

6.4 链接

程序中N条汇编机器码需要整合在一起,此时把这些机器码链接在一块输出最终可执行文件


编译过程大致如此,不过有人会迷茫,最终可执行文件为什么可以执行?这里深入讲述一下,计算机最终执行权是CPU,CPU按照Flash或RAM区域地址逐步执行,而当可执行文件存到Flash或RAM区域,CPU就会根据可执行文件的内容逐步执行,这里讲解一个例子,例如当我在桌面GUI右击一下鼠标,为什么桌面会弹窗出来,步骤是这样,鼠标机械动作触发了电信号,经过USB协议与电脑主板通信,电脑主板把收到的数据反馈给CPU,由于加载了系统,系统层面会接收到鼠标这种HID设备事件,系统事件循环触发系统GUI已定逻辑,显存加载弹窗的数据,系统界面弹窗,这一切都是因为电脑系统已经集成了逻辑,这个系统逻辑就是用C语言逐步写出来的,也是经过了上述编译四个过程得出的程序

7 . 小结

学习C语言,有疑惑可以用C free,VS等软件验证程序,如果中途学习感觉到困惑有阻碍,不必忧心,放宽心态,多看多写,自然而然就明白了其中的逻辑,另外不必刻意背运算优先级,写着写着自然就记住了,印象模糊时可来回顾一遍运算优先级,看到这里,相信大家基本入门了。

  • 如果喜欢,请关注一波,后续持续更新嵌入式实用内容,谢谢大家。

技术交流QQ群 : 745662457
群内专注问题答疑,项目外包,技术研究

你可能感兴趣的:(嵌入式,单片机,c语言,嵌入式硬件)