常用头文件
math.h
常用函数
abs();// 求绝对值 返回值int
sqrt();// 求平方根 返回值double
sin()
stdio.h
printf();
scanf();
getc();
string.h
strlen();
strcpy();
strcmp();
无符号类型
unsigned
浮点数问题
浮点数无法精确存储的原因
一个单精度的变量只能保证有效数位是7位。7位后面的数字是无意义的,并不准确表示该数
在C语言中尽量避免将一个很大的数和很小的数直接相加或相减,否则会丢失小数
输出控制符
\t:制表符,输出8个空格
\r:跳到一行初始位置
char类型的八进制
char c = '\729'; // 错误的代码,以\开头的是八进制,而八进制不能有9
%m.n问题
scanf()的问题
scanf("%2d %*3d %d", &a, &b);
如果输入以下信息:
12 345 67
系统会将12赋给a,在%*3d表示读入3位整数,但不赋值给任何变量,所以跳过345,将67给b
switch
switch与case常量表达式只能是整数类型、字符型;
case只能是常量表达式
二维数组
int a[3][4] = {0}; // 数组的初始化,每个元素都为0
int a[][4] = {1, 2, 3, ...}; // 合法的,可以这么玩
字符数组
可以理解为字符串,C语言中没有字符串类型,但是可以是字符数组来模拟。
因此,每个字符数组的最后一位是\0
字符串的初始化
char ch[10] = {"xxx"};
char ch[] = "xxx"; // 和上面一样都是等价的
// 只不过这样的话,系统会自动在最后面加\0
字符数组与printf应用
char * p = "%d %d";
int a = 10, b = 20;
printf(p, a, b);
字符处理函数
puts(str); // 将一个以'\0'结束的字符串输出的终端
gets(str); // 从终端输入字符串到str并返回str首地址
strcat(str1, str2); // 把str2中字符串追加到str1后面,并删除str1后的'\0'字符,并返回str1的首地址
strcpy(str1, str2); // 将str2中字符拷贝的str1中,最后的'\0'也会拷贝。前提是str1必须可以装下str2
strcpy(str1, str2, size); // 将str2装入str1中,指定复制的长度size
strcmp(str1, str2); // 按ASCII码从左到右逐个比较字符串内容,直到出现'\0',然后返回结构
str1 == str2 返回值==0
str1 > str2 返回值>0
str1 < str2 返回值<0
strlen(str); //返回str的长度,不包括字符串结束符'\0'
strlwr(str); // 将字符串中大写字母转换为小写字母
strupr(str); // 将字符串中小写字符转换为大写字母
变量修饰符
auto : 定义变量默认就是这个
static : 定义静态变量
register: 使用该关键字,变量会存放在寄存器里,有效提高运算速度
extern : 外部变量,放在静态存储区,意思就是说别的.c文件可以使用 默认函数就是该类型
宏定义
无参
#define 宏名 字符串(常数,表达式)
在使用的时候,当编译器扫描到宏时,会直接替换
有参数
#define 宏名(参数表) 字符串
#define ADD(X, Y) (X+Y)
使用
int sum = ADD(5, 10); 展开后 int sum = (5, 10); // 注意替换的时候会有括号的,因为在定义时候就有括号
头文件
<>:到存放C库函数的头文件所在目录
"":现在当前目录找,找不到时,回去C库函数所在目录找
条件编译
满足条件编译,不满足不编译;条件编译作用:直接在语法检查的时候判断是否编译
使用格式一
#ifdef 标识符
程序段1
#endif
格式二:
#ifdef 标识符
程序段1
#else
程序段2
#end
格式三:
#if 常量表达式
程序段1
#else
程序段2
#endif
函数指针
格式:
类型说明符 (* 指针名)();
类型说明符:函数返回类型
() 表示是一个函数指针
指针数组
int * a[5]; 存放地址的数组
数组指针
指向数组的指针
int (*pl)[5];
数组关于数组名和&数组名
&a+1:是加整个数组的大小
&a[0] + 1:是一个元素的大小
逗号表达式
int a = (2, 3, 4);
// 先计算左边的操作数,再计算右边的操作数
// 右边的操作数的类型的值作为整个表达式的结果
scanf()问题
如果在scanf()中有非输入控制符,要原样输入
如:
scanf("m%d", &a); // 要想使用先输入m,再输入要给a的值
三目运算符
格式:A?B:C
等价于
if(A)
B;
else
C;
数据类型
int 、long int、 short int、 char 、 float、double
位运算
运算符
操作
优先级
~
按位取反
1
<<
左移
2
>>
右移
2
&
按位与
3
^
按位异或
4
|
按位或
5
注意事项:
~的运算操作数是1个,其余都是两个
可以与赋值结合
<<=、>>=、&=、^=、|=
异或运算,相同为1,不同为0
<
操作数直接左移,高位丢掉,低位补0
>>右移
如果无符号右移,空位直接补0
如果是有符号右移,
如果是正数,右移补0
如果是负数,
左边补1,称为算数右移【实际上是使用这个】
左边补0,称为逻辑右移
动态内存
malloc(size); // 在内存申请开辟长度为size的连续空间
calloc(n, size); // 在内存范围n个长度为size的连续空间,函数返回初始地址,若分配失败则返回NULL
free(p); 释放p指向的内存
共用体
union 共用体名
{
数据类型1 成员1;
数组类型2 成员2;
...
}
为共用体变量分为空间大小是以所有成员中占用空间字节数最大的成员为标准
如:
union Myunion
{
int age;
char names[20];
}
sizeof(union Myunion) == 20
共用体的初始化
只能对第一个成员初始化
共用体在使用的时候,会只保留最后一次对成员赋值的值
与结构体不同的是
只按空间最大的成员来分配空间
在同一时刻,只存放一个成员的值
枚举
enum 枚举名
{
枚举元素
...
}
typedef
typedef 起别名
typedef int Num[100];
Num a; // 那么a就是一个数组,且元素有100个
文件
输入:数据从文件到内存
输出:数据从内存到文件
文件分类
按存储介质分
普通文件
设备文件:键盘、鼠标
按数据组织分
文本文件:ASCII码文件
二进制文件
C语言中文件的操作类型FILE是C为我们定义好的文件结构体
FILE * fp1, *fp2, *fp3;
文件常用函数
fopen(); 打开文件
fclose(); 关闭文件
系统自动打开和关闭的三个标准文件
标注输入 --- 键盘 stdin
标准输出 --- 显示器 stdout
标出错输出 --- 显示器 stdern
fopen作用
建立文件信息区
建立文件缓冲区
FILE * fopen(char * name, char * mode);
name: 文件路径
mode: 打开文件方式
返回值:如果正常打开文件会返回文件结构体地址,反之返回NULL
文件的打开方式
r
打开文件必须存在,且每次都会覆盖 读
w
没有文件立刻建立;有文件覆盖该文件 写
rb
二进制
wb
二进制
a
向文件末尾添加新的数据,且文件必须存在
ab
二进制
r+
既读既写,文件必须存在
w+
新建一个文件,既读既写
a+
源文件不删除,末尾添加数据,既读既写
rb+
ab+
wb+
文本文件:回车 转换为 换行符
二进制文件:不会转换
读写函数-字符
读取字符
fgetc(fp):从fp指向文件读入一个字符并返回,读成功返回。读失败返回EOF既-1
fputc(ch, fp):把字符ch写到文件指针变量,所指向的文件中
写成功:返回输出字符
写失败:返回EOF既-1
feof():对于二进制文件读取时判断文件是否结束,返回值文件结束为1,否则为0
读取字符串
fgets(str, n, fp):从fp文件读入长度为(n-1)的字符串,存入str数组中
返回值:
成功返回str首地址
失败返回NULL
读完n-1之前遇到\n或EOF字符,读入既结束,但也将\n按字符读入
fputs(str, fp):str所指向的字符数组写入文件中
返回值:
成功返回0
失败返回非零
读写函数-二进制
fread(buffer, size, count, fp)
fwrite(buffer, size, count, fp)
buffer:要读/写首地址
szie:要读/写文件大小(长度)
count:要读/写数据块的个数
fp:文件指针
随机读写
rewind(fp):让文件指针重新指向文件开头
fseek(fp, 位偏移, 起始点):
起始点:0:文件开始位置;1:当前位置;2:文件末尾
位偏移:long类型加L
fseek(fp, 100L, 0); // 文件开始偏移100个字节
fseek(fp, -10L, 2); // 文件末尾往前偏移10个字节
ftell():获取文件标记当前指向的位置
ferror(fp):文件读写的出错检测,0是没有出错,非0是出错;每次读写时都会有新的ferror()函数
clearerr():使文件错误标志和文件结束标志为0
二进制读写2个字节
putw
getw
ASCII码表
优先级表