Linux下vim编辑、makefile编译、GDB调试

  • Post author:
  • Post category:linux




Linux环境下C语言编程



1 .序

笔者又来更新博客了,每次立下Flag说要一周一次更新博客,但总是拖,最后奈何4月份只更新了一次,说明四月份又浑浑噩噩度过了一个月,不过值得可喜的是笔者在4月份找了一份实习工作,在里面做嵌入式软件开发,目前负责QT的开发。

笔者目前的Linux环境是ubantu16.04,gnome桌面环境,使用Linux系统时间久了不免产生审美疲劳,所以笔者就换了个MacOS的主题环境,果然界面焕然一新,又可以开开心心的编程了。附上桌面环境图。

在这里插入图片描述



2.Vim的相关操作

在Linux下各种文件的配置信息,难免会用到编辑器,而Vim就是一款强大的编辑器,当然C语言的编程也需要Vim编辑器输入,有很多人觉得VIm的操作繁琐,不容易记住很多指令,不过笔者觉得只要记住常用几个指令就足以应付这些了。



(1)命令行模式,

控制光标的

移动、进行复制、粘贴、删除撤销

等操作。通过

Ctrl+[

可以返回到命令行模式。

光标的移动通过

上下左右

键来进行移动,当然也可以通过

k j h l

来移动,使用字母键进行字符移动时,可以在其前面

加数字

,表示在对应的放下上进行移动。


dd

:表示删除一行,类似的ndd删除本行及下面的n行


yy

:复制一行,nyy复制当前行和下面的n行


p

:粘贴


u

:撤销


gg/G

:回到文首/文尾,然后输入数字,就可以跳转到行首,输入一个暴大的值,跳到行尾


/或者?

:后面输入数字,可以搜搜文本,n 或者shift+n 可以跳到下一个或者上一个


0 或者$

:行首(HOME) 行尾(END)也行



(2)插入模式,

只有在插入模式下,才可以进行文字的输入,按字母


i


可以进入插入模式,就能正常的进行操作了,就类似于word的操作一样了,然后上文也说过了,通过 Ctrl + [ 可以退出插入模式,进入命令行模式。



(3)底行模式

在退出插入模式后,按:可以进入底行模式,在底行模式下,可以进行文件的保存和退出。


:q

:不保存直接退出vim编辑器。


:q!

:不保存强制退出vim编辑器。


:wq

:保存退出vim编辑器。



3.C语言编程

C语言的编程,必然需要编译链接成可执行文件。当然一般的C语言运行过程需要经过:

预处理→编译→汇编→链接→可执行文件。

在Linux环境下,可以使用

gcc

来编译链接生成可执行文件。


  1. 预处理


    下文中可以看到,经过预处理之后,编译器已经把需要包含的头文件编译到.i文件当中。

    -E
#include<stdio.h>
int main()
{
  int i,j;
  for(i=0,j=5;i<j;i++)
    printf("%d Hello World!",i);
  return 0; 
}
gcc test.c -o test.i -E
extern int pclose (FILE *__stream);
extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
#912 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
#942 "/usr/include/stdio.h" 3 4
#2 "test.c" 2
#2 "test.c"
int main()
{
  int i,j;
  for(i=0,j=5;i<j;i++)
    printf("%d Hello World!",i);
  return 0;
}

  1. 编译


    编译阶段,就是编译器把源代码编译成.s汇编程序,可以试着点开.s文件查看一下。

    -s
gcc test.i -o test.s -S
.LC0:
        .string "%d Hello World!"
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        movl    $0, -8(%rbp)
        movl    $5, -4(%rbp)
        jmp     .L2

  1. 汇编


    将汇编语言源程序汇编成目标文件。

    -c
gcc test.s -o test.o -c

  1. 链接


    将目标程序链接相应的库函数生成可执行文件,之后执行,可以看到成功正确执行函数功能。
gcc test.o -o test
./test
0 Hello World!1 Hello World!2 Hello World!3 Hello World!4 Hello World!

*****不过正常直接一步就可以生成可执行文件来运行。

gcc test.c -o test
./test 
0 Hello World!1 Hello World!2 Hello World!3 Hello World!4 Hello World!



makefile文件的使用

当然这只是单文件的C语言运行,如果涉及到多个文件的编译的时候,就需要注意到编译顺序了,被调用的文件需要先编译产生.o文件,然后再配合调用函数的.o文件一起生成可执行文件。接下来举个栗子。

主函数test.c文件,主要包含子文件:print.c、hello.c、和Add.c文件,都在主函数中调用。

#include<stdio.h>
#include"print.h"
#include"hello.h"
#include"Add.h"
int main()
{
 int a,b;
  hello();
  printf("请输入两个计算的数\n");
  scanf("%d\n %d",&a,&b);
  int c=Add(a,b);
  print(c);
  printf("\n结束!");
  printf("终于学会make编译了!\n");
  return 0;
}

hello.c和hello.h文件:也主要是打印,负责刚开始的内容输出。

#include"hello.h"
void hello()
{
  printf("hello,world,今天开始学习make编译!\n");
}

//接下来是hello.h文件 ,只是负责对使用的函数进行声明。
#include<stdio.h>
void hello();

print.c和printf.h文件:主要负责打印,当然直接就可以使用printf,我这里是为了说明生成可执行文件的编译顺序。

#include<stdio.h>
#include"print.h"
void print(int c)
{
   printf("c=%d ",c);
}

//接下来是print.h文件 ,只是负责对使用的函数进行声明。
#include"stdio.h"
void print(int c);

Add.c和Add.h文件:主要是对输入的两个数进行相加,返回输出结果,也是在主函数中调用。

#include<stdio.h>
#include"Add.h"
int Add(int a,int b)
{
   int c=a+b;
   return c;
}
//接下来是Add.h文件 ,只是负责对使用的函数进行声明。
#include"stdio.h"
int Add(int a,int b);

由于在主函数中先调用的hello.c文件,所以你就先编译hello.c生成.o文件,当然你如果先编译Add.c或者print.c也是可以的,因为他们三个没有互相调用,当如果hello.c调用print.c中的函数,这个时候你就需要先编译print.c文件,然后才能编译hello.c文件。

之后再将生成的目标文件链接相应的库生成可执行文件。接下来,就按照讲的顺序来编译运行链接运行一下程序。

gcc hello.c -o hello.o -c
gcc Add.c -o Add.o -c
gcc print.c -o print.o -c
gcc test.c -o test.o -c

gcc test.o print.o hello.o Add.o -o test

./test

hello,world,今天开始学习make编译!
请输入两个计算的数
12
34 
c=46 
结束!终于学会make编译了!

是不是有一点小开心,自己今天终于有收获了,进步就是这样一点点来的。

当然如果每次修改一下程序都要这样编译一下,是不是会觉得很浪费时间,当然这还是只有几个文件,如果出现上百个文件,岂不是时间都花在编译指令上了,调试起来太麻烦了,所以就出现了

makefile

文件。

makefile文件中主要放的就是你程序的编译指令,通过

make

就可以直接执行makefile文件中的指令,就进行编译了,无需再慢慢每个文件进行编译了。

接下来就看看makefile文件的编写规则。首先放一个我自己写的刚刚的那个工程的makefile文件。

test:test.o Add.o hello.o print.o 
	gcc -o test test.o Add.o hello.o print.o 
test.o: test.c Add.h hello.h print.h
	gcc -c test.c -o test.o
Add.o: Add.c Add.h
	gcc -c Add.c -o Add.o
hello.o: hello.c hello.h
	gcc -c hello.c -o hello.o
print.o: print.c print.h
	gcc -c print.c -o print.o
clean:
	rm *.o test

顶层需要写自己最后生成的目标文件,也就是可执行文件test,:感叹号后面的就是生成可执行文件需要用到的目标文件,

下面就是生成可执行文件的指令,需要把所有的目标文件链接形成可执行文件。

接下来就是目标文件的生成,需要用到-c这个指令,把每个.c文件都生成.o文件就可以了。

最后一行的话,是清除生成的.o文件。接下来我们用makefile指令编译一下,make之后,就可以看到编译器有相应的输出,之后可以看到有可执行文件test了。

make
#编译器输出
gcc -c test.c -o test.o
gcc -c Add.c -o Add.o
gcc -c hello.c -o hello.o
gcc -c print.c -o print.o
gcc -o test test.o Add.o hello.o print.o

./test

hello,world,今天开始学习make编译!
请输入两个计算的数
12 34
c=46 
结束!终于学会make编译了!

其中比较关键的两点需要注意的就是:

第一点是默认的makefile文件名有两种:makefile或者Makefile,

这两种可以直接使用make指令,编译器是可以识别的,如果换成其他的文件,就需要用到-f指令了,例如

make
#编译器输出
make: *** 没有指明目标并且找不到 makefile。 停止。

make -f MakeFile
#编译器输出
make: 'test' is up to date.

第二点是makefile文件在书写编译指令的时候(第二行中gcc那一行),需要使用


Tab


键来空格,要不然会出现错误。



GDB调试

习惯了Windows上面软件自带调试系统,可以


随意设置断点、单步、运行等调试手段


,Linux上面的调试方式还真有点不习惯 ,有点原生态,什么都需要自己去写,去设置,比如上面的编译。

  1. 首先想用gdb调试,在写makefile文件时,要加入


    -g


    调试选项。

    在这里插入图片描述
  2. 然后


    gdb+可执行文件


    ,即可进入调试界面。

    在这里插入图片描述

    在这里插入图片描述


  3. b + 行数


    ,然后r 即可运行到指定的程序行数

    在这里插入图片描述


  4. print + 变量


    ,即可查看变量的内容

    在这里插入图片描述


  5. n可以单步调试


    ,但是


    不进入


    程序内部

    在这里插入图片描述


  6. s单步调试


    ,但


    进入


    程序内部

    在这里插入图片描述
  7. 如果不设断点,可以


    直接r运行


    程序。

    在这里插入图片描述



基本上面这些就满足日常的调试需求。



gdb+运行程序的好处就是,如果遇到段错误(


segmentation fault


),可以直接


停在错误的地方


,可以看到错误的行数以及在哪个文件,方便查找错误,

如果直接运行程序,程序退出后,只是显示段错误,并不会提示其他信息。当然如果语法错误,编译的时候就会显示出来。




如有雷同,纯属我抄你,有问题可以直接联系邮箱,在个人资料里面。



版权声明:本文为qq_34430371原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。