Linux下的C语言
1. 搭建C语言开发环境/运行环境
1. 文本编辑
Linux下文本编辑器常用emacs和vim,由于本人常用vim,因此暂时只讲述vim的用法,vim需要自行安装。
#安装命令
sudo apt-get update #将系统内所有资源更新为最新版本
sudo apt-get install vim
vim的使用是一门深奥的学问,将vim使用好是现阶段的目标,让我们一起来看一下吧!
#vim编辑器的使用
vim **.c #进入某个文件
#进入后为命令模式,需要按英文输入模式下的i进入插入模式,才能够编辑文档
#如果想要退出编辑模式,按esc键回到命令模式,shift+:进入输入命令模式,w表示保存,q表示退出,通常情况下wq一起使用
#一些小快捷键
I 当前光标前
a 当前光标后面插入
shift + a / A 行位插入
shift +i / I 行首插入
o 下一行插入
shift + o / O 上一行插入
x 删除光标所在位置的
dd 整行删除
number + dd 剪切当前光标下面的number行,放到粘贴板上
p 粘贴
set nu 显示行号
当我们想要编辑多个文件的时候怎么办呢?— 多个源文件分而治之
命令模式下:
sp 文件名.c
ctrl + w + 上箭头 进入上面的代码块
ctrl + w + 下箭头 进入下面的代码块
wqa 所有文件都保存并退出
2. 编译器
Linux下C语言编译器常使用cc或者gcc,一般的Linux系统已经为我们安装好了,可以通过命令进行查看。
#查看cc和gcc版本信息
cc -v
gcc -v
#编译命令
cc / gcc **.c
参数:-c **.c
-o ***.out 编译后的文件名
#执行命令
./***.out
3. 头文件和系统预装文件
<> 这样文件导入,表示为系统预装文件
“” 这样导入的文件表示是在当前路径下的文件
头文件的作用:不会在修改的函数 公共框架/公共类 打包做成一个静态库,提前编译好,因为编译后就无法看到源代码了,可以写成头文件,便于其他人使用
例如:max的头文件max.h
int max(int a , int b);
4. make 工具
make工具可以将大型的开发项目分成若干个模块,可以清晰和快捷的整理源文件,内部使用gcc
#检查make版本信息
make -v
makefile 文件 每次只需要修改该文件即可
结构:
**注释
最终需要的文件:需要那些文件
执行什么命令
需要文件1:源文件
[tab/6空格]执行什么文件**
保存并退出
**make命令执行该文件**
eg:
# this is makefile
hello.out:max.o min.o hello.c
gcc max.o min.o hello.c
max.o:max.c
gcc -c max.c
min.o:min.c
gcc -c min.c
5. echo
gcc main.c -o main.out && ./main.out
&& 符号表示前面表达式返回0后面语句才能够执行
echo $? 输出0表示程序运行成功,其他表示失败
2. 标准输入流/输出流/错误流
printf,scanf底层源码:
fprintf(stdout,"please input the value a:\n");
int a;
/*scanf("%d",&a);*/
fscanf(stdin,"%d",&a);
if(a<0){
fprintf(stderr,"the value must > 0\n");
return 1;
}
1. 重定向机制
“>>” 输出流重定向到某个文件,追加 不是覆盖
“>” 覆盖
“<” 输入重定向
2. 管道
“ | ” 将前部分输出传入到后半部分代码中
3.GDB调试工具的使用以及内存
1. GDB 调试工具的使用
注:gcc -g 编译的才能够进行调试
gdb 文件名.out
start 开始调试
l 列出源代码
n 继续执行
p 变量名 显示变量值
bt 查看函数堆栈
s 进入函数执行的内部
2. 内存
32位的系统最大只支持4g的内存,2^32 只有32条地址总线
64位的系统最大支持2^64的内存
(1) 系统内存分配示意图
(2) 程序的内存映像
1)堆:用于存放函数参数值,函数返回地址,非静态局部变量的值。
2)栈:由程序员分配释放,如果程序员不释放,程序结束后由os回收
3)全局区(静态区):全局变量和静态变量存储在此处,初始化的放在一块区域,未初始化的放在相邻的另一块区域BSS。
4)数据段:常量字符串放在这个区域。
5)代码段:存放函数体的二进制代码。
字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。小端字节序指低字节数据存放在内存低地址处(由右向左),高字节数据存放在内存高地址处;大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处(由左向右)。
4. 指针
(1)* 和 & 区别
*是一个特殊符号,表明一个变量是指针变量,定义 p1、p2 时必须带*。而给 p1、p2 赋值时,因为已经知道了它是一个指针变量,就没必要多此一举再带上*,后边可以像使用普通变量一样来使用指针变量。也就是说,定义指针变量时必须带*,给指针变量赋值时不能带。
float a = 1.1;
int b = 1.2;
float *p1 = &a; # p 存放a的地址 *p存放a值
int *p2 = &b;
#改变指针内容
p1 = &a;
p2 = &b;
(2)* 不同场景下的使用
*在不同的场景下有不同的作用:可以用在指针变量的定义中,表明这是一个指针变量,以和普通变量区分开;使用指针变量时在前面加表示获取指针指向的数据,或者说表示的是指针指向的数据本身。
int *p = &a;
*p = 100;
(3) 数组指针
http://c.biancheng.net/view/1993.html
(4) 函数指针:(*函数名)(参数的类型 参数)
int (*pquadrate) (int a) = &quadrate;
Array数组其实是一种指针常量,而p则是一种指针变量(数组和指针有一定的通用性,又有一定的差别,指针可以表达数组,而数组不可以表达指针);
p++:指针偏移,运行效率比数组高;
(5) 指针运算,遍历