1. 基本数据类型
1.1 整型家族
1.1.1 整型变量
整形包括短整型(short int),整形(int),长整型(long int),他们都有有无符号这一说法(signed unsigned)。
类型 | 比特数 | sizeof() |
[signed] int | 32 | 4 |
unsigned int | 32 | 4 |
[signed] short [int] | 16 | 2 |
unsigned short [int] | 16 | 2 |
long int | 32 | 4 |
long int | 32 | 4 |
1.1.2 整型常量
八进制数,十进制数,十六进制数。八进制以0开头,十六进制以0x开头。整型常量后加上”L“或”l“,代表长整型,整型常量后加上”U“或”u“,代表无符号整型。
1.2 实型家族
1.2.1 实型变量
实型变量分别是单精度(float),双精度(double),长双精度(long double)三种。
类型 | 比特位 | sizeof() | 有效位数 |
float | 32 | 4 | 6~7(一般是⑦) |
double | 64 | 8 | 15~16(一般是16) |
long double | 64 | 8 | 18~19 |
注:这里的有效位数是总的位数,包括整数部分的位数的全部位数。
1.2.2 实型常量
形式 | 表示方法 | 举例 |
十进制表示 | 有数码0~9和小数点组成 | 0.0 330. |
指数形式 | <尾数> E(e) <整形指数> | 3.0E5 -4.956E-20 |
注:float表示一个很小的数,超过范围就是表示不准,一般就以输出%e的方法输出对应的科学计数法表示方法,用实数的指数形式表示。
1.3 字符串家族
1.3.1 字符变量
字符变量也可以看作是整型变量的一种,也分有无符号这一说,当它存储字符常量时,其实是将字符的ASCII码存储到内存单元中。
类型 | 比特数 | sizeof() |
[signed] char | 8 | 1 |
unsigned char | 8 | 1 |
1.3.2 字符常量
单个引号引起来的单个字符,例如'a','5','?',当'5'这种情况出现时,不能直接参与运算,而是会以他的ASCII码值相加减,比如'0'-0=48。字符和对应的数字相差48,数字零的ASCII为48。
除此之外,还有一种常量——转移字符。转义字符以反斜线“\”开头,后接一个或几个字符,有其特定的意义,对应也有其ASCII码。
字符形式 | 含义 | 对应ASCII值 |
\n | 回车换行 | 10 |
\t | 水平跳到下一制表位置(补空格,tab的效果) | 9 |
\r | 回车,将当前位置移到本行开头(覆盖早先) | 13 |
\\ | 反斜线符“\” | 92 |
\' | 单引号符 | 39 |
\b | 向前退一格 | 8 |
1.4 枚举家族
注:枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能在分解为任何的基本类型。
枚举类型定义的一般形式如下:
enum 枚举名{
枚举值表
};
enum DAY{MON=1,TUE,WED, THU, FRI, SAT, SUN};
注意:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推
单独使用switch的时候,会根据你输入的那个数字或字母进行处理,比如switch(a),case 1:(case 'a':)。
1.5指针家族
1.5.1 指针的概念
内存单元的指针(地址)和内存单元的内容(具体存放的变量)是两个不同的概念。
1.5.2 指针常量
NULL。只有唯一的一个NULL,空地址。
1.5.3 字符串常量
双引号引起来的量,双引号引起来的不能是双引号(”“)和反斜杠(\n)。在c语言中,字符串常量在存储时系统会自动在尾部加一个”串结束标准“,即”\n“。字符’A‘占一个字节,字符串”A“占两个字节。
2. 变量与常量
2.1 变量的定义
基本类型 | 关键字 |
整型 | unsigned int,short,long |
浮点型 | float,double |
字符型 | unsigned char |
枚举类型 | enum |
指针类型 | 数据类型 * |
2.2 typedef
为一个数据类型定义一个新名字。
typedef 数据类型 自定义数据类型
typedef unsigned long uint32;
uint32 a; 等价于unsigned long a;
2.3 常量的定义
2.3.1 const定义常量
const int *a;
int * const a;
在第一条语句中,const用来修饰指针a所指向的对象,也就是我们无法通过指针a来修改其指向的对象的值。但是a这个指针本身的值(地址)是可以改变的,也就是a这个指针是可以指向其他对象的。(a=&N)改变其地址。
第二条相反。(*a=N)修改地址对应的值。
注:在定义的时候就应该声明其值。不然会报错。
2.3.2 define定义常量
#define 符号名 替换列表
#define MSG "I'm Antigloss!" (引号也加入在内)
#define SUM 99
2.4 作用域
2.4.1 函数原型作用域
始于“(”,结束于“)”。
2.4.2 局部变量
在函数内部定义的变量称为局部变量。局部变量只能在模块内访问使用。局部变量在进入模块时生成(压入堆栈),在退出模块时消亡(弹出堆栈)。
2.4.3 全局变量
[extern]类型说明符 变量名,变量名
例如:int a,b;
等效于:extern int a,b;
- 全局变量在定义时就已经分配内单元了
- 全局变量定义必须在所有函数外,且只能定义一次。
- 一般不使用全局变量,虽然全局变量可以加强函数模块之间的数据联系,但又使函数要依赖这些变量,独立性就会降低。所以经量不使用全局。
- 全局变量在程序执行过程中都要占用存储空间,而不是仅在需要时才开辟存储空间。
- 在同一个源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量不起作用。
- 全局变量的作用域可以通过extern关键字扩展到整个文件或其他文件。但是static修饰的静态变量不能实现extern使用其值。static修饰的静态全局变量,是内部链接,限制了变量只在当前文件夹使用。
在使用extern的时候,不能出现两个或多个main函数,
2.5 存储模型
变量的存储方式可分为静态存储和动态存储。静态存储是在程序编译时就分配一定的存储空间并一直保持不变,直至整个程序结束。
动态存储变量实在程序执行过程中才分配存储单元,典型的就是函数的形式参数。在函数定义时,并不分配内存单元,而是在给予调用时,才会分配。调完函数就释放。如果被多次调用,那么多次申请释放。
2.5.1 自动
<存储类型> 数据类型 变量名
auto为存储说明符,可说明一个变量为自动变量。如果变量没有初始化,它的值是不确定的。
自动变量的作用域都是仅限于定义该变量的模块内。
2.5.2 寄存器
修饰符register声明的变量属于寄存器存储类。按道理这种变量应该是被频繁使用,如果可能,应该存到寄存器,加快存取速度。如果没有被初始化,该值也是不确定的。
2.5.3 静态、空链接
静态变量的类型说明符:static。
静态变量的存储空间在编译完成后就分配了,并且在程序运行的全部过程中都不会撤销。要注意:属于静态存储的方式的变量不一定是静态变量。
静态变量在定义是未赋值,则系统自动赋予0。
2.5.4 静态、外部链接
未使用static修饰的全局变量属于静态、外部链接存储类。若没初始化,也是自动赋值0。该值可以使用extern关键字来再次声明,调用。
2.5.5 静态、内部链接
被static修饰的全局变量属于静态、内部链接。此类变量是不能被extern声明调用的,这类变量只能在本文件中使用。若未声明其初始值,被设定为0。
3. 预处理
C语言提供了多种预处理功能,如宏定义、文件包含、条件编译等。
3.1 预定义
3.1.1 预定义符号
符号 | 示例 | 含义 |
__FILE__(%s) | /home/david/hello.c | 正在预编译的源文件名 |
__LINE__(%d) | 5 | 文件当前所在行 |
__FUNCTION__(%s) | main | 当前文件函数名 |
__DATE__(%s) | Mar 13 2009 | 预编译文件的日期 |
__TIME__(%s) | 23:04:12 | 预编译文件的时间 |
__STDC__(%d) | 1 | 如果编译器遵循ANSI C ,则值为1 |
一般用于程序出错的时候。
3.1.2 宏定义
#define 标识符 字符串
宏定义的时候,只是将符号替换成定义的字符串,要注意宏的副作用。
#define PI 3.1415926
宏定义的作用域包括从宏定义命名起到源程序结束,如果要终止,可使用#undef取消作用域。
#undef PI
宏名在程序中被括号括起来的,并不做替换。
#define 宏名(形参表) 字符串
例如:#define M(y) y+3
k=M(5)
k=5+3
补充:"max = (x > y) ? x : y",用于计算x、y中较大值。
3.2 文件包含
包含命令中的文件名可以用双引号括起来,也可以用尖括号。
使用尖括号表示在系统头文件目录中查找。(/user/include)
使用双引号表示首先在当前的源文件目录中去查找,找不到采取系统目录中找。
3.3 条件编译
#ifdef 标识符
程序段1
#else
程序段2
#endif
#ifndef 标识符
程序段1
#else
程序段2
#endif
#if 常量表达式
程序段1
#else
程序段2
#endif
(它的功能是,如果表达式为真,则执行程序段1,反之。)