• 高级Linux程序设计第一章:入门


    1、用GCC编译

    1.1、创建源文件

    • (main.c) C 源文件 - main.c

    #include <stdio.h>

    #include “reciprocal.hpp”

    int main (int argc, char **argv)

    {

        int i;

        i = atoi (argv[1]);

        printf (“The reciprocal of %d is %g\n”, i, reciprocal (i));

        return 0;

    }

    • (reciprocal.cpp) C++ 源文件 - reciprocal.cpp

    #include <cassert>

    #include “reciprocal.hpp”

    double reciprocal (int i) {

        // I should be non-zero.

        assert (i != 0);

        return 1.0/i;

    }

    • (reciprocal.hpp) 头文件 - reciprocal.hpp

    #ifdef __cplusplus

        extern “C” {

    #endif

        extern double reciprocal (int i);

    #ifdef __cplusplus

        }

    #endif

    1.2、编译源文件

    • 编译main.c:

    % gcc -c main.c

    • 编译reciprocal.cpp:

    % g++ -c reciprocal.cpp

    • 参数-I指定搜索头文件的位置。

    • 默认情况下,GCC在当前文件夹及标准库的头文件所在的文件夹来搜索头文件。

    % g++ -c -I ../include reciprocal.cpp

    • 可以用参数-D在命令行设定宏(macro),并且可以设定宏的值

    对于如下程序definemacro.c:

    #include "stdio.h"

    #include "stdlib.h"

    int main(int argc, char** argv){

            int i = 3;

    #ifdef CHANGEVALUE

            i = 4;

    #endif

            printf("i = %d\n", i);

            printf("PT = %f\n", PI);

    }

    如果编译时命令行为gcc definemacro.c,会报‘PI’ undeclared错误。

    如果编译时命令行为gcc -D PI=3.14 definemacro.c,则输出如下:

    i = 3
    PT = 3.140000

    如果编译时命令行为gcc -D PI=3.14 -D CHANGEVALUE definemacro.c,则输出如下:

    i = 4
    PT = 3.140000

    • 可以用GCC编译时优化代码.

    % g++ -c -O2 reciprocal.cpp

    1.3、链接对象文件

    • g++可以将.o对象文件链接成程序

    % g++ -o reciprocal main.o reciprocal.o

    • 如果想链接其他库文件,则用参数-I

    例如欲链接库libpam.a,则用如下命令行,编译器会自动加上前缀lib和后缀.a

    % g++ -o reciprocal main.o reciprocal.o –lpam

    • 链接器默认在/lib和/usr/lib文件夹下面寻找系统标准库。

    • 如果想从其他的文件夹下面寻找要链接的库,则从参数-L指定

    % g++ -o reciprocal main.o reciprocal.o -L/usr/local/lib/pam –lpam

    2、用Make自动编译

    • Makefile如下:

    reciprocal: main.o reciprocal.o

        g++ $(CFLAGS) -o reciprocal main.o reciprocal.o

    main.o: main.c reciprocal.hpp

        gcc $(CFLAGS) -c main.c

    reciprocal.o: reciprocal.cpp reciprocal.hpp

        g++ $(CFLAGS) -c reciprocal.cpp

    clean:

        rm -f *.o reciprocal

    • 首先是编译目标(target),紧接着是一个冒号:,然后是完成目标所需的依赖(dependencies)

    • 下一行是完成编译目标的规则

    • 规则行必须以Tab键开头

    • $(CFLAGS)是make变量,变量可以再Makefile中定义,也可以在命令行定义

    % make CFLAGS=-O2

    gcc -O2 -c main.c

    g++ -O2 -c reciprocal.cpp

    g++ -O2 -o reciprocal main.o reciprocal.o

    3、用GDB调试

    3.1、带调试信息编译

    • 如果要在编译时带调试信息,则在编译时命令行用-g参数

    % make CFLAGS=-g

    gcc -g -c main.c

    g++ -g -c reciprocal.cpp

    g++ -g -o reciprocal main.o reciprocal.o

    3.2、运行GDB

    • 启动GDB

    % gdb reciprocal

    • 命令run加参数可运行程序

    (gdb) run

    Starting program: reciprocal

    • 命令where可以查看Stack

    (gdb) where

    #0 __strtol_internal (nptr=0x0, endptr=0x0, base=10, group=0) at strtol.c:287

    #1 0x40096fb6 in atoi (nptr=0x0) at ../stdlib/stdlib.h:251

    #2 0x804863e in main (argc=1, argv=0xbffff5e4) at main.c:8

    • 用up命令可以弹出运行栈

    (gdb) up 2

    #2 0x804863e in main (argc=1, argv=0xbffff5e4) at main.c:8

    8 i = atoi (argv[1]);

    • 用print命令可以查看变量值

    (gdb) print argv[1]

    $2 = 0x0

    • 用break命令可以设定断点

    (gdb) break main

    Breakpoint 1 at 0x804862e: file main.c, line 8.

    • 用next命令执行下一条语句

    (gdb) next

    9 printf (“The reciprocal of %d is %g\n”, i, reciprocal (i));

    • 用step命令可以进入一个函数

    (gdb) step

    reciprocal (i=7) at reciprocal.cpp:6

    6 assert (i != 0);

  • 相关阅读:
    1>/dev/null 2>&1的含义
    rpm常用命令及rpm参数介绍
    linux按位运算
    关于比较运算符的一个例子
    js屏蔽效果
    jquery异步提交无刷新
    常用js验证
    获取输入字符的首字母(中文为拼音首字母)
    SQL查询合并字符串
    获取鼠标点击的坐标处理
  • 原文地址:https://www.cnblogs.com/forfuture1978/p/1717720.html
Copyright © 2020-2023  润新知