1.1 C介绍语言系统
1.1.1 C语言概述
C语言是一种面向过程的通用计算机高级编程语言(分析解决问题的步骤,一步一步解决问题),C语言一般用于编写底层硬件驱动程序和编写操作系统(C语言->unix系统->Linux->andriod)。
C语言高效 灵活性高à编写操作系统具有天然优势。C语言 汇编指令(平台汇编指令不一致) C语言编写大大缩短了开发周期(汇编指令);
C语言缺点:可维护性低,可复用性低;
面向对象:分析问题结局的步骤:分成对象处理问题;
机器人行走:按C写:先迈左腿,抬高30度,向前跨30度,落脚;
按照C 写作:只调用对象中的行为行走(行走行为函数:底部或面向过程)
大大节省了开发周期;
C面向高级语言和过程C 面向对象的高级语言:
C: 可维护性低,可重用性差;优点:灵活性高(适合操作系统开发),节省内存消耗(更适合单片机开发:单片机内存容量小)
C :可维护性高,可重用性好;缺点:灵活性降低,内存空间消耗(对象中无用的属性也需要开放空间)
C 与C语言:
单功能/单片机开发C最具优势:更快 C语言倾向于底层;
C 高级编程语言:刚开始比较慢,后期应用开发比较快;
Python也可编程单片机:运行效率远低于C;
1.1.2 C语言程序的组成和结构
- C语言编辑器&&编译器使用
gcc 要编译的文件 默认生成文件名 a.out
编译时会出现警告或错误:
使用”./可执行文件名运行编译的可执行程序
注:如果gcc后的“-o 生成可执行文件名称不写a.out。
gedit现阶段编辑器首选配置root用户无法实现(因为管理员身份是临时身份);如果将虚拟机安装手册配置成root登录身份可以使用gedit首选配置;
- C语言程序组成
主函数
main函数:是程序的入口地址,在程序运行时自动运行。一旦主函数运行结束,整个程序运行结束。在C语言中,主函数的名称必须是main编程人员不能自定义主函数名称。主函数只有一个。
分析: 主函数的名称必须是main“;
分析: 主函数有,只有一个
- 头文件
第一个文件中存储了调用功能函数的声明(让编译器知道可以使用哪些函数)。第一个文件不会被编译和执行,只能在预处理中匹配#include使用它。在C语言中,每个标准库函数都有一个相应的头文件。使用哪个包含相应的头文件。
函数:函数定义 函数声明 函数调用 将函数声明放入头文件中;
#表示预处理阶段(编译过程:预处理(替换) 编译(C语言编译为汇编指令) 汇编(汇编指令到二进制指令) 链接(将.c编译成源文件.o链接文件)这类知识->预处理阶段)
include:包含
C库中常用的输入输出函数:标准库C库 标准输入输出函数包括输入输出头文件
#include <stdio.h>:stdio:standard input output .h在C语言与C 中头文件的后缀名称
<>:在软件安装目录下搜索头文件的路径
linux搜索路径(//usr/include/i386-linux-gnu/bits/stdio.h)
“”:寻找头文件的路径,头文件首先在工程目录下查找,如果查找不到需要通过软件安装目录进行查找;
#include “stdio.h” 寻找时间大于#include <stdio.h>
#include “stdio.h如果你的项目目录下有stdio.h会影响编译的结果(编译出错)
#include <tdio.h> int main() //主函数 { printf(“hello C\n”); //函数调用语句 return 0; } Int:函数具有返回值 return 0;程序结束 0所代表的的退出状态 通知给操作系统,本进程已经结束退出状态值为0,可以进行清理程序中堆区开辟; |
- C语言程序结构
C语言运行范围
C语言程序只能在“{}“范围内执行。
- C语言语句
C语言程序的执行部分是由语句组成。程序的功能是由执行的语句实现,使用分号“;“来表示一条语句的结束。C语言语句分为:控制语句、函数调用语句、表达式语句和空语句。
控制语句:if() for() break;----------------相关章节(九条语句章节)
函数调用语句:printf(“%s\n”,”hello”); fun(); strlen();---------相关章节(函数章节)
表达式语句:c=a+b; a++; a+=2; a=b*3;------------------相关章节(运算符章节)
- 空语句: ;分号为空语句 ; ;
1.1.3 C语言编程规范
一条语句中,不同内容之间使用空格间隔;
int A = 10;if( a > b ) 太拥挤不利于程序员阅读;
每条语句不要顶格写,使用table键自动缩进。向右缩进:Tab;向左缩进:Shif+Tab。
#include <stdio.h> int main() //主函数 { TAB键printf(“hello C\n”); //函数调用语句 TAB键return 0; } |
每一条语句各自占一行,大括号“{}”每个占一行
对代码进行注释,多行注释使用“/* 要注释的内容 */”,单行注释使用“//要注释的内容”
#include <stdio.h> /*********************************************************** 函数名称:主函数 函数功能:…. 函数参数:… 返 回 值:…. ***********************************************************/ int main() //主函数 { TAB键printf(“hello C\n”); //函数调用语句 TAB键return 0; } |
1.2 嵌入式C语言主要知识点:
C语言的基本概念、C语言的基本结构和编程规范;
基本数据类型(原码反码补码 进制 基本数据类型) -------重点掌握
运算符(单目 双目运算符 三目运算符) -------重点掌握
九条语句(选择语句if switch 循环语句for while dowhile 跳转语句) -------重点掌握
32个关键字
数组(一维数组二维数组) -------重点掌握
函数(函数定义编写通用 函数声明 函数调用 库函数介绍) -------重点掌握
指针(C语言中重点 指针数组 数组指针 函数指针 指针函数等等) -------重点掌握
结构体(块 结构体成员对齐等) -------重点掌握
链表(指针与结构体结合) --------重点掌握
共用体、枚举和预处理、模块化编程 -------重点掌握
期末考试
1.2.1 嵌入式C语言学习建议
先敲代码---照敲(搞懂程序逻辑),加上自己的理解注释。-------成功了70% 不要眼高手低
自己写代码---根据题目要求去写;成功了----20%
上机调试—自己先去分析,计算你的逻辑结果,再去执行程序,对比结果.
1.2.2 嵌入式C语言作业要求
每天按时完成作业早8点前需要提交
在上课的时候遇到不懂的问题及时提出,当堂解决;下课连线方式解决;
1.2.3 C语言原码、反码、补码(了解)
计算机中最小的存储单元为比特(位);计算机在存储时会按照8个比特位为一个字节进行存储,手机中的128G(所代表的的为128G字节);一个比特位能够表示两种信息,一个字节能够表示的信息量为2^8次方个。
计算机中进行数值运算时:
数值:1+2=3算数结论:3
如果不考虑原码反码补码:1+2 = 0000 0001 +0000 0010 =0000 0011 数值为3;
数值:1-1=0算数结论:0
如果不考虑原码反码补码:1-1=0000 0001 – 0000 0001 = 0计算机中没有减法运算器(无法实现减法);减法运算器电路相当复杂;
人为规定1+(-1)操作即可:将数值符号参与到加法运算中;
人为规定:最高位为符号位:0表示正数 1表示负数
1+(-1) = 0000 0001[原码] +1000 0001[原码]=1000 0010 数值:-2 ×
当前知识不能够满足咱们以上运算;
涉及出新的知识点:反码
正数的反码与原码是一致,负数的反码是对原码按位取反,只有最高位符号位不变;
1+(-1)=0000 0001[原码]+1000 0001[原码]=0000 0001[反码]+1111 1110[反码]=1111 1111[反码]=反码到原码进行显示给使用者1000 0000[原码] = -0(根据咱们高数知识:-0等同于0)
人为理解-0与+0是一致,但是0一般不带符号(+-对0没有任何意义)
计算机识别+0或者-0是比较麻烦的过程;
涉及出新的知识点:补码
正数的补码与原码一致;负数的补码是反码+1;
1+(-1)=0000 0001[原码]+1000 0001[原码]=0000 0001[反码]+1111 1110[反码]=0000 0001[补码]+ 1111 1111[补码] = 0000 0000(最高位溢出:不要了)=0000 0000[补码与原码一致]=0算数运算为0;
通过补码运算:计算机只需要有加法运算器就OK;
补码出现,解决了0的符号:导致两种编码问题-0 +0
数值:(-1) +(-127)=-128 算数结论:
-1 +(-127)=1000 0001[原码]+1111 1111[原码]=1111 1110[反码]+1000 0000[反码]
= 1111 1111[补码]+1000 0001[补码]=1000 0000[补码]数值-0:编译器规定了-0 数值应该-128
不要造成学习的负担:直接记忆:-128
笔试:一份最多为1个原码反码补码题 题目:-2 的补码是多少?
总结:
原码:最高位为符号位,0代表正数,1代表负数,无符号的最高位会成为数据位;
反码:正数的反码与原码一致;负数的反码与原码除符号位不变其它位进行取反;
补码:正数补码与原码一致;负数的补码是该数的反码加+1;
注意*运算器由算术逻辑单元(ALU)、累加器、状态寄存器、通用寄存器组等组成。算术逻辑运算单元(ALU)的基本功能为加、减、乘、除四则运算,与、或、非、异或等逻辑操作,以及移位、求补等操作。计算机运行时,运算器的操作和操作种类由控制器决定。
1.3 进制转换(熟悉)
进制也就是进位计数制,是人为定义的带进位的计数方法
学习:二进制、八进制、十六进制
进制是学习计算机语言最基本的知识,所以一定要掌握。其实它很简单,我们日常生活中有很多进制的例子,例如:
一分钟六十秒,逢六十进一,就是六十进制;
一天二十四小时,逢二十四进一,就是二十四进制;
一星期七天,逢七进一,就是七进制;
一年十二个月,逢十二进一,就是十二进制;
小学数学是逢十进一,就是十进制;
而计算机中的数据只有 0 和 1,逢二进一,就是二进制。
1.3.1 十进制转二进制/八进制/十六进制
整数部分:转 N 进制:除 N,取余,倒排
十进制转二进制/八进制/十六进制
十进制数值 21 为例:转为二进制 八进制 十六进制
十进制转二进制 |
十进制转八进制 |
十进制转十六进制 |
小数部分:十进制小数转二进制 八进制 十六进制 小数乘以 N,取整,小数部分继续乘以 N,取整,得到小数部分 0 为止,将整数顺序排列。
十进制转二进制 |
十进制转八进制 |
十进制转十六进制 |
1.3.2 二进制转八进制/十进制/十六进制
二进制转十进制方法为:把二进制数按权展开、相加即得十进制数。
二进制转八进制方法为:3 位二进制数按权展开相加得到 1 位八进制数。(注意事项,3 位二进制转成八进制 是从右到左开始转换,不足时补 0)。
二进制转十六进制方法为:与二进制转八进制方法近似,八进制是取三合一,十六进制是取四合一。(注意 事项,4 位二进制转成十六进制是从右到左开始转换,不足时补 0)。
二进制转十进制 |
二进制转八进制 |
二进制转十六进制 |
1.3.1 八进制转二进制/十进制/十六进制
八进制转二进制方法为:八进制数通过除 2 取余法,得到二进制数,对每个八进制为 3 个二进制,不足时在
最左边补零。
八进制转十方法为:把八进制、十六进制数按权展开、相加即得十进制数。
八进制转十六进制方法:将八进制转换为二进制,然后再将二进制转换为十六进制,小数点位置不变。
八进制转二进制 |
八进制转十进制 |
八进制转十六进制 |
八进制转为二进制: 0001 0101 二进制转十六进制: 0x15 |
1.3.4 十六进制转二进制/八进制/十进制(课间练习)
十六进制转十方法为:把八进制、十六进制数按权展开、相加即得十进制数。
十六进制转八进制 |
十六进制转十进制 |
十六进制转二进制 |
十六进制需要先转为二进制:0001 0101 通过二进制转为八进制: 025 |
1.4 C语言数据类型
1.4.1 C语言数据类型概述
数据类型主要是为了定义数据在内存中所占的空间大小(字节数)以及分配数据的存储位置以及确定其作用范围(数据大小范围)。1字=2字节 1字节=8位(1byte=8bit)
1.4.2 C语言数据类型分类
在C语言中,数据类型可以分为:基本数据类型、构造数据类型以及空类型。
基本数据类型:整型int(短整型{关键字:short}、长整型{关键字:long})、浮点型(单精度浮点型{关键字:float}、双精度浮点型{关键字:double})、字符型({关键字:char})
构造数据类型:数组、结构体、共用体、枚举、指针;
空类型:void ->(万能型指针:void*p)
整型
整型数据类型概述
整型数据是指不包含小数部分的数值型数据(例如:123、-123、567),整型数据类型使用关键字“int”来表示。C语言规定了一个“int”整型数据至少占用2个字节的空间大小,通常占用4个字节的空间。(8位16位单片机int 占2字节大小,对于32位单片机或者PC4字节空间 后期工作中在51单片机中:int数值范围)
整型数据类型分类
整型数据根据是否支持符号(正负号)形式分为:有符号类型(signed)和无符号类型(unsigned),缺省表示为有符号类型(int 等价于 signed int)。
有符号类型:关键字signed int==等价于signed int
无符号类型:关键字unsigned
有符号类型---32位为例(4字节为例)
有符号类型的整型数据使用最高位来表示符号为(0:正、1:负),其余31位用来表示数据。数据的取值范围是:-231~+231-1。(需要了解数值范围: -2,147,483,648--- 2,147,483,647 记忆:21亿)为什么记忆相关的数值范围:
Int A =0; A++; if(A > 22亿)永远不成立;
记忆范围对于将来设定条件是非常有必要的;
原码反码补码:8位数据 最高位为符号位 其余7位为数据位; 2^7=128 -128 -0 补码 0—127 -1—128(-0) |
无符号类型
无符号类型的整型数据只能表示正整数,所有32位都用来表示数据。数据的取值范围是:0~232-1。(0- 4,294,967,296 42亿)
思考题:如果数值超出了取值范围,会出现什么情况(无符号最大值为4294967295,如果存入的数值为4294967296,那结果会怎么样?)
#include <stdio.h> int main() { unsigned int num = 4294967298; //2 printf("%u\n",num); return 0; } |
unsigned int num_1 = 4294967296; /* 无符号整型数值范围 0~4294967295*/ unsigned int num_2 = -1; /* 无符号整型数值范围 0~4294967295*/ int num_3 = 2147483650; /* 有符号整型数值范围-2147483648~2147483647*/ int num_4 = -2147483651; /* 有符号整型数值范围-2147483648~2147483647*/ printf(“%u\n”,num_1); 打印出的数值为:0 归位溢出:4294967296(当前数值)> 4294967295(最大值),从范围(0~4294967295)最大值超出需要从范围最小值0开始, 4294967296====0; printf(“%u\n”,num_2); 打印出的数值为: 4294967295 归位溢出:-1(当前值)<0(范围最小值),从范围(0~4294967295)最小值超出,需要从最大值4294967295开始,-1=======4294967295; printf(“%d\n”,num_3); 打印出的数值为: -2147483646 归位溢出: 2147483650(当前值)> 2147483647(范围最大值),从范围(-2147483648~2147483647)最大值超过,需要从最小值-2147483648开始,2147483650====== -2147483646 printf(“%d\n”,num_4); 打印出的数值为: 2147483645 |
注:C语言中的整型数据类型默认为有符号类型,所以“signed”可以省略,直接使用“int”来表示,但如果需要表示为无符号类型,必须写“unsigned”。并且计算机的溢出属于归位溢出,一旦出现溢出情况,那么计算机会从最值(最小值或最大值)开始重新计算。超出多少位 从最值开始数几位显示(4294967296超出1位,从最小值数一位即0)
- 其他整型数据类型
- 短整型
短整型数据类型使用关键字“short”来表示,C语言中规定了短整型占2个字节大小的空间,同样短整型也分为“有符号短整型(short/signed short,数据的取值范围是:-215~+215-1)数值范围(-32768~32767)”和“无符号短整型(unsigned short,数据的取值范围是:0~216-1)数值范围(0~65535)”。
- 长整型
长整型数据类型使用关键字“long”来表示,C语言中规定了长整型占4个字节大小的空间,同样长整型也分为“有符号长整型(long/signed long,数据的取值范围是:-231~+231-1)(数值范围: -2,147,483,648--- 2,147,483,647)”和“无符号长整型(unsigned long,数据的取值范围是:0~232-1)(数值范围: 0~4294967295)”。
- 长长整型
长整型数据类型使用关键字“long long”来表示,C语言中规定了长长整型占8个字节大小的空间,同样长长整型也分为“有符号长长整型(longlong/signed longlong,数据的取值范围是:-263~+263-1)”和“无符号长长整型(unsigned longlong,数据的取值范围是:0~264-1)”。但需要注意,长长整型数据类型只有在C语言的C99标准中存在,在C89标准中是不存在的。 C语言协议标准C11 C99 C89
定义您购买苹果的数目:int/long/short a=100;
但是在后期单片机开发/操作系统开发中:考虑内存使用(如何节省内容,通过合理的数据类型达到节省内存的第一步);
建议咱们同学后期定义变量时数据类型分配要合理;
- 浮点型
- 浮点型数据类型概述
浮点型数据类型也称为“实型数据类型”,来用存储带有小数点的数据(必须有小数点),例如:-12.0、23.456、25.。浮点型数据中不区分“有符号”和“无符号”,固定为“有符号”类型(数据的最高位为符号位)。
注意点:浮点型数据中不区分”有符号”和”无符号”;固定为有符号类型;
- 浮点型数据类型
浮点型数据类型根据小数点的精确位数,分为“单精度浮点型”和“双精度浮点型”。
单精度浮点型
单精度浮点型使用关键字“float”来表示,C语言中规定“float”占4个字节的大小空间,小数点至少精确到小数点后的7位左右。
双精度浮点型
双精度浮点型使用关键字“double”来表示,C语言中规定“double”占8个字节的大小空间,小数点至少精确到小数点后的16位左右。
验证小数点后7位左右/16位左右:
字符型
字符型数据类型概述
字符型数据使用关键字“char”来表示。字符型数据是在存储空间中通过存储一个特定的整数来表示一个特定的字符(整数和字符之间是一一对应的,通过“ASCII码表”进行转换)。
字符型数据意义
存放整数
C语言中规定“char”占1个字节空间大小,字符型同样分“有符号(char/signed char,数据的取值范围是:-27~+27-1)”和“无符号(unsigned char,数据的取值范围是:0~28-1)”。
有符号的数据的取值范围: -27~+27-1 -128~+127
无符号的数据取值范围:0~28-1 0-255
存放字符
C语言中字符分为两类,一类为打印字符(可见字符,普通字符),使用单引号(’’)括起来,例如:‘a’、‘1’;另一类为控制字符(不可见字符,转义字符),使用反斜杠(\)+字符来表示。例如:\n(换行)、\r(回车)、\b(退格)、\t(tab)、\0(字符串结束标志位)。
#include <stdio.h> int main() { printf("%d\t%d\t%d\t\n",1,2,3); char buff[]="he\0llo"; printf("%s\n",buff); return 0; } |
注:字符型属于两种表示方法,可以表示一个整数,也可以表示一个字符,字符使用的原则是:只要在程序中,凡是看到字符,其实就是一个整数,当整数来使用。
1.4.3 关键字“sizeof”
sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。
sizeof主要是计算数据类型所占用的字节空间大小。
sizeof(基本数据类型、变量名);
#include <stdio.h> int main() { int A =10; float B; double C; short D; long E; printf("int:%u A:%u\n",sizeof(int),sizeof(A)); printf("float:%u B:%u\n",sizeof(float),sizeof(B)); printf("double:%u C:%u\n",sizeof(double),sizeof(C)); printf("short:%u D:%u\n",sizeof(short),sizeof(D)); printf("long:%u E:%u\n",sizeof(long),sizeof(E)); return 0; } |
1.5 课程回顾
1.原码 反码 补码
2.进制转换 十进制转为二进制/八进制/十六进制
3.数据类型:基本数据类型整型(短整型short 长整型 long 整型 int) 浮点型(单精度浮点型float 双精度浮点型 double) 单精度浮点型,精确到小数点后7位左右(不同编译器精确位数有所差异:浮点型float {符号位0正 1负 小数部分.314159 指数部分 10^1=3.14159} 浮点型没有有符号和无符号之分,固定为有符号)双精度浮点型 double:精确到小数点后16位左右;
字符型:ASCII表:0-31控制字符 32-127打印字符(可见字符)
控制字符:\t横向制表 1\t2\t3\t4\n 1 TAB键 2 TAB键 3 TAB键 4
\n换行符: printf(“hello C\n”);
\0字符串结束标志 hello\n he\0llo\n
关键字占用空间大小(字节数):sizeof(类型/变量名);
-
数据常量和数据变量 数据常量
数据常量概述
数据常量是指在程序运行的过程中,其中是不可改变的数据。因为常量的数值不可改变,一般使用一个固定的数值去表示一个常量。例如:12、-78、12.89、‘s’。
printf(“%d\n”,12);
数据常量分类
数据常量分为“数值型常量”和“字符型常量”两种,通过数据的形式可以判断常量的类型,常量的数据类型使用默认类型。
数值型常量
整型常量类型默认为“int(有符号整型)”,浮点型常量默认为“float(单精度浮点型)”。可以通过尾缀的形式改变数值常量的类型,如:12L表示为“long(长整型)”,12ul表示为“无符号长整型”。
字符型常量
- 字符常量:使用单引号(‘’)引起来的单个字符。如:‘a’、‘1’,在存储器中占1个字节的空间。
- 字符串常量:使用双引号(“”)引起来的单个或多个字符。如:“a”、“Hello”,在存储器中占的空间大小为字符串字符个数+1个字节。
字符常量:单一字符,单一字符需要使用单引号;
字符串常量:使用双引号,多个字符或者单一字符,所占空间=字符数目+1(\0);
printf(“%c\n”,’a’); printf(“%s\n”,”hello”); int A = 10; A =20L;
-
-
数据变量
-
数据变量概述
数据变量是指在程序运行的过程中,其值可以改变的数据。因为变量的数值是可以变化的,不是固定不变的,一般使用一个固定的名称(标识符)来表示一个变量。变量在使用前一定要先提前定义。
数据变量组成
数据变量由变量名(标识符)和变量值(常量数值)两部分组成。
Int(数据类型) A(标识符)=100(常量值);
A(标识符)=200(常量值);
变量(标识符)的命名规则
- 变量名组成:可以由字母(严格区分大小写)、数值、下划线以及美元符号($)组成。
- 变量名开头:不能以数字开头。
- 变量重名:不能与关键字重复(重名)。
#include <stdio.h> int main() { //1)变量名组成:可以由字母(严格区分大小写)、数值、下划线以及美元符号($)组成。 //2)变量名开头:不能以数字开头。 //3)变量重名:不能与关键字重复(重名)。 int A; //对 //int 4GCount; //不对 int _4GCount; //对 int $4GCount; //对 //int int; //不对 int a; //不同与A int A_B; //对 int A$B; //对 int _12345678912345678912345678912wertyuidfghkfghjfghjkfghjfghjfghgh3456789;//对 return 0; } |
“匈牙利命名法是一种编程时的命名规范。 其中每一对象的名称都要求有明确含义,可以取对象名字全称或名字的一部分。要基于容易记忆容易理解的原则。保证名字的连贯性是非常重要的。” 全局变量 g_ 常量 m_ 局部变量 l_ 静态变量 s_ 指针 p 函数 f 无效 n 长整型 l 布尔 b 浮点型(有时也指文件)f 双字 dw 字符串 sz 短整型 n 双精度浮点 d 计数 c(通常用cnt) 字符 ch (通常用c) 整型 i(通常用n) 字节 by 字 w 无符号 u 最大Max 最小Min 初始化Init 临时变量T (或Temp) 源对象Src 目的对象Dest g_ nMax |
驼峰命名法:是一种命名规范,广泛用于各种计算机开发场景中。帮助开发人员清晰的命名各个文件。 •大驼峰命名法 •小驼峰命名法 2.使用 这种命名法长得很像骆驼的驼峰,因此叫做驼峰命名法。 驼峰命名法指的是将文件名通过英文命名,除了第一个单词以外,其他单词的第一个首字母都为大写状态。 int nameArray; //小驼峰命名法 nameArray名字数组 存放名字; int NameArray; //大驼峰命名法 NameArray 大驼峰命名法 大驼峰和小驼峰的区别在于,第一个单词的首字母是否大写,如果大写,则为大驼峰命名,反之,为小驼峰。 |
数据变量定义
变量定义的格式:数据类型 变量名;
例如:int age /* 定义了一个整型变量age */
- 数据类型:规定了变量能够保存什么样类型的数据。使用“基本数据类型”、“构造数据类型”以及“空类型”来作为