目录
之前一直学习的都是Cpp,由于Linux的内核语言是C,很有必要系统的记录和学习一下C语言,其操作底层的便利性其他语言无法比拟
更主要的是锻炼操作内存类型资源的能力,深入理解指针的使用
做这套c语言笔记要回答好三个问题
什么时候用?怎么使用?为什么要这样设计?
GCC基本操作
gcc -o 输出文件名 输入文件名 相当于output
gcc -o build(不需要打后缀名) 001.c
gcc -v -o 可以展示出在操作中的调用过程
打个hello world试验一下
无输出运行成功
实际存储的这个build其实是一个待执行文件,并不是执行过后的结果
还需要./build 做一个执行
C语言的编译过程
预处理
gcc -E -o 把.c转化为.i
在.i中已经完成了替换
即#define #include这些操作,在最开始就转化成.i时就已经经过了处理
因此define include并不是关键字,并不是编译时进行操作
编译流程
第一步是调用cc1 把.c文件转化为.s(汇编文件)文件(编译器)
gcc -S -o可以直接调用这个编译器
第二步调用as把汇编文件转化为.o(二进制机器语言)
gcc -c -o是间接调用的as
如果要把.c直接转化.o也可以直接gcc -c
第三步链接其他o文件来执行将预处理文件导入build的过程
使用代码就是gcc -o(其实经过了三个步骤)
c语言常见错误
预处理错误
在#include 用双引号一般用来调用本文件夹中自己定义的头文件 <>引的是环境变量里的
not find NO such file
就是路径下找不到
解决办法: gcc -I 跟头文件的目录 再加-o去输出(直接在include后根头文件的绝对路径也没问题)
编译错误
语法错误 太多了 !分号 大括号最容易错
链接错误
原材料不够了(undifined) 没有定义 or 原材料太多了(multpile)重复定义
解决办法:如果是函数体定义在其他文件 只要在gcc -o 最后加上对应。c就可以打包进行编译
预处理
# include 就是包含的头文件
#define 宏 就是替换(不会进行语法检查)
tips:
#define ABC (5+3) 为宏体加一个括号会更加规范,并且可以在计算中保证最高的优先级
#define ABC(x) ( 5+(x)) 宏函数
#ifdef #else #endif
条件预处理
#ifdef ABC
语句(如果定义define了ABC,这条语句就会参与编译,否则不参与编译)
#endif
gcc -D ABC1 -o:可以人为的增加宏定义到文件中,实际上相当于上文ifdef的开关
发行版本:
预定义宏
形如 __FUNCTION__ __FILE__ __LINE__
是系统已经定义好的宏
使用范例,指向信息(function指向的最近函数名),方便做测试
宏展开
# 字符串化
## 连接符号
#define ABC(x) #x 就是把x当成字符串
int day1=10
int day2=20;
#define ABC(x) day#x
printf(“the day is %d\n”,DAY(1));
就是把这个自变量的部分贴在后面,更方便阅读