C语言个人笔记(持续更新中)
第一&二章 概况
1 在UNIX、LINUX和Windows下的运行过程
c语言执行过程:源代码.c--->(编译器/汇编器)--->目标代码.obj--->(链接器)--->可执行代码.exe
编译器:将c文件编译为汇编语言
汇编器:将c文件编译为机器语言
链接器:有三种链接方式:
在UNIX系统上编译
不具备专门的C语言编译器,通常使用通用UNIX编译器(可以编译java等语言)的文本编译器
例:
cc 源.c //源文件通过.c结尾 运行时键入
ls ./ //此时会看到一个a.out的新文件
a.out //运行该文件即可完成编译。且在下一次编译时新的a.out会替换掉该文件,如想保存可通过改文件名实现
在LINUX系统上编译
gcc 源.c //gcc编译器需要单独安装
在WINDOWS系统上编译
通过使用IDE来编译即可
2 ANSI/ISO标准
最初终极标准为C89或者C90,现在则多使用C99标准
3 调试
语法错误:编译器可以检查到并报错
语义错误:编译器检查不到,逻辑出错
关键字错误:出线了C99规定的关键字,会报错
第三章 数据和C
整数与浮点数
整数通过二进制存储 符号位+数位
浮点数通过IEEE754方式存储 符号位+阶码+尾数
十六进制与八进制
使用%o输出8进制,使用%x输出16进制,前加%#o可以输出带格式的8进制,16进制同理
int a = 1;
printf("%#x",a); //输出: 0x1
各类型打印方法
无符号数:%u
长整型:%ld
短整型:%hd
字符:%c
字符串:%s
浮点数:%f
转义方式与特殊非打印字符
printf("\\,\""); //输出: \,"
非打印字符:\a \b \f \n \r
各类型一般情况下字节数
char:1B int:4B short:2B float:6bit double:18bit long double:18bit
输出过程分析
当遇到 printf() 语句时,先将内容存入缓冲区,此时若缓冲区已满or遇到换行则将内容输出到屏幕并刷新缓冲区。
第四章 字符串与格式化I/O
使用 scanf("%s",name); 当遇到空格等时会停止读取,如AI Halen,此时只能读取到AI
strlen() 与 sizeof()
strlen:只计算不空的字符,不计算空格与/0等
sizeof:计算所占用所有空间
第五、六、七章 循环、判断、运算符
第八章 I/O和输入确认
1 缓冲区
ANSI C中指定应对输入进行缓冲,当然可以使用 setbuf() 和 setvbuf() 来进行非缓存输入
缓冲分类:
完全缓冲:只有缓冲区满时才进行清空缓冲区的操作(将内容发送到目的地)
行缓存:当遇到换行符时就进行清空缓冲区的操作(多数系统均采用改方法)
2 中止键盘输入
文件、流和键盘I/O
文件读写通常采用流式文件的方法,而键盘I/O则与存储设备上的普通文件相同,采用stdin的流表示输入,而通过stdout的流表示输出。
为检测文件流尾标记,C输入函数装备了内置的文件尾检测器,而键盘输入可以看做文件,所以也可以使用该方法实现。
文件结尾
1、曾经文件结尾只能通过操作系统嵌套CTRL+Z来实现
2、现在则可以使用让操作系统知道存储器大小信息来让其停止
这两种方法的检测方式都是通过使用getchar()来判断收到的字符是否为EOF(end of file),通常EOF的值为-1(getchar的返回值一般为用户输入的ASCII码,所以一般在0~127之间),因为来判断
3 重定向和文件
当文件与I/O程序同时工作时,有两种方法可以对输入输出进行重定向(一般流输入通过标准输入完成)
第一种:使用专门的文件操作函数,即标准文件操作
第二种:使用不同通道重定向I/O,也就是说将stdin流重新分配至文件
UNIX输入重定向
echo_eof < words //将words文件引用到echo_eof文件当中完成输入重定向
UNIX输出重定向
echo_eof > mywords //将键盘输入的内容发送给名为mywodes的文件
UNIX组合重定向
echo_eof < mywords > savewords //将名为mywords文件的内容输入到savewords中
注:
-
重定向只能存在于数据文件与可执行程序之间
-
输入不能来自多个文件,输出不能输出到多个文件
4 输入确认
scanf返回值为输入成功个数,如 scanf("%d,%d,%d",&a,&b,&c);
若为3则全部输入正确,为2则只有两个正确
第九章 函数
- C语言被称为函数式语言。由于采用了函数模块式的结构,C语言易于实现结构化程序设计(SP)
可定义不确定函数参数
- 在一个函数体内不能再嵌套定义另一个函数
int imax(char *,...) //位于头文件stdarg.h中
1 递归
斐波那契数列:
long fib(int n)
{
if(n>2)
return fib(n-1)+fib(n-2);
return 1;
}
2 变量作用域
形参变量只有在被调用期间才分配内存单元,调用结束立即释放。
局部变量
又称为内部变量,作用域存在于函数中
全局变量
-
又称为外部变量,用extern进行修饰,其作用域是整个源程序
-
外部变量可以加强函数连续,可是也会增加函数间的耦合性,降低函数独立性
-
当局部变量与全局变量同名时。在局部变量的作用域内,全局变量不适用
3 变量的存储类型
变量的作用域不同本质是存储类型不同。
静态存储
在变量定义时就分配内存空间,知道程序结束才释放。(如全局变量)
- extern 外部(全局)变量
- static 静态变量
动态存储
使用时才分配存储单元,使用完毕立即释放。(如形参)
- auto 自动变量(C语言中最普遍的变量申明)
- register 寄存器变量(不能取地址,只是一种请求)
- volatile 易变变量(总是重新从它所在的内存读取数据)
第十章 数组与指针
1 数组
数组作为参数传递时
把数组的首地址传递出去(即将实参数组的地址传递出去)
通过该方式传递数组时在函数中的操作可能会导致数组本身的值发生改变,这时需要加上const
double xxx(const int a[],int n)
double xxx(const int *a,int n)
2 指针
地址间接访问符
可以使用间接访问符(也称作取值运算符)* 来获取指针中存放的数值: val = *ptr;
int *p=&i; //指针的取值运算符与指针的说明符不一样
*p = 5; //等价于i=5
多维数组与指针
int main()
{
int x[4][2] = { 2,4,6,8,1,3,5,7 };
printf("%d ", *(*(x+2)+1)); //取出(2,1)的数据结果为3
}
声明二维数组指针时:
int x[4][2] = { 2,4,6,8,1,3,5,7 };
int (*p)[2];
p=x;
const指针的运用
当const指针赋值给非const指针时会报错,因为编译器担心你通过非const指针改变数值,在进行一次间接运算时,反过来编译通过