linux C —— gdb调试、简单Makefile

gcc可以编译c, c++, object-c, java等众多的语言程序
g++则是专注于C和C++。

gdb调试

GDB 调试器是一个功能强大的工具,它可以做很多的调试工作,如断点,单步跟踪等。
相关命令:

GDB命令格式含义简写
listList[开始,结束]列出代码l
printPrintf p打印变量p
breakBreak [行号|函数名]设置断点b
continueContinue[开始,结束]继续运行c
infoInfo para列出信息i
nextNext下一行n
stepStep进入函数S
displayDisplay para显示参数
fileFile path加载文件
runRun args运行程序r

下面演示两个例子,追踪快速排序的过程和查看优化后的gcd()算法(方法来自编程之美)

观察快速排序:

打印数组,查看快速排序中各个元素的位置变化

源码:

#include <stdio.h>
#include <algorithm>
using namespace std;
int partion(int a[],int start,int end){
    int i=start,j=end;
    int temp=a[start];
    while(i<j){
        while(i<j && a[j]>=temp)  j--;
        a[i]=a[j];  // i are more 
        while(i<j && a[i]<=temp)  i++;
        a[j]=a[i]; // j are more
    }
    a[i]=temp;   // at end , i=j
    return i;
}
void Qsort(int a[],int start,int end){
    if(start<end){
        int d=partion(a,start,end);
        Qsort(a,start,d);
        Qsort(a,d+1,end);
    }
}
int main(){
   int a[10]={3,2,7,5,1,0,9,6,4,11};
   Qsort(a,0,9);
   for(int i=0;i<10;i++)
      printf("%d ",a[i]);
   printf("\n");
   return 0;
}

指令:

edemon@linux:~$ g++ -g -o exe main.cpp
edemon@linux:~$ gdb exe
(gdb) break 17
Breakpoint 1 at 0x4006f4: file main.cpp, line 17.
(gdb) run
Breakpoint 1, Qsort (a=0x7fffffffdda0, start=0, end=9) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$2 = {3, 2, 7, 5, 1, 0, 9, 6, 4, 11}
(gdb) continue

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=0, end=3) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$3 = {0, 2, 1, 3, 5, 7, 9, 6, 4, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=0, end=0) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$4 = {0, 2, 1, 3, 5, 7, 9, 6, 4, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=1, end=3) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$5 = {0, 2, 1, 3, 5, 7, 9, 6, 4, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=1, end=2) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$6 = {0, 1, 2, 3, 5, 7, 9, 6, 4, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=1, end=1) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$7 = {0, 1, 2, 3, 5, 7, 9, 6, 4, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=2, end=2) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$8 = {0, 1, 2, 3, 5, 7, 9, 6, 4, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=3, end=3) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$9 = {0, 1, 2, 3, 5, 7, 9, 6, 4, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=4, end=9) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$10 = {0, 1, 2, 3, 5, 7, 9, 6, 4, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=4, end=5) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$11 = {0, 1, 2, 3, 4, 5, 9, 6, 7, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=4, end=4) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$12 = {0, 1, 2, 3, 4, 5, 9, 6, 7, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=5, end=5) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$13 = {0, 1, 2, 3, 4, 5, 9, 6, 7, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=6, end=9) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$14 = {0, 1, 2, 3, 4, 5, 9, 6, 7, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=6, end=8) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$15 = {0, 1, 2, 3, 4, 5, 7, 6, 9, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=6, end=7) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$16 = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=6, end=6) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$17 = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=7, end=7) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$18 = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=8, end=8) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$19 = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11}
(gdb) continue
Continuing.

Breakpoint 1, Qsort (a=0x7fffffffdda0, start=9, end=9) at main.cpp:17
17      if(start<end){
(gdb) p *a@10
$20 = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11}
(gdb) continue
Continuing.
0 1 2 3 4 5 6 7 9 11 
[Inferior 1 (process 7467) exited normally]

计算24, 26的最大公约数:

使用gdb查看递归情况,a和b是怎样变化的。
源码:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL N=1e5+10;
LL odd(LL a){
    return a&(1LL);
}
LL gcd(LL a,LL b){
    if(a>b) swap(a,b);
    if(a==0) return b;
    if(odd(a) && odd(b)) return gcd(b-a,a);
    if(!odd(a) && odd(b)) return gcd(a>>1,b);
    if(odd(a) && !odd(b)) return gcd(a,b>>1);
    if(!odd(a) && !odd(b)) return gcd(a>>1,b>>1)<<1;
}
int main(){
    cout<<gcd(24,26)<<endl;
    return 0;
}

指令:

$ g++ -g -o exe main.cpp
$ gdb exe
(gdb) run

Breakpoint 1, gcd (a=24, b=26) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=12, b=13) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=6, b=13) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=3, b=13) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=10, b=3) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=3, b=5) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=2, b=3) at main.cpp:10
]10     if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=1, b=3) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=2, b=1) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=1, b=1) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.

Breakpoint 1, gcd (a=0, b=1) at main.cpp:10
10      if(a>b) swap(a,b);
(gdb) continue
Continuing.
2

makefile

Linux中的make工具提供了一种管理工程的功能, 编写Makefile文件,通过make命令将多个文件编译为可执行文件
例如:
main.c
t1.c //output “hello world”
t2.c //output “I’m learning linux c”
action.h

action.h:

#ifdef __ACTION_H__
#define __ACTION_H__
extern void action1();
extern void action2();
#endif 

main.c
#include "action.h"
int main(){
    action1();
    action2();
    return 0;
}

t1.c:

#include <stdio.h>
void action1(){
    printf("hello world\n");
}

t2.c:

#include <stdio.h>
void action2(){
    printf("I'm learning linux C\n");
}

Makefile:

exe:action1.o action2.o main.o action.h
    gcc -o exe action1.o action2.o main.o
    gcc -c -o action1.o t1.c
action1.o:action.h t1.c
action2.o:action.h t2.c
    gcc -c -o action2.o t2.c
main.o:action.h main.c
clean:
    rm -f exe action1.o action2.o main.o


edemon@linux:/media/edemon/document/program/prodoc/contest/newpra/makeFile$ make
gcc -c -o action2.o t2.c
cc    -c -o main.o main.c
main.c: In function ‘main’:
main.c:3:5: warning: implicit declaration of function ‘action1’ [-Wimplicit-function-declaration]
     action1();
     ^
main.c:4:5: warning: implicit declaration of function ‘action2’ [-Wimplicit-function-declaration]
     action2();
     ^
gcc -o exe action1.o action2.o main.o
gcc -c -o action1.o t1.c
edemon@linux:/media/edemon/document/program/prodoc/contest/newpra/makeFile$ ls
action1.o  action2.o  action.h  exe  main.c  main.o  Makefile  t1.c  t2.c
edemon@linux:/media/edemon/document/program/prodoc/contest/newpra/makeFile$ ./exe
hello world
I'm learning linux C

常见问题:
Makefile:2: * missing separator. Stop.
第二行命令缺少tab空格
加tab空格后颜色改变。
这里写图片描述

make: * No rule to make target ‘action.h’, needed by ‘action1.o’. Stop.
我将头文件放到了/usr/include,事实上那是画蛇添足。只需要将所有的文件放在当前的文件夹下即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值