一、为什么嵌入式开发中选择C语言作为开发语言
1.C语言的特点
①C语言具有出色的可移植性,能够在不同体系结构软/硬件平台上运行,所谓移植性好,就是当程序应用于不同的平台时,需要修改的源码少
②C语言具有简练紧凑,使用灵活的语法机制,并且能直接访问硬件
③C语言具有很高的运行效率
2.C语言与汇编语言的选择
①C语言是高级语言,能实现一些复杂的功能,主要用于对硬件实施复杂操作
②汇编是低级语言,主要用于对简单硬件的初始化
3.C语言和解释性语言的选择
解释性语言例如Java,它们都需要通过中间软件实现解释,运行效率低,但解释性语言能适用于多种平台
二、面向过程处理机制(C)和面向对象处理机制(C++)
1.从处理对象来看:面向过程的处理机制解决的是具体事物,注重的是解决问题的过程;而面向对象的处理机制处理的是宏观事物,注重的是解决问题的结果
2.从特性来看:面向过程的处理机制可以直接访问硬件,可移植性号,执行效率高;而面向对象的处理机制代码具有很好的复用性,维护性,扩展性
三、C语言的标准
1.C语言之父,也是Unix之父:丹尼斯·里奇
2.C语言的标准
①K&R C
1978年,丹尼斯•里奇(Dennis Ritchie)和布莱恩•柯林汉(Brian Kernighan)合作出版了《C程序设计语言》的第一版。书中介绍的C语言标准也被C语言程式设计师称作“K&R C”K&R C主要介绍了以下特色:
结构(struct)类型
长整数(long int)类型
无符号整数(unsigned int)类型
把运算符=+和=-改为+=和-=。因为=+和=-会使得编译器不知道使用者要处理i = -10还是i =- 10,使得处理上产生混淆。
②ANSI C和ISO C
C 的第一个标准是由ANSI发布的。ANSI C现在被几乎所有广泛使用的编译器支持。现在多数C代码是在ANSI C基础上写的。
③C89和C90
1983年,美国国家标准协会组成了一个委员会,X3J11,为了创立 C 的一套标准。经过漫长而艰苦的过程,该标准于1989年完成,并在作为ANSI X3.159-1989 “Programming Language C”正式生效。这个版本的语言经常被称作”ANSI C”,或有时称为”C89”(为了区别C99)。 在1990年,ANSI C标准(带有一些小改动)被美国国家标准协会采纳为ISO/IEC 9899:1990。这个版本有时候称为C90或者ISO C。因此,C89和C90通常指同一种语言。 传统C语言到ANSI/ISO标准C语言的改进包括:
增加了真正的标准库
新的预处理命令与特性
函数原型允许在函数申明中指定参数类型
一些新的关键字,包括 const、volatile 与 signed 宽字符、宽字符串与字节多字符
对约定规则、声明和类型检查的许多小改动与澄清
④C99
2000年3月,ANSI 采纳了 ISO/IEC 9899:1999 标准。这个标准通常指C99。 C99新增了一些特性,如:
支持不定长的数组,即数组长度可以在运行时决定。
变量声明不必放在语句块的开头,for 语句提倡写成 for(int i=0;i<100;++i) 的形式,即i 只在 for 语句块内部有效。
初始化结构的时候允许对特定的元素赋值。
允许编译器化简非常数的表达式。
取消了函数返回类型默认为 int 的规定。
但是各个公司对C99的支持所表现出来的兴趣不同。当GCC和其它一些商业编译器支持C99的大部分特性的时候,微软和Borland却似乎对此不感兴趣,他们把更多的精力放在了C++上。
⑤C11
在2011年12月,ANSI 采纳了 ISO/IEC 9899:2011 标准。这个标准通常即C11,它是C程序语言的最新标准
3.gcc支持的C语言标准
gcc默认是不支持c99及以上版本的
如果想支持,需要在编译时加参数:-std=c99 gcc -std=c99 -o xx xx.c
或者在源码里定义宏
define STDC_VERSION 199901L
不同的编译器支持不同的标准
四、数据类型
1.什么是数据类型?
数据是集合的划分,不同数据类型对CPU的意义不一样
2.左右法则:先找到变量字母,再看右边,后看左边,反复
int a;//整型变量
int *a; //整型指针变量
int **a; //整型指针的指针变量
int a[10]; //整型数组
int *a[10];//整型指针数组
int (*a)[10];//整型数组指针变量
int (*a)(int);//形参为int,返回值为int的函数指针变量
int (*a[10])(int);//函数指针数组,数组的元素指向形参为int,返回值为int的函数
int * ( * ( * fp1 ) ( int ) ) [10];
解释:fp1是一个函数指针变量,该函数指针指向一个形参为int,返回值为指针数组的函数,数组的元素指向整型指针数组
int * ( ( arr[5] ) ( ) ) ( );
解释:arr是一个函数指针数组,该数组的元素指向一个形参为空,返回值为函数指针的函数,该函数指针指向一个形参为空,返回值为整型指针的函数
float ( * ( * b ( ) ) [ ] ) ( );
解释:b是一个函数,形参为空,返回值为函数数组指针,该数组指针指向函数指针数组,该数组元素指向一个形参为空,返回值为float型的函数
void * ( * c) ( char , int ( * ) ( ) );
解释:c是一个函数指针变量,该函数指针指向一个形参1为char,形参2为形参为空,返回值为int的函数指针,返回值为void* 型的函数
void * * ( * d) ( int a,char * * ( * b) ( char , char *) );
解释:d是函数指针变量,该函数指针指向形参1为int型,形参2 为函数指针变量(该函数指针指向形参1为char * ,形参2为char * * ,返回值为char * * 型的函数),返回值为void**型
float ( * ( * e[10] (int * ) ) [5];
解释:e是函数指针数组,该数组元素指向一个形参为整型指针,返回值为float型数组指针的函数
3.强制类型转化
char →int→float→double
沿箭头方向的转化是隐式类型转化,由编译器本身自动进行
4.字节长度
bit
字节 = 8 bit ☆
半字 = 2 个字节 = 16 bit
字 = 4 个字节 = 32 bit
通常我们所说的所占空间的大小都以字节来衡量
5.sizeof 不是函数,是运算符
书写格式 sizeof (num) = sizeof num //测变量名有两种写法
sizeof (int) //测数据类型只能加括号
注意:使用的时候sizeof 与括号之间应该加空格
数据类型 字节长度
char 1
short 2
long 4
int 4
float 4
double 8
long long 8
注:任何类型的指针的长度都是4,因为指针用来保存地址,操作系统中地址长度固定,32为操作系统的地址长度为4,而64为操作系统的地址长度为8
6.有符号与无符号(signed & unsigned)
* 计算机中的数据都是以补码表示的
正数: 原码 = 补码
负数:取绝对值的原码取反加一(已知负数的补码,有数值部分取反加一,得到原码)
*计算机中常量都是有符号的
例:
输出~2的十进制表示,即对2按位取反,输出十进制的值
2 的原码 0000 0010
~2的补码1111 1101
符号位为1是负数,以补码保存
数值位111 1101 取反加一 000 0011(十进制3)
所以~2的十进制表示为-3
7.越界
*char类型的数据 能表示的范围,有符号 -128 ~127 ,无符号 0 ~255
*typedef 用来解决有符号数据和无符号数据的可移植问题
*有符号数和无符号数进行比较的时候,有符号数变成无符号数进行比较
*越界问题
例1
signed char ch = -128;
ch = ch - 1;
printf(“ch = %d\n”,ch);
输出结果是ch = 127
过程:
-128 补码:1000 0000
-1补码:1111 1111
所以结果是0111 1111 即十进制的127
如果是unsigned char ch = 0 ;输出结果就是ch = 255 计算方法是一样的
例2
signed char ch = -128;
printf(“ch = %d\n”,ch - 1);
输出结果为 ch = -129
注:例1是执行了赋值操作,所以存在越界的问题,而例2仅仅是计算表达式的值,存在迷惑性
7.sizeof & strlen
首先,这两个从本质上来讲,sizeof是运算符,而strlen 是函数;其次在计算值时sizeof是计算空间的大小,不需要考虑里面的值时多少,而strlen在计算字符串的长度时,遇到\0就截止,且不计算\0
例:
char *ptr = “hello world”;
sizeof (ptr) 4 //测的是指针的长度
strlen(ptr) 11 //测量字符串的长度,遇到\0截止
char ptr[100] = “hello world”;
sizeof(ptr) 100 //测量字符数组的空间长度
strlen(ptr) 11 //测量字符串的程度,遇到\0截止
char ptr[ ] = “hello world”;
sizeof(ptr) 12 //系统自动根据字符串的大小分配空间,且包含\0在内
strlen(ptr) 11 //测量字符串的长度,遇到\0停止
8.变量的三大特点
①变量的数据类型:说明变量占用空间大小
②变量的作用域:变量的有效范围,即变量的使用范围
③变量的存储区域:变量的存储方式
9.进程:当系统在执行一个程序是被称为一个进程
进程的虚拟地址空间:进程的活动范围,操作系统为每个进程抽象出4g的虚拟空间
MMU内存管理单元:作用是将虚拟内存空间映射到物理内存
printf打印一个空间地址时,打印的是虚拟内存的地址
虚拟内存解决了系统内存空间资源稀缺的问题
☆4g虚拟内存的划分示意图
10.局部变量和全局变量的区别
①从变量的存储区域来看:局部变量存在虚拟内存的栈空间,而全局变量存在虚拟内存的堆空间
②从初始化来看:局部变量不初始化时默认为任意值,而全局变量不初始化时默认为0
③从变量的作用域来看:局部变量在所在函数使用完后立即释放,而全局变量在所有程序执行完最后释放
11.声明与定义的区别
①声明可以有多次,但定义只能有一次
②先声明,后定义,是语言的规范要求
③声明不占用内存空间,而定义占用内存空间