嵌入式初学-C语言-前言

概述

C语言是一种计算机编程语言,我们是利用代码来控制计算机的运行,从而达到某种目的,我们 就很有必要了解计算机的运行原理。

计算机组成

OS + 应用程序

计算机硬件

基本组成:

输入设备:输入数据给计算机处理,举例如:键盘,鼠标

输出设备:结果数据展示 ,举例如:显示器,打印机

外存储器:永久存放数据,容量大,但访问速率慢,举例:磁盘

内存储器:临时存放待处理的数据及运行的程序代码,访问速度快,数据是临时存放,相对来说, 容量较小,举例:内存条

处理器:

运算器:进行算术运算和逻辑判断

控制器:管理和协调计算机的其它部件

计算机运行原理

  1. 计算机通过输入设备将数据加载到内存

  2. CPU从内存中获取数据进行处理,并将结果数据再次放回到内存。

  3. 通过输出设备将结果数据进行输出展示。

  4. 如果我们需要将结果数据进行长期存储,可借助于外存储器保存。

计算机语言

机器语言(0,1,指令码) 计算机唯一可以直接运行的代码

汇编语言(符号化指令):汇编语言必须经过汇编程序转换为机器语言后计算机才能运行

高级语言:利用数学运算符及一些英文单词来描述程序指令。(C/C++/JAVA/Python)高级语言是 必须要通过编译器或者解释器转换为机器语言。

C语言版本

为了C语言健康发展下去,很多有识之士及美国国家标准协会(ANSI)于1982年成立了一个委员会以 确定C语言的标准。

C89:1989 ANSI 发布了第一个完整的C语言标准,即C89。

C90:不过人们习惯性的称为 "ANSI C"1990年ISO(国际标准化组织一字不改的采纳了 C89,官方给出的 名称为 ISO C90)

C99:1999年,C语言标准经过了一次修正和完善后,ISO发布了新版的C语言标准,简称" C99"。

C18:最新的C语言标准为 2018年6月份发布的 "C18"

C语言特点

C语言是一种强大而灵活的语言,可以用来编写任意复杂的程序。

C语言简洁、紧凑,使用方便。

C语言是可移植的。

C语言很适合结构化程序设计,因而要求用户以功能模块的方式来思考问题。

C语言可直接控制硬件 (位运算符,地址 )

生成目标代码质量高,程序执行效率高,运行速度快。

优点:

功能强大,语言灵活

C可移植性强

C语言可以直接控制硬件

C语言运行效率高

C语言具有结构化的控制语句

C语言具有丰富的数据类型和运算符

缺点:

C语言的缺点主要表现为数据的封装性弱。这一点使得C在数据的安全性上有很大的缺陷,这也是C 和C++的一大区别。

C语言的语法限制不太严格,对变量的类型约束不严格,影响程序的安全性,对数组下标越界不做 检查等。从应用的角度,C语言笔其他高级语言较难掌握。也就是说,对用C语言的人,要求对程序 设计更熟练一些。

C语言开发过程

C语言的开发分为三步:①编辑-->②编译-->③运行

  1. 创建一个C语言源程序文件(.c)

  2. 在源文件中由程序员编写C语言程序代码

  3. 由编译器对源文件进行编译,生成可执行程序

  4. 机器运行可执行程序,确认功能的正确性

C语言的编译四步骤:①预处理-->②编译-->③汇编-->链接④

C语言中3类标识符:

1.关键字(32个)

1.auto:声明自动变量,用于函数内部的局部变量

2.break:跳出当前循环

3.case:开关语句的一个分支

4.char:声明字符型变量或函数

5.const:声明只读变量,其值不能被修改

6.continue:跳出当前循环的剩余部分,开始下一次循环

7.default:开关语句中的默认选项

8.double:声明双精度浮点型变量或函数

9.do:用在循环中,表示循环体重复执行的部分

10.else:条件语句中的"否则"部分

11.enum:声明枚举类型

12.extern:声明变量或者函数是在别处定义的

13.float:生命浮点型变量或函数

14.for:一种循环语句

15.goto:无条件跳出语句

16.if:条件语句,如果指定条件为真则执行if后面的代码

17.int:声明整型变量或函数

18.long:声明长整型变量或函数

19.register:声明寄存器变量,提示编译器,该变量可能被频繁使用

20.return:子程序返回值

21.short:声明短整型变量

22.signed:生命有符号类型变量或函数

23.sizeof:计算数据类型或变量的大小

24.static:生命静态变量,表示变量生命周期直到程序结束

25.struct:生命结构体类型

26.switch:用于开关语句,选择多个选项之一执行

27.typedef:用于给数据类型定义别名

28.union:声明共用体类型

29.unsigned:生命无符号类型或函数

30.void:声明函数无返回值或者无参数

31.volatile:说明变量在程序执行中可被隐藏的更改,提示编译器对访问该变量的代码不进行优化

32.while:用于循环语句

12个预处理命令

C语言的12个预处理命令包括:‌#if、‌#ifdef、‌#ifndef、‌#else、‌#elif、‌#endif、‌#define、‌#undef、‌#line、‌#error、‌#pragma、‌#include。‌ 这些命令都以符号#开头,‌每条预处理指令必须独占一行。‌这些命令在C语言编程中扮演着重要的角色,‌允许程序员在编译前对程序进行各种条件和宏定义的处理,‌从而影响编译过程和程序的最终行为。‌

#if、‌**#else**、‌**#elif** 和 #endif 用于条件编译,‌根据常数表达式的结果有选择地编译程序源代码的不同部分。‌

#define 用于定义一个标识符和一个串,‌在源程序中每次遇到该标识符时,‌都用定义的串替换它。‌

#undef 用于取消之前定义的宏。‌

#line 用于修改源文件的行号和文件名。‌

#error 用于强制编译程序停止编译,‌主要用于程序调试。‌

#pragma 用于为特定的编译器提供非标准的编译指令。‌

#include 用于读入另一个源文件,‌允许程序员将代码分割到多个文件中,‌并通过包含文件的方式将它们组合在一起。‌

用户标识符

C语言中的用户标识符(User Identifier)是用来命名变量、函数、标签等程序实体的名字。C语言的用户标识符必须遵循以下规则:

-只能包含字母(大写"A-Z"和小写"a-z")、数字("0-9")和下划线("_")。

-必须以字母或下划线开头。

-是大小写敏感的,即"i"和"I"被视为不同的标识符。

-不能使用C语言的关键字作为用户标识符。

用户标识符示例:

int value; // 合法

int _value; // 合法

int 2value; // 不合法,不能以数字开头

int value@; // 不合法,只能包含字母、数字和下划线

int for; // 不合法,不能使用C语言的关键字

什么是原码、反码、补码:

1. 原码

原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。

比如:

如果是8位二进制:

[+1]原= 0000 0001

[-1]原= 1000 0001

第一位是符号位,因为第一位是符号位,所以8位二进制数的取值范围就是:(即第一位不表示值,只表示正负。)

[1111 1111 , 0111 1111] 即 [-127 , 127]

原码是人脑最容易理解和计算的表示方式。

2. 反码

反码的表示方法是:

  • 正数的反码是其本身;
  • 负数的反码是在其原码的基础上,符号位不变,其余各个位取反。

[+1] = [0000 0001]原= [0000 0001]反

[-1] = [1000 0001]原= [1111 1110]反

可见如果一个反码表示的是负数,人脑无法直观的看出来它的数值。通常要将其转换成原码再计算。

3. 补码

补码的表示方法是:

  • 正数的补码就是其本身;
  • 负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1。(也即在反码的基础上+1)

[+1] = [0000 0001]原= [0000 0001]反= [0000 0001]补

[-1] = [1000 0001]原= [1111 1110]反= [1111 1111]补

对于负数,补码表示方式也是人脑无法直观看出其数值的。通常也需要转换成原码再计算其数值。

为什么要有原码、反码、补码?

首先, 因为人脑可以知道第一位是符号位,在计算的时候我们会根据符号位,选择对真值区域的加减。但是对于计算机,加减乘数已经是最基础的运算,要设计的尽量简单,计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂!

于是人们想出了将符号位也参与运算的方法。我们知道,根据运算法则减去一个正数等于加上一个负数,即:1-1 = 1 + (-1) = 0, 所以机器可以只有加法而没有减法,这样计算机运算的设计就更简单了。

于是补码的出现,解决了0的符号问题以及0的两个编码问题:

1-1 = 1 + (-1) = [0000 0001]原+ [1000 0001]原= [0000 0001]补+ [1111 1111]补= [1 0000 0000]补=[0000 0000]补=[0000 0000]原注意:进位1不在计算机字长里。

这样0用[0000 0000]表示,而以前出现问题的-0则不存在了。而且可以用[1000 0000]表示-128:-128的由来如下:

(-1) + (-127) = [1000 0001]原+ [1111 1111]原= [1111 1111]补+ [1000 0001]补= [1000 0000]补

-1-127的结果应该是-128,在用补码运算的结果中,[1000 0000]补就是-128,但是注意因为实际上是使用以前的-0的补码来表示-128,所以-128并没有原码和反码表示。(对-128的补码表示[1000 0000]补,算出来的原码是[0000 0000]原,这是不正确的)

使用补码,不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数。这就是为什么8位二进制,使用原码或反码表示的范围为[-127, +127],而使用补码表示的范围为[-128, 127]。

因为机器使用补码,所以对于编程中常用到的有符号的32位int类型,可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位,而使用补码表示时又可以多保存一个最小值。

相关推荐
远望清一色8 分钟前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
weixin_4426434217 分钟前
推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案
服务器·网络·安全·filelink数据摆渡系统
confiself18 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
XiaoLeisj29 分钟前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
杜杜的man33 分钟前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*34 分钟前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
半桶水专家34 分钟前
go语言中package详解
开发语言·golang·xcode
llllinuuu35 分钟前
Go语言结构体、方法与接口
开发语言·后端·golang
Karoku06635 分钟前
【企业级分布式系统】Zabbix监控系统与部署安装
运维·服务器·数据库·redis·mysql·zabbix
cookies_s_s36 分钟前
Golang--协程和管道
开发语言·后端·golang