Linux下的C语言入门

本文介绍了Linux环境下C语言编程的基础,包括使用vi编辑器,编译,gdb调试,多文件编译及makefile的使用。重点讲解了内存空间的五个部分:栈、堆、全局区/静态区、文字常量区和程序代码区,分析了栈和堆的区别和联系,强调了内存管理的重要性。
摘要由CSDN通过智能技术生成

Linux下的C语言入门

一.编辑器vi

vi是linux下最常用的文本编辑器,,我们可以使用它来编写c语言代码。

vi有命令模式和插入模式

一进来就时命令模式,输入i在当前光标处开始插入字符,可以用上下左右箭头控制输入。摁esc键可回到命令模式,下面介绍命令模式下几种常用的命令:

3 dd	//将光标所在行往下共3行代码剪切
3 yy	//将光标所在行往下共3行代码复制
p	//粘贴
:set nu	//显示行号
:sp filename	//新建一个文件并打开编辑窗口
:wq	//保存并退出
:q	//退出
:q!	//强制退出xxxxxxxxxx 

二.编译

//把hello.c编译。输出文件名为hello.out
gcc hello.c -o hello.out

//然后运行hello.out文件
./hello.out

三.使用gdb调试代码

gdb是对c语言debug的一个工具,在使用时,只需要在编译命令后面加一个-g,例如:

gcc hello.c -o hello.out -g
//然后调试
gdb hello.out

下面是一些基本操作命令:

l	//显示源代码
start	//开始调试,可以运行到下一个断点
break 6	//在第六行添加一个断点
break max	//在函数max的起始位置添加断点
info break	//显示所有断点
delete numofBreak	//删除编号为numofBreak的断点
n	//执行一行语句,注意不进入函数内部
s	//执行一行语句,遇到函数会进入函数内部
finish	//执行完当前函数
p a	//查看变量a的值
p &a	//查看变量a的地址
bt	//查看函数栈,可以看到函数序号
f 1	//切换到序号为的1的函数
q	//退出gdb调试

四、多文件编译及makefile的使用

命令格式:

gcc hello1.c hello2.c hello12.c -o hello.out -g
1

在hello1.c,hello2.c,hello12.c里的函数可以相互调用,当我们的源文件有很多很多时,每次都手动输入这些命令麻烦且容易出错,因此我们要使用make工具来管理这些编译命令,以达到快捷编译的效果。
使用方式:新建一个makefile文件,然后在里面编写内容:

/*格式:
 *	outputfilename:file1 file2 file3
 *	|<- tab->| gcc file1 file2 file3 -o outputfilename -g
 *解释:
 *	第一行是代表编译生成outputfilename文件所需要那些文件
 *	第二行是编译命令,注意其前面一定要有一个tab
 *注意:
 *	在第一行中如果存在非.c的文件,
 *	需要下面按着格式写明该文件的编译
 */

hello.out:hello1.o hello2.o hello12.c
        gcc hello1.o hello2.o hello12.c -o hello.out -g
//hello1.0和hello2.o都需要在下面这样声明
hello1.o:hello1.c
        gcc hello1.c -o hello1.o -g
        
hello2.0:hello2.c
        gcc hello2.c -o hello2.o -g

当makefile文件编写保存好之后,只需输入make命令就可快捷地进行编译。

五.内存空间(借鉴)

这部分是关于堆和栈,借鉴了一位大佬的博客
https://www.cnblogs.com/wsq-888/articles/cao-zuo-xi-tong-zhan-he-dui.html
内存空间图:

-c

栈:

​ 执行期间编译器自动分配,编译器用它实现函数调用,调用函数时,栈增长,函数返回时,栈收缩。局部变量、函数参数、返回数据、返回地址等放在栈中

栈的特点

  1. 内存分配取决于编译器,用户栈在程序运行期间可以动态的扩展和收缩。
  2. 和数据结构中的“栈”本质上是不一样的,但是操作方式类似于栈。
  3. 数据从栈中的进出满足“后进先出”的规律。
  4. 栈向低地址方向增长,esp(栈指针)指向栈顶元素。
堆:

​ 动态储存器分配器维护着的一个进程的虚拟存储器区域。一般由程序员分配释放(堆在操作系统对进程初始化的时候分配),若程序员不释放,程序结束时可能由OS回收,每个进程,内核都维护着一个变量brk指向堆顶。

堆的特点

  1. 内存分配取决于程序员,C/C++可以手动释放该片内存。
  2. 和数据结构的”堆“完全两回事,没有半点关系,在这里堆的结构更像链表。
  3. 所有的对象,包括数组的对象都存在堆上。
  4. 堆内存被所有的线程共享。
  5. 引用类型总是放在堆中。
  6. 堆向高地址方向增长,内核都维护的变量brk指向堆顶。

注意:值类型和指针总是放在他们被声明的地方(复杂)
当值类型的数据在方法体内被声明时,它们都应该放在栈上。
如果一个只类型被声明在方法体外且存在于一个引用类型中,那么它将会被堆里的引用类型所取代。

全局区/静态区:

​ 全局变量、静态变量、常量的存储区域,程序终止时系统释放。

文字常量区:

​ 存放常量字符串,程序结束后由系统释放。

程序代码区:

​ 存放函数体(类成员函数和全局函数)的二进制代码。

实例
int a = 0;        //全局初始化区
char *p1;       //全局未初始化区
void main()
{
    int b;          //栈
    char s[] = "123";  //栈
    char *p2;       //栈
    char *p3 = "sdfghhj"; //其中,“sdfghhj\0”常量区,p3在栈区
    static int c = 0; //全局区
    p1 = (char*)malloc(10);   //10个字节区域在堆区
    strcpy(p1,"sdfghhj");    //"sdfghhj\0"在常量区,编译器可能会优化p1和p3指向同一块区域

}
栈和堆的区别:
  1. 栈内存存储的的是局部变量,堆内存存储的是实体。
  2. 栈内存的更新的速度会更快些(局部变量),堆内存的更新速度相对更慢。
  3. 栈内存的访问直接从地址读取数据到寄存器,然后放到目标地址,而堆内存的访问更麻烦,先将分配的地址放到寄存器,在读取地址的值,最后再放到目标文件中,开销更大。
  4. 栈内存是连续的空间,堆内存一般情况不是连续的,频繁地开辟空间,释放空间容易产生内存碎片(外碎片)。
栈和堆的联系:

,堆内存的更新速度相对更慢。
3. 栈内存的访问直接从地址读取数据到寄存器,然后放到目标地址,而堆内存的访问更麻烦,先将分配的地址放到寄存器,在读取地址的值,最后再放到目标文件中,开销更大。
4. 栈内存是连续的空间,堆内存一般情况不是连续的,频繁地开辟空间,释放空间容易产生内存碎片(外碎片)。

栈和堆的联系:

​ 堆中对象是直接由栈中的句柄(引用)管理者,所以堆负责产生真实对象,栈负责管理对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值