嵌入式培训C语言笔记简单版
Linux指令
Linux指令 |
|
终端放大: ctrl+shift+”+” |
|
终端缩小: ctrl+”-” |
|
切换超级用户#: sudo -s |
|
切回普通用户$:su 用户名 |
|
pwd |
:显示绝对路径 |
绝对路径:从根目录开始 相对路径:相对用户当前文件夹所在路径 |
|
/:根目录 ~:家目录 |
|
cd |
:跳转路径命令 |
cd /:跳转到根目录 |
|
cd ~:跳转到家目录 |
|
cd ./aaa/:跳转到aaa目录 |
|
cd ../:跳至上一级目录 |
|
cd -:跳至上一回 |
|
mkdir 文件夹名 |
:创建文件夹(多个用空格隔开) |
touch 文件名 |
:创建文件(多个用空格隔开) |
rm |
:删除文件 |
rm 1*.c (删除1*文件) |
|
rm -r 目录名 (-r可放在目录名前或后) |
|
cp |
:复制 |
cp ./1.c ./111/main.c(1.c文件复制到111文件夹下并改名为main.c) |
|
mv |
:剪切 |
mv ./1.c ./name/(1.c文件剪切到name文件夹下) |
数据类型
数据类型 |
||
*.c |
源文件 |
|
*.h |
头文件 |
|
头文件:存放被调用的功能函数的声明。 头文件不会被编译执行,只能预处理(#) |
||
创建源文件 |
①touch 文件名 ②gedit main.c & |
|
编译 |
gcc main.c -o main.out ./main.o |
|
进制转换 |
||
十进制 |
D/d |
0~9 |
八进制 |
012/056 |
数字前面加0,0~7 |
二进制 |
B/b |
1010B/b1010 |
十六进制 |
0X/0x |
0x12/0X12/12h/12H |
小数二进制转换 |
||
0.125->0.001B |
0.78->0.110001...B |
|
0.125*2=0.25——0 0.25*2=0.5——0 0.5*2=1.0——1 |
0.78*2=1.56——1 0.56*2=1.12——2 0.12*2=0.24——0 0.24*2=0.48——0 0.48*2=0.96——0 0.96*2=1.92——1 ... |
|
小数点后保留n位二进制数, 就乘2^n次方 |
0.125*2^3 =1D->001B 0.78*2^6=49.92D->0011 1001B |
|
数据类型分类 |
||
基本数据类型 |
整型,浮点型(实型),字符型 |
|
构造数据类型 |
数组,指针,结构体 |
|
空类型 |
void |
|
整型 |
||
int 4字节 不能用%c输出 signed int/int 有符号整型 -2^31~2^31-1 unsigned int 无符号整型 0~2^32-1 |
||
短整型 short int |
short 2字节 signed short/short -2^15~2^15-1 unsigned short 0~2^16-1 |
|
长整型 long int |
long 4 字节 signed long/long -2^31~2^31-1 unsigned long 0~2^32-1 |
|
浮点型(实型)固定为有符号 |
单精度浮点型 float 4字节 小数点后精度 6~7位 |
|
双精度浮点型 double 8字节 小数点后精度 16~17位 |
||
字符数据类型 char |
||
ASCII |
‘\0’---0 空格---32 0---48 A---65 a---97 |
|
存放整数 |
char 1字节 signed char/char -2^7~2^7-1 unsigned char 0~2^8-1 |
|
存放字符 |
普通字符:单引号括起 ‘A’ ‘a’ 控制字符(转义字符,不可见):\+ 字符 \t:将当前位移到下一个Tab \r:将当前位移到本行开头 \n:将当前位移到下一行开头 \f:将当前移到下一页开头 字符型有两种输出方式:字符%c 整数%d |
|
运算符 |
||
运算符 |
本质是一个符号,能够运算的特殊符号 ①单目运算 ②双目运算 ③三目运算 单目运算优先级高于双面运算 |
|
数据常量 |
数值常量:可以通过加尾缀来修改数据类型 如:12---singed int 12U---unsigned int 字符型常量:字符常量&字符串常量 ‘a’ “a”---’a’+’\0’ |
|
数据变量 |
变量数据类型 变量名称(标识符)= 变量值 int num = 10; |
|
变量名称: ①只有数组、字母、下划线、$组成 ②不以数组开头 ③不为关键字 |
||
算数运算符 |
+ - * / % |
|
只有相同数据类型的数据才能运算 |
||
浮点型不能求余 |
||
不同数据类型,低精度自动向高精度转换 char-short-int-long-float-double |
||
关系运算符 |
> < >= <= == != |
|
从左到右一次运算 |
||
逻辑运算符 |
&& || ! |
|
&&:全部为真则结果为真,有一个为假则结果为假。 ①&&②&&③:如果①为假则整体为假,后边的常量②or表达式③都不再进行计算与判断 |
||
||:有一个为真则结果为真,全部为假则结果为假。 ①&&②&&③:如果①为真则整体为真,后边的常量②or表达式③都不再进行计算与判断 |
||
算术运算符 高于 关系运算符 高于 逻辑运算符 |
||
符合运算符 |
+= -= *= /= %= <<= >>= &= |= ^= ~= |
|
先计算运算符右边的变量or表达式的值, 然后带入左边进行计算 |
||
自加自减运算符 |
a++:先计算再+1 ++a:先+1再计算 |
|
逗号运算符 |
格式:变量 = (语句1,语句2...语句n); |
|
结果:最后一个变量or表达式的值作为整体表达式的值。 |
||
三目运算 |
格式:条件表达式?表达式1:表达式2 为真:执行表达式1 为假:执行表达式2 |
|
数据类型转换 |
自动转换(隐式类型转换) char-short-int-long-float-double char short 参与运算时,会率先提升为int完成后在返为原类型 |
|
强制类型转换 格式:(需要类型)数据or表达式 |
||
位运算 |
||
运算符 |
& | ^ ~ << >> &= |= ^= |
|
按位与 & 有0为0,全1为1。 |
||
按位或 | 有1为1,全0为0。 |
||
按位异或 ^ 相同为0,不同为1。 |
||
按位左移 << 高位移出,低位补0。 |
||
按位右移 >> 低位移出,高位补0。 |
||
作用 |
对数据的每个二进制位进行运算操作 |
|
清0: n的第i位清0。 n &= ~(1< |
||
置1: n的第i位置1。 n |= (i< |
||
取反: n的第i位取反。 n ^= (1< |
||
原反补 |
||
正数 |
原码 = 反码 = 补码 |
|
负数 |
原码: 最高位位符号位。 反码: 除符号位,每位取反。 补码:除符号位,每位取反,末尾加1。 |
标准输入输出函数
标准输入输出函数 |
|
关键数sizeof |
用于计算数据类型所占字节空间大小 |
sizeof(数据类型or变量名) |
|
子函数:计算的是形参地址所占字节 主函数:变量所占字节数 |
|
printf函数 |
包含”stdio.h” |
%d:以十进制输出 12 %u:以unsigned int输出 %x:以十六进制输出 12 %#x:0x12 %o:以八进制输出 45 %#o:045 %c:以字符格式输出 %s:以字符串格式输出 %ld:long类型输出 %f:以单精度格式输出 %lf:以双精度格式输出 %.nf:输出n个小数位 %nd:%+nd 靠右输出占n位 %-nd 靠左输出占n位 %p:输出变量的地址or指针地址 %%:输出一个%号 |
|
printf(“%s---%d\n”,__FILE__,__LINE__) |
|
getchar():读取上次输入的最后一个字符 |
9条控制语句
9条控制语句 |
|
c的核心为数据与算法 |
数据:数据类型和数值 |
算法:运算符&9条控制语句 |
|
控制语句主要实现控制功能&逻辑功能 |
|
基本语句分类 |
顺序语句:0条,没有关键字 固定执行过程:从上到下,从左到右 |
选择语句:2条 if…else 判断语句 switch…case…break…default 选择语句 |
|
循环语句:3条 for循环,while循环,do…while循环 |
|
跳转语句:4条 break 停止语句,return 返回语句 continue 中止语句,goto跳转语句 |
|
if…else |
条件:非0 |
先计算条件表达式的值,再判断真假 |
|
格式:if(条件表达式1){……} else if(条件表达式2){……} else{……} 条件表达式1:为真,后面不再判断 |
|
if(a=0) 赋值0为假 |
|
switch…case…break…default |
格式:switch(整型表达式) { case 整型常量表达式1:程序1;break; default:程序n;break; } 整型表达式:short int long char 整型常量表达式:必须是常量,唯一性 |
整型表达式:整型常量,整型变量,整型运算符 |
|
如果没有break,以后的case不再判断,直接执行后面的程序语句,直到遇到break停止or整个执行完毕 |
|
while/do…while循环语句 |
只关心结果,不关心次数 |
for循环语句 |
只关心次数,不关心结果 |
格式:for(语句1;语句2;语句3){……} 1.循环变量的初始化 2.循环条件表达式 3.对循环变量进行操作 |
|
过程:根据1且按照2的规则,判断满足就执行循环语句,循环体执行完后,根据3对循环变量进行操作。 |
|
转移语句 |
break:只能结束一层循环(就近原则) |
continue |
|
return语句:放在函数体内,用于结束函数运行,还可以给上一级返回一个数据 |
|
goto:用于让程序无条件转到指定标签位置 格式: 标签名: 程序段… goto 标签名; |
数组
数组 |
|
概述 |
数组就是多个具有相同数据类型(基本,构造)的数据有序的集合 |
据存储方式,分为“一维数组”&“二维数组” 据存储内容,分为“数据数组”、“字符数组”&“字符串数组” |
|
一维数组 |
数组中存储的元素只有一个唯一的下标 |
格式: 数据类型 数组名[数组长度] 数据类型:基本、结构体、指针数据类型 除了数组名以外的内容全是数据类型。 数组长度:必须是一个正整型的常数值 |
|
数组赋值: 未赋值的部分默认为0; 没有赋值的数组,数值时随机的 非初始化时,数组不能直接整体赋值 |
|
求数组能保存的元素个数 |
sizeof(str):求数组所占字节大小 sizeof(syr[0]):求数组的第一个元素所占字节大小 个数 = sizeof(str)/sizeof(str[0]) |
字符型数组 |
字符数组&&字符串数组 |
空格在字符数组&字符串数组中作为一个字符,在数值数组只起到间隔作用 |
|
字符串数组 |
字符串数组的长度为数组中字符的个数+1 |
|
|
字符串不是一种数据类型,字符串必须使用数组||指针来存储 |
|
非初始化赋值方法: scanf(“%s”,变量名); gets(数组名); |
|
二维数组 |
又称数组数组,元素都是数组的数组 |
二维数组赋值: ①只能省略行,不能省略列。 ②可以省略数组每行之间的大括号。 |
|
冒泡算法 |
n个数排序排n-1趟(0,1……n-2) 第一趟排n-1个数(0,1,……,n-1-1) 第二趟排n-2个数(0,1,……,n-2-1) 第n趟排n-(n-1)个数(0) |
for(i=0;i for(j=0; j { if(buff[j] > buff [j+1]) 交换 } |
函数
函数 |
|
概述 |
函数时程序最基本的组成单元 |
是否有自己编写分为: 自定义函数 库函数(API函数、标准库函数、三方函数) |
|
主函数在程序中负责整体调度,一般不参与功能性作用。 子函数主要负责完成功能性任务 |
|
高内聚,低耦合 |
|
字符串标准库函数 |
strlen:返回有效长度 |
strcmp:对比,成功返回0 |
|
strcat:拼接,strcat(A,B)成功返回AB |
|
strcpy:复制,strcpy(空,有)成功返回字符串。 先清空,后复制 |
|
函数三要素 |
函数声明,函数定义,函数调用 |
函数声明 |
格式:函数类型 函数名(形参列表) |
如果函数没有函数类型,程序默认返回为int |
|
函数名为函数的入口地址。 |
|
形参的数据类型不可省略,形参不可直接赋值 |
|
形参:只有数据类型,没有数值。是在函数在声明,定义时使用。 实参:是一个确定的值,不能是随机数,是函数调用时的参数。 |
|
实参数据类型与形参数据类型不一致,实参类型转换为形参数据类型。 |
|
函数应用 |
如果返回值类型与函数类型不一致,则会强制将返回值类型转换为函数类型 |
函数作用范围 |
全局函数:整个工程可见 所有的函数默认extern,可省略不写 局部函数:只能当前源文件.c使用 在函数类型之前加关键字 static |
变量作用范围 |
全局变量:在函数体外面定义的变量, 全局变量初始值为0. 全局变量的作用时间:从函数定义开始,到整个工程结束。 extern int a;//全局变量声明 int a=9;//全局变量定义 在声明外部全局变量的时候,不允许对变量进行赋值。 |
局部变量:函数体内部定义的变量 变量的初始值为随机值。 局部变量的作用时间:从变量定义(函数调用)开始,到所在函数运行结束。 局部变量的作用范围:只在定义的函数内有效。 |
|
静态局部变量:在局部变量的数据类型前加关键字static。 静态变量有着全局的生命周期(作用时间),局部变量的作用范围。 静态局部变量只有第一次定义的时候会赋初始值,之后在调用时直接用上一次的结果。 |
|
全局变量&局部变量重名时,局部变量有效。就近原则。 |
|
局部变量不能使用“extern”来修饰。 |
|
函数递归 |
…… |
内存五大区域 |
|
栈区 |
函数(包括main)内局部变量已经函数的形参的存储空间在栈区创建。 栈区的变量:自动开辟,自动释放。 |
堆区(动态内存分配区) |
程序员使用“malloc”函数申请空间。 使用“free”函数释放,或者工程结束自动释放。 |
全局变量区(全局/静态区) |
主要存放全局变量&&静态变量。 自动开辟,自动释放。 |
常量区(数据存储区) |
程序访问时,只读。 主要存放文字常量。 |
程序代码区 |
存放二进制代码。 |
指针
指针 |
|
变量地址就是该字节空间的首地址。 |
|
指针 |
指针的本质就是地址, 指针只能用来保存地址。 指针是地址构造数据类型,32位系统下指针大小为4位。 |
指针保存地址,内存空间保存数值。 |
|
指针变量 |
指针类型:使用基本数据类型or构造数据类型&&*作为指针类型。 指针类型中的数据类型决定了变量所指向的变量的类型。 |
在定义语句中,*只是用来说明变量为指针变量,没有实际意义。 |
|
指针初始化:没有初始化的局部指针变量为野指针。 使用指针时,NULL为0,指向的为空指针。 |
|
指针变量应用 |
指针变量指向的地址是一个变量, 普通变量的指针是一个常量。 |
普通变量使用运算符进行计算, 指针变量只能使用“+、-、++、--”运算。 |
|
指向数组的指针 |
指针配合下标,指针当作数组形式使用 |
出口参数 |
函数的返回值: ①返回一个数值:可以是局部变量、全局变量、静态局部变量的值。 ②返回一个地址:不能返回局部变量的地址,可以返回静态局部变量、全局变量的地址。 |
void add(int *a, int *b) add(&a, &b);通过形参改变实参,输出函数。 |
|
二级指针 |
指向一级指针的地址 |
int **q=NULL; p=&a:指向a的地址 int *p=NULL; q=&p:指向p的地址 int a=20; q为p的地址 *q为a的地址 **q为a的值 |
|
指针数组 |
本质是一个数组(指针类型的数组) 数组中的每个元素的类型都是指针类 |
char *buff[]={“abc”,”QWER”}; |
|
数组指针 |
本质是个指针(数组类型的指针) |
格式:数据类型 (*变量名)[数组长度] |
|
用于访问二维数组。 |
|
(*p)[2]---第0行第2列 (*(p+i))[2]---第i行第2列 *p[2]---第2行第0列 |
|
[] 与.优先级高于* |
|
指针函数 |
char *fun() |
指针函数的本质是一个函数(函数类型是指针类型)。 函数的返回值是一个指针。 |
|
函数指针 |
本质是个指针。 |
int (*p)(int, int )=NULL; |
|
格式: 返回值类型 (*函数名)(形参) = 初始化内容 |
|
空类型指针 |
void *p |
可以指向任何类型的元素的指针。 |
|
void *v=NULL;int m; v = m; *v---非法间距取值 *(int *)v---间接获取,强制转换。 |
|
函数四要素 |
指针必须有类型,指针类型是声明指向的对象类。 |
指针所指向的数据类型,决定指向地址里数据的类型。 |
|
指针必须有指向,没有指向,则指向空。 |
|
指针本身也占内存空间,指针自身是个变量。 |
结构体
结构体 |
|
结构体 |
是一种构造数据类型,用关键字“struct”。 是相同数据类型or不同数据类型的集合。 结构体中的成员与素组中的元素一样,存储空间是连续的。 |
结构体声明 |
成员变量之间类型可以相同也可以不同。 |
成员可以是基本数据类型、构造数据类型 |
|
结构体最好声明在全局变量位置,让所有的函数都可以直接调用。 |
|
结构体声明必须加; |
|
声明时,成员不能赋值。 |
|
结构体变量定义 |
①结构体声明 |
②使用声明的结构体类型定义结构体变量 格式:“struct 结构体类型名 变量名” |
|
typedef 重定义 |
typedef struct student{……}stu; struct student ----stu ---- 结构体类型名 |
struct student{……}stu;stu---结构体变量 |
|
结构体成员变量访问方式 |
①结构体变量名访问: 结构体变量名.成员变量名 |
②指针访问:指针名->成员变量名 (*指针名).成员变量名 |
|
结构体中“->”来访问结构体指针变量中的数据。 |
|
“.”用于结构体变量。 “->”只适用于结构体指针。 |
|
同类型的结构体变量之间可以直接赋值。 book[i] = book[2]; |
|
结构体嵌套 |
在嵌套结构体数据的成员变量的结构体之前声明。 |
结构体类型大小 |
结构体有效对齐值 |
LINUX下: ①顺序排序,前面已开辟的空间节点数必须是该成员类型所占字节数的整数被,不过则补齐(结构体空洞)。 ②四字节对齐原则,double分为2个四字节,整体空间为4的倍数。 |
|
windows: ①~ ②:整数空间是最大成员类型所占字节的整数倍。 |
|
结构体数组 |
本质是一个数组,数组中元素为结构体类型。 格式:struct 结构体类型 数字名[数组长度] struct BOOK book[5]; |
结构体指针 |
本质是个指针,指针的数据类型为结构体。 格式: struct 结构体类型 *变量名 struct BOOK *p = NULL; |
结构体指针必须有指向,则能用p->id赋值 struct BOOK *p = book; |
|
结构体数组&指针 struct BOOK book[5]; struct BOOK *p = book; |
|
共用体 |
特殊的结构体,关键字“union”。 共用体中的数据成员公用一个内存空间,成员新的赋值会把之前的数据覆盖。 |
共用体的存储空间: windows :最大类型的整数倍。 LINUX:32位下,所占字节为4的倍数。 |
|
大端(小尾):高位低地址(51单片机-8/16) 小端:低位高地址(pc/32位单片机) |
|
枚举 |
本质是一组整型常量,关键字“enum”。 格式:enum 名{枚举常量1,2,……,n} 枚举常量默认从0开始,后面+1。 |
链表
链表 |
|
链表 |
数据结构有顺序存储结构与链式存储结构。 顺序存储结构: 通过相对位置来表示数据之间的关系。 链式存储结构: 有结构体构成,所包含的结构体个数有任意个,但链表在内存中是不连续的(区别于结构体数组,真正释放空间)。 |
链表组成 |
有表头、若干节点、表尾组成。 |
头指针:头节点,只有指针域。 |
|
结构体:相同数据类型与不同数据类型的集合。 |
|
内存动态分配 |
动态申请空间,返回类型位void*类型。 |
void*类型:即可以返回任意类型的地址,在使用是要强制类型转换成对应指针类型地址。 |
|
头文件:#include |
|
malloc(size) |
成功:返回开辟空间首地址 失败:NULL。 |
calloc(n, size) |
n块size字节的空间 成功:返回第一块首地址(空间连续) 失败:NULL |
realloc(p, size) |
申请size字节,把新空间地址给p |
free(p) |
free释放空间,然后释放后地址指向NULL。 |
编译过程
编译过程 |
|
编译过程 |
gcc main.c -o main.out |
xx.c(编译预处理) -> xx.i(编译) -> xx.s(汇编) -> xx.o(链接) -> xx.out |
|
xx.c 初始化c语言程序 xx.i 编译预处理之后的c语言程序 xx.s 汇编文件 xx.o 二进制文件(机器语言---二进制代码) xx.out 最终的二进制文件 |
|
gcc 1.c ------> a.out gcc 1.c -o 1.out ------> 1.out |
|
gcc -E xx.c -o xx.i gcc -S xx.i -o xx.s as xx.s -o xx.o gcc -o xx.out xx.o ./xx.out |
|
宏定义 |
|
不带参数 |
#define PI 3.14 |
带参数 |
#define fun(a, b) a*b fun(2,3+4) ----> 2*3+4 |
#define mul(a, b) ((a)*(b)) mul(2,3+4) ---> 2*(3+4) |
|
条件编译 |
|
#ifdef #ifndef #if #endif |
//存在XX宏定义,则代码生效。 #define XX #ifdef XX 代码 #endif |
//若条件为真,则代码生效。 #if 条件 代码 #endif |
|
//若不存在XX宏定义,则代码生效。 #ifndef XX 代码 #endif |
|
//防止重复定义XX #ifndef XX #define XX 代码 #endif |
|
模块化编程 |
|
C源文件 |
函数定义、变量定义 |
H头文件 |
源文件的接口声明、预编译指令 函数声明、预处理、重定义、结构体定义 |
32个关键字 |
|
类型 |
int short long unsigned signed float double char void sizeof typedef |
控制语句 |
if else switch case break default for while do continue goto return |
其他 |
static extern struct union enum auto register volatile const |
auto |
修饰局部变量,局部变量的默认属性。 int a; ----- auto int a; |
register |
修饰变量,建议编译器把变量优化位寄存器变量。 register int a; |
volatile |
修饰变量,防止变量被编译器优化。 volatile int a; a=1; a=2; a=3; |
const |
修饰变量,该变量只读(常变量)。 |
修饰普通变量: const int a=10; |
|
修饰指针变量: const int *p; ------ int const *p; const 在*前修饰*p,不可修改指向的内容,可以重新指向。 const 在*之后修饰p,p可以修改指向空间的内容,p不可再另外指向。 |
//个人总结,内容有所精减。想了解详细资料可以私信。
//若有错误,敬请原谅!
//C语言学习结束,下阶段学习单片机。