Linux C编程基础

  1. 编辑器的使用:vi、 gedit或Eclipse。
  2. 使用GNU cc

GNU cc(gcc)是Gnu/Linux操作系统中编译器套件,使用它能够编译C等编写的程序。gcc是一个交叉平台的编译器,支持在不同CPU平台上开发基于不同体系结构硬件的软件。gcc也可以在编译时优化执行代码,而且能够产生调试代码。

gcc在编辑过程中可以分为预处理、编译、链接三个阶段。

下表说明了gcc常用命令行选项

选项

描述

-o filename

指定输出文件名,如果不指定filename缺省文件则是a.out

-c

只编译产生目标文件(.o文件)不链接

-DFOO=BAR

定义预处理宏FOO,其值为BAR

-IDIRNAME

将DIRNAME路径加到头文件搜索目录中

-LDIRNAME

将DIRNAME路径加到库文件搜索目录中

-static

静态链接库文件

-lFOO

链接名为libFOO的库文件

-g

在可执行代码中包含标准的调试信息

-ggdb

在可执行代码中包含gdb特有的调试信息

-On

指定优化编译的级别n,n可以为1、2、3

-ansi

使用ANSI/ISO C标准语法

-pedantic

允许发出ANSI/ISO C标准所列出的警告

-pedantic –error

允许发出ANSI/ISO C标准所列出的错误

-w

关闭所有警告

-Wall

允许发出gcc的所有警告

-werror

编译时将警告作为错误处理

-v

显示在编译过程中每一步用到的命令

(1)举例:简单使用(源程序名设为t1.c)

  1. 直接编译成可执行文件t1

#gcc  t1.c  -o  t1  

  1. 只做预处理

#gcc  -E  t1.c  -o  t1.cpp

  1. 将预处理结果编译成目标文件

#gcc  -x  cpp-output  -c  t1.cpp

  1. 将目标文件链接成可执行文件t1

#gcc  t1.o  -o  t1

(2)优化编译选项

优化可以改进执行文件的代码长度和执行效率

-O1   通常包括线程直接跳转和延迟退栈。

-O2   包含O1级所做的优化,并调整处理器指令执行时序。优化使处理器在等待其他指令的结果或数据延迟时仍然可以执行其他不相关指令,从而充分利用CPU资源,但其实现与处理器是密切相关的

-O3    包括O2级的一切优化并使用内嵌函数、循环展开以及其他与特定处理器特性有关的优化。

(3)调试选项

gcc能够使用-g和-ggdb选项在可执行代码中插入调试信息以便于程序调试。-g选项后可以附加1、2或3指定要在代码中加入多少调试信息。缺少情况下是2,它将在输出代码中加入符号表、行号、局部和外部变量信息。1级选项仅生成函数调用时的堆栈转储和回退信息,不包含行号和变量的调试信息。3级选项则包括所有2级的调试信息并包含所有宏定义等。

如果使用GNU Debugger(gdb)来调试,可以使用-ggdb所特有的调试信息以方便gdb调试。但是,这样做会使程序不能被其他的调试程序调试。

  1. 使用GNU gdb

一般,Linux发行版本都包含了一个叫gdb的GNU调试程序。gdb是一个功能强劲的调试器,提供了非常复杂的调试功能:

  1. 在调试器中查看代码
  2. 设置断点
  3. 单步执行跟踪监视程序中变量的值
  4. 运行中改变程序代码
  1. 启动gdb

#gdb

或#gdb filename    //filename是由gcc –g(或-ggdb)生成的含调试信息的可执行文件

如下例:

#gcc  -g  t1.c  -o  t1

#gdb  t1

  1. 在调试中查看源代码

(gdb)list                                            //在gdb命令提示符下输入list命令显示当前行附件的10行代码

或(gdb) list  n                                //显示第n行附近10行代码

  1. 设置断点与单步执行

(gdb)break  <n>                             //将第n行设置一个断点

或(gdb)break  <函数名>              //将某函数设置为一个断点

或在上面两种方式中加上文件名如break <文件名:n>来实现一个多文件项目设置断点

或(gdb)break  <行号n或函数名> if <条件表达式>  //根据条件设置断点

在断点停止执行时,可以用step或next命令实现单步调试,step遇到函数时将单步进入函数,而next命令在遇到函数时执行整个函数。

  1. 监视程序中变量的值

(gdb)print  变量名

第一次显示为$1=值  第二次显示出为$2=值等等

  1. 改变代码的运行

(gdb)print  变量名=值               //可以用print命令给变量在调试中赋新值,方便调试

可以用finish命令结束当前函数的调用(含main函数),或者用return  value停止当前函数并将value返回结调用者。

  1. Eclipse程序调试方法

    见书上:P111-118。

  1. 练习

如有以下C程序yanghui.c

#include <stdio.h>

int main()

{ int a[16][16];

  int i,j;

  for(i=1;i<16;i++)

     {a[i][1]=1;a[i][i]=1;}

  for(i=3;i<16;i++)

     for(j=2;j<i;j++)

          a[i][j]=a[i-1][j-1]+a[i-1][j];

  for(i=1;i<16;i++)

    { for(j=1;j<=i;j++)

        printf("%5d",a[i][j]);

      printf("\n");

     }   

}

  1. 用gcc编译生成可执行文件yanghui?

       gcc  yanghui.c -o yanghui

  1. 用gcc只做预处理生成yanghui.cpp?

       gcc -E yanghui.c -o yanghui.cpp

  1. 将yanghui.cpp编译生成目标文件yanghui.o?

gcc  -x  cpp-output  -c  yanghui.cpp

  1. 再yanghui.o链接生成yanghui1

       gcc yanghui.o -o yanghui1

  1. 为了使用gdb来调试,请将yanghui.c编译生成含调试信息的目标代码文件yanghui2。

       gcc  -ggdb yanghui.c -o yanghui2

  1. 用gdb打开yanghui2文件,用list命令查看一下源代码。

       gdb  yanghui2    (gdb)list

  1. 在gdb环境下运行代码查看输出结果。

       (gdb)run

  1. 将第7行设置一个断点,并使程序运行,到第7行暂停,此时查看i,j变量的值为何?用whatis命令查看变量i,j的类型及数据a的类型。

(gdb)break 7

使用单步命令执行5次后,查看此时i,j的值为何?

(gdb)step   (gdb)print i,j

  1. 再将第15行设置第二个断点?使程序从刚才位置直接运行到此断点。(finish)

     (gdb)break 15   (gdb)continue

  1. 删除所有断点,再运行一次程序。

(gdb)delete  (gdb)run

  1. 修改源程序yanghui.c将第10行修改为for(i= =1;i<16;i++),再将其编译生成含调试信息的目标代码yanghui3。

gcc  -ggdb yanghui.c –o yanghui3

  1. 在gdb中打开yanghui3,运行,查看结果是什么?为什么?

gdb yanghui3 (gdb)run

  1. 将第10行设置成断点,运行程序,暂停后查看i的值,结果为多少?

(gdb)break 10 (gdb)run (gdb) print i

  1. 此时,用print语句将i设置成1,再单步查看程序的执行,是否可以继续执行?为什么?

(gdb)print i=1  (gdb)step

  1. 用continue结束程序的运行(实际上是结束main的运行),查看输出结果,是否与yanghui2运行结果一样?是否能通过这个例子理解在调试时改变代码的运行?

(gdb) delete 1 (gdb)continue

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值