一. 第一段C
1 |
|
解析:
#include : 引入头文件
所有程序从main函数开始执行。
printf:格式化输出到屏幕,依赖stdio.h头文件。
stdio.h :标准输入输出头文件,使用printf()函数时,没提前引入此头文件会编译出错
return 0:退出程序。
二. 数据类型
基本类型:算术类型,包括
- 整数类型
- 浮点类型
枚举类型
也是算术类型,用来定义在程序中只能赋予一定的离散整数值的变量
void类型
类型说明符void说明没有可用的值。
派生类型
- 指针类型
- 数组类型
- 结构类型:数组类型和结构类型统称为聚合类型
- 共用体类型
- 函数类型:指的是函数返回值的类型
1. 整数类型
标准整数类型的的存储大小和值范围
| 类型 | 存储大小(字节) | 值范围 |
|---|---|---|
| char | 1 | -128到127或0到255 |
| unsigned char | 1 | 0到255 |
| signed char | 1 | -128到127 |
| int | 2或4 | -32768到32767或-2147483648到2147483647 |
| unsigned int | 2或4 | 0到65535或0到4294967295 |
| short | 2 | -32768到32767 |
| unsigned | 2 | 0到65535 |
| long | 4 | -2147483648到2147483647 |
| unsigned | 4 | 0到4294967295 |
各种数据类型存储大小和系统位数有关,需要得到该类型在当前系统上的大小,可以使用sizeof运算符
1 |
|
结果:
1 | int 存储大小 : 4 |
2. 浮点型
标准浮点型的存储大小,值范围,精度:
| 类型 | 存储大小(字节) | 值范围 | 精度 |
|---|---|---|---|
| float | 4 | 1.2E-38 到 3.4E+38 | 6 位小数 |
| double | 8 | 2.3E-308 到 1.7E+308 | 15位小数 |
| long double | 16 | 3.4E-4932 到 1.1E+4932 | 19 位小数 |
在程序中可以这样获得以上这些值:
1 |
|
ps:%E是以指数形式输出单,双精度实数
三. 变量
变量其实只是程序可操作的存储区的名称。C语言中,每个变量都有类型,类型决定变量存储的大小。
变量命名必须以字母或下划线开头,后面可以跟着数字,字母和下划线,并且字母区分大小写。
1. 变量定义
变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量的存储。定义的时候需指定变量的数据类型,并包含一个或多个变量列表。
以下为变量的声明:
1 | int a, b, c; |
写多个变量名表示同事创建多个变量。
变量的初始化:
1 | int a = 1; |
2. 变量的声明
变量的声明向编译器保证变量以指定的类型和名称存在,变量的声明有两种情况:
需要建立存储空间。
例如:int a在声明的时候就建立了存储空间。
不需要建立存储空间。
通过extern关键字声明的变量名而不定义他,如:extern int a,a变量可以不在这定义,而是在其他文件进行定义
除有extern关键字的,都是变量的定义。
1
2extern int a; //变量的声明
int a; //变量的声明,也是变量的定义
3. 左值(Lvalues)和右值(Rvalues)
C中有两种类型的表达式:
左值
指向内存位置的表达式称为左值表达式,左值表达式可出现在“=”左边或右边。
右值
右值指的是存储在内存中某些地址的数值。右值不能进行赋值,也就是说右值不能出现在“=”左边,只能存在右边。
1
2int a = 1; //a为左值,指向数字1在内存中所在的地址,故a可在等号左边和右边
int b = a;1
1 = 2; // 数值型为右值型,只能在等号右边,所以这样写会报错。
四. 常量
常量是固定值,在程序执行过程不会改变,这些固定的值也叫字面量。常量的值在定义后不能进行修改。
常量可以是任何基本数据类型,如字符常量,整数常量等。
1. 整数常量
带前缀整数常量可以是:
- 十进制:不带前缀
- 八进制:0为前缀
- 十六进制:0x或0X为前缀
带后缀整数常量(后缀可大写可小写):
- 后缀 U (或u):无符号整数(unsigned)
- 后缀 L (或l):长整数(long)
- UL或LU:无符号长整型
实例:
1 | 8 //十进制 |
2. 浮点常量
浮点数由整数部分、小数点、小数部分、指数部分组成。浮点常量表现形式:
小数形式:必须包含整数部分、小数部分,或两者都有
指数形式:必须包含小数点、指数,或两者都有
3. 字符常量
字符常量是在单引号中,可以是以下类型:
- 普通字符:例如’x’
- 转义序列:例如:’\t’
- 通用字符:例如’\u02C0’
4. 字符串常量
跟字符常量类似,但字符串常量括在双引号中””
5. 定义常量
在C中,有两种方式定义常用:
使用#define预处理器
1
使用const关键字
1
const int LENGTH = 10;
注意:通常把常量定义为大写字母形式
五. 存储类
C程序中,存储类定义程序中变量、函数的范围(可见性)和生命周期,这些说明符房子啊他们所修饰的类型之前。下面是C程序中可用的存储类:
- auto
- register
- static
- extern
1. auto
auto存储类是所有局部变量默认的存储类,auto只能用在函数类,也就是说auto只能修饰局部变量。
1 | { |
2. register
register存储类用于定义存储在寄存器的局部变量,而不是RAM中的局部变量,这意味着变量的最大尺寸等于寄存器的大小,而且不能用’&’运算符对它进行运算(因为它没有内存位置)
1 | { |
3. static
static存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在进入和离开作用域时进行创建和销毁。所以,使用static修饰的局部变量可以在函数之间调用保持局部变量的值。
使用static修饰全局变量时,会使变量的作用域限制在声明它的文件内。只要方法跟变量在同个文件内,都可调用该变量。
4. extern
extern存储类用于提供一个全局变量的引用,全局变量对所有程序文件都是可见的。
当使用extern时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置。
当有多个文件,且定义一个可以在其他文件中使用的全局变量或函数时,可以在其他文件中使用extern来得到已定义的变量或函数。extern就是用来在另一个文件中声明一个全局变量或函数。
文件一:main.c
1 |
|
文件二:printcount.c
1 |
|
结果:
1 | count is 10 |
六. 运算符
位运算符
位运算符作用于位,并逐位执行操作,真值表如下:
| p | q | p&q(与) | p|q(或) | p^q(异或) |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 |
| 1 | 0 | 1 | 1 | 1 |
<<二进制左移运行:将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0).
>> 二进制右移运算:将一个数的二进制位全部右移若干位,正数左补0;负数左bu1,右边丢弃。
杂项运算符
- sizeof():返回变量的大小
- &:返回变量的地址
- *:指向一个变量
七. 判断
C语言中“非零即为真”,就是说非零和非空认定为true,零或null认定为false
八. 循环
for无限循环
由于构成for循环的三个表达式中任何一个都不是必须的,所以三个条件都为空就构成一个无限循环。
1 | for( ; ; ){ |
九. 函数
函数是一组一起执行的任务语句。
函数的声明告诉编译器函数的名称、返回类型和参数;
函数的定义提供函数的实际主体。
函数的参数
形参:如果函数要使用参数,则必须声明接受参数的变量,这些变量就称为函数的形参。形参在进入函数时被创建,退出函数时被销毁。
函数调用时的两种传递参数方式:
传值调用
该方法把参数的实际值复制给函数的形参,此时修改函数的形参并不会影响实参
引用调用
通过指针传递,形参为指向实参地址的指针,当操作形参时,相当于同时在操作实参。
默认情况下,C语言使用传值调用。
十. 枚举
第一个枚举成员的默认值为整型0,后续枚举成员的值在前一个成员加1。
枚举变量的定义,有三种方式:
先定义枚举类型,再定义枚举变量
1
2
3
4
5
6
7
8
9
10enum DAY{
MON = 1,
TUE,
WED,
THU,
FRI,
SAT,
SUN
};
enum DAY day;定义枚举类型的同时定义枚举变量
1
2
3
4
5
6
7
8
9enum DAY{
MON = 1,
TUE,
WED,
THU,
FRI,
SAT,
SUN
}day;省略枚举名称,直接定义枚举变量
1
2
3
4
5
6
7
8
9enum{
MON = 1,
TUE,
WED,
THU,
FRI,
SAT,
SUN
}day;
十一. 指针
内存地址:
每个变量都有一个内存位置,每个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示在内存中的一个地址。
什么是指针?
指针是一个变量,其值是另一个变量的地址,即,内存位置的直接地址。
实际数据类型,不管是整形,浮点型或者字符型等,对应的指针的值类型都是一样的,都是一个代表内存地址的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
使用指针:
1 |
|
C中的Null指针
声明变量时,如果没有确定可以赋值的地址,通常给指针变量赋NULL值,此时的指针称为空指针。
NULL指针是定义在标准库中值为零的常量,
十二. 函数指针
通常指针变量是指向例如整形,字符型等变量,而函数指针是指向函数的指针变量。
函数指针可用于调用函数,传递参数。
回调函数
函数指针作为某个函数的参数:
函数指针可以作为某个函数的参数来使用,回调函数就是一个通过函数指针调用的函数,也就是说回调函数是由别人的函数执行时调用你实现的函数。
十三. 结构体
C数组允许存储相同类型的数据,结构是C语言中可由用户自定义的数据类型,它允许存储不同类型的数据项。
定义结构
使用struct语句定义一个包含多个成员的新数据类型:
1 | struct tag{ |
- tag:结构体标签
- member:标准的变量定义,比如int a。
- variable-list:结构变量,定义在结构的末尾,可以指定一个或多个结构变量。
例子:
1 | struct Books{ |
结构体的成员可以包含其他结构体,也可以包含指向自己结构体类型的指针,从而实现一些更高级的数据结构,比如树结构或者链表等。
结构体变量的初始化
结构体变量可以在定义时指定初始值:
1 | struct Books{ |
访问结构成员
可以使用成员访问运算符(.)来访问结构成员。
1 |
|
结果:
1 | Book1 title: C Programming |
指向结构的指针
定义指向结构的指针方式跟定义指向其他类型变量的指针类似:
1 | struct Books *struct_pointer; |
给结构指针变量赋值:
1 | strcut_pointer = &Book1; |
为了使用指向该结构的指针访问结构成员,需使用->运算符:
1 | struct_pointer->title; |
上面例子使用结构的指针来访问成员变量来实现:
1 |
|
十四. 共用体
共用体是一种特殊的数据类型,允许在相同的内存中存储不同的数据类型。共用体可以定义多个成员变量,但任何时候只能有一个成员变量带有值。共用体提供一种使用相同内存位置的有效方式。
定义共用体
定义共用体,需使用union语句,方式跟结构体相似。
1 | union Data{ |
共用体占用的内存为成员变量中最大的那个,例如上面例子中,Data占用10个字节。
访问共用体成员
访问共用体成员,可以使用成员访问符(.)。共用体变量的定义可以使用union,例如定义一个共用体类型的变量:
1 | unit Data data; |
注意:同一时间只能使用一个变量。
十五. typedef
C语言中typedef关键字,可以用来为已有类型或者自定义的数据类型取一个新的名字。例如
1 | typedef unsigned char BYTE; |
这样重命名后,以后就可以用BYTE来定义unsigned char了,这好比给自己起了一个昵称之后,以后朋友可以用你原来的名字叫你,也可用昵称来叫你了。
typedef 与#define的比较:
- typedef仅限为类型定义符号名称,#define不仅为类型定义别名,也能为数值定义别名,例如我们能将数字1定义为ONE
- typedef是由编译器执行解释的,#define语句是预编译器进行处理的