一、基本数据类型
基本类型:又称非构造性数据类型,其构造简单,是由系统事先定义好的。
构造类型:又称复杂数据类型,一般由程序员将其它数据类型(包括构造类型本身)按一定的规则构造而成。
指针类型:指针变量中只能存放地址(指针)。主要用于解决动态数据的建立、删除和使用。
空类型: 主要用于数据类型的转换和定义函数的类型。
C程序中的数据类型有常量和变量之分,分别属于以上这些数据类型。在程序中用到的所有数据都必须先定义后使用。
类型标识符 名字 取值范围
char 字符型 ASCII字符代码
unsigned char 无符号字符型 0至255
signed char 有符号字符型 -27 ~ 27-1
int 整型 -231~ 231-1
unsigned int 无符号整型 0 ~ 232-1
signed int 有符号整型 同int
float 浮点 10-38~1038
double 双精度型 10-308~10308
二、移植性:
在嵌入式开发中,考虑到代码的移植性,对于有符号(signed)与无符号(unsigned)一定要留心系统默认的是无符号还是有符号;
为了解决此问题,通常使用typedef来重新指定声明无符号还是有符号;
Typedef int sig_int;
Typedef unsigned int un_int;
三、
printf( )函数
功能:向终端输出若干个任意指定类型的数据
格式:printf(“格式控制”,参数表列);
scanf( )函数
功能:等待用户从键盘上输入数据,然后按格式控制的要求对数据进行转换后送到相应的变量地址中去
格式:scanf(“格式控制”,地址表列);
注意:数据输入过程中产生的垃圾的处理方法!!
%s:用来输入字符串,将字符串送到一个字符数组中,在输入时以非空白字符开始,以第一个空白字符结束。字符串以串结束标志’\0’作为最后一个字符。
%*:表示本输入项在读入后不赋给相应的变量(赋值抑制符)
四、定义与声明
定义:创建一个变量,为其分配内存空间,并为它取名字(变量名),一个变量只能定义一次;变量是对程序中数据的存储空间的抽象
声明:告知编译器,这个名字(变量名)已经匹配在一块内存上了,但是并未为其分配内存;
五、变量的存储类型(C的存储类别有四种:auto、static、register和extern)
存储空间的划分
程序区:用于存放程序编译后形成的可执行代码(执行时装入)
静态存储区:用于存放程序中的静态数据,如全局变量等
动态存储区:用于存放程序中的动态数据,如函数形参、局部变量、函数调用时的现场保护和返回地址等
静态数据: 说明在静态存储区中分配存储单元并在程序执行过程中始终占用该单元,直到程序结束才释放;如:全局变量、局部静态变量
动态数据: 在函数开始执行时分配动态存储空间,函数结束时释放这些空间。如:形参变量、局部动态变量(auto register)、函数调用现场保护和返回地址等
六、进程空间的划分
每个进程运行所需的空间称为进程的虚拟地址空间。32位操作系统中该空间大小为4G(2^32)。分配方法一在硬盘上开辟虚拟内存空间,二采用软件实现(写时复制),在内存中给每个进程映射。1G=2 ^30
七、关键字
1、register:请求编译器尽可能地将变量存在CPU内部寄存器中;
使用注意:
register修饰变量的类型必须是CPU所接受的;
register变量可能不是在内存中存储,所以不能使用&来获取变量的地址
2、static
全局静态变量:作用范围局限于它的源文件,即只有本文件内的代码才可以访问它,变量名在其他文件内不可见
局部静态变量:局限于特定函数,但出作用域并不释放,在函数体内的静态变量的值也能够维持
静态函数:作用范围仅限于它的源文件,即只有本文件内才能够调用,函数名在其他文件不可见
存放位置:程序开始时,存放在全局数据区,结束时释放空间,默认初始化值是0,使用时可改变其值;
3、const
const int *a; int const *a;
是一个指向const int型的指针,a所指向的内存单元不可改写,所以(a)++是不允许的,但a可以改写,所以a++是允许的。
int const a;
a是一个指向int型的const指针,a是可以改写的,但a不允许改写。
int const * const a;
a是一个指向const int型的const指针,因此a和a都不允许改写
const给读代码的人传达非常有用的信息。比如一个函数的参数是const char *,你在调用这个函数时就可以放心地传给它char *或const char *指针,而不必担心指针所指的内存单元被改写
尽可能多地使用const限定符,把不该变的都声明成只读,这样可以依靠编译器检查程序中的Bug,防止意外改写数据。
const对编译器优化是一个有用的提示,编译器也许会把const变量优化成常量
4、extern:表明变量或函数的定义在别的文件中,下面用到的这些变量或是函数是外来的,不是本文件定义的,提示编译器遇到此变量或函数时,在其他模块中寻找定义;
如果一个函数只能被本文件中其它函数所调用,称为内部函数(或静态函数)。定义时在函数类型前加static。
5、struct:在网络协议、通信控制、嵌入式系统的C/C++编程中,我们经常要传送的不是简单的字节流(char型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体
“结构体名”用作结构体类型的标志;
花括弧内是该结构体中的各个成员,由它们组成一个结构体;在结构体内对各成员都应进行类型声明;
“成员表列”也称为域表。每个成员也称为结构体中的一个域,成员名命名规则与变量名一样;
每个成员名前的类型标识符可以为已经定义了的任意类型,当然可以是结构体类型标识符,即结构体成员也可以是另一个结构体变量。
此处只是构造出一个新的类型,并没有定义该类型的变量,因此在内存中并没有开辟任何存储空间;
在程序中可以定义多个结构体类型,不同结构体类型用不同的结构体名来区分。
①引用形式:结构体变量名. 成员名
“.”是成员运算符,在所有的运算符中优先级最高。
②不能将一个结构体变量作为一个整体进体输入输出,只能对结构体中的各个成员分别进行输入输出。
③不能用指向结构体变量的指针指向该结构体变量的某个成员。
④访问结构体成员变量的三种方法:
stu.num、stu.name、stu.score
(*p).num、(*p).name、(p).score
p->num、p->name、p->score
“->”为指向运算符,是优先级最高的运算符;
成员运算符“.”的优先级高于指针运算符“”,因此采用 “(*p).成员名” 形式时,括号不能省略;
在定义结构体变量的同时,可以进行初始化
结构体变量的各个初值用花括号{ }括起来,大括号内各个成员变量的值之间用逗号分隔,其值必须与成员变量一一对应,且数据类型应与成员变量一致。
6、union:当多个基本数据类型或复合数据结构要占用同一片内存时,我们要使用联合体;
当多种类型,多个对象,多个事物只取其一时(我们姑且通俗地称其为“n 选1”),我们也可以使用联合体来发挥其长处;可以把一个整型变量、一个字符型变量、一个实型变量放在同一个地址开始的内存单元中。即使几个不同的变量共占同一段内存空间。
所谓“共用体(union)”是指使几个不同的变量共占同一段内存的数据类型。
7、typedef是C语言的关键字,其作用是为一种数据类型定义一个新名字
格式:typedef 数据类型 自定义数据类型
typedef unsigned long uint32;
在嵌入式的开发中,由于涉及到移植问题,typedef的功能就更引人注目了
8、define
定义常量与命令(避免幻数)
#define MAX 100
#define SIZE 1024
#define LOGIN_SUCCESS 1
#define LOGIN_FAIL 0
注意:在宏定义的命名时,尽量能够清晰的表明其用途;
八、位运算及其运算符
1.按位与──&
(1)格式:x&y
(2)规则:对应位均为1时才为1,否则为0 :3&9=1
(3)主要用途:取(或保留)1个数的某(些)位,其余各位置0。
2.按位或──|
(1)格式:x|y
(2)规则:对应位均为0时才为0,否则为1:3|9=11
(3)主要用途:将1个数的某(些)位置1,其余各位不变。
3.按位异或──^
(1)格式:x^y
(2)规则:对应位相同时为0,不同时为1:3^9=10
(3)主要用途:使1个数的某(些)位翻转(即原来为1的位变为0,为0的变为1),其余各位不变。
4.按位取反──~
(1)格式:~x
(2)规则:各位翻转,即原来为1的位变成0,原来为0的位变成1:在IBM-PC机中,0=0xffff,9=0xfff6。
(3)主要用途:间接地构造一个数,以增强程序的可移植性。
5.按位左移──<<
(1)格式:x<< 位数
(2)规则:使操作数的各位左移,低位补0,高位溢出:5<<2=20。
(3)实现&、|、^运算主要用途的方法
1)构造1个整数:该数在要取(或保留)的位、或要置1的位、或要翻转的位上为1,其余均为0。
2)进行按位与、或按位或、或按位异或操作。
(4)实现按位取反主要用途的方法
1)求~0,间接地构造一个全1的数;
2)按需要进行左移或右移操作,构造出所需要的数。
6.复合赋值运算符
除按位取反运算外,其余5个位运算符均可与赋值运算符一起,构成复合赋值运算符: &=、|+、^=、<<=、>>=
7.不同长度数据间的位运算──低字节对齐,短数的高字节按最高位补位:
(1)对无符号数和有符号中的正数,补0;
(2)有符号数中的负数,补1。