Gamer's Show

你知道人生最要紧的事是快乐不停

0%

L2-编程环境

重点:

  • 多文件编译与链接过程
  • 宏定义&MAKE文件
  • 程序命令行参数
  • GDB调试工具

声明与定义

对于头文件,尽量只申明函数而不实现函数。尽量只声明全局变量而不定义全局变量

  • 声明:告诉编译器关于变量名称、变量类型、变量大小,函数名称、结构名称大小等信息,在此阶段不会给变量分配任何的库存

    • 声明变量:extern int x;;也可以用于函数声明
    • 通常用在全局变量在不同文件内的共享
    • 头文件中只是进行函数声明,并没有实现(定义)函数体,避免在链接时发现多个相同的函数实现(重复定义)而发生错误
  • 定义:变量声明+内存分配

    • 我们常见的int x=1或者int x都是变量定义,后者只是缺少初始化

宏定义

  • #define:一种预编译指令,用于给一个字符串定义一个“标识符”,这个标识符叫做宏名,被定义的字符串叫做替换文本
    • 预编译:宏替换:将宏名用被定义的字符串替换后再进行编译
    • 作用域:宏定义的有效范围称为宏名的作用域,宏名的作用域从宏定义的结束处开始到其所在的源代码文件末尾,不受分程序结构的影响。
      • 可以用预处理指令#undef加上宏名终止宏名的作用域。
  • 宏定义的简单使用:<宏名>(<参数表>) <字符串>
    1
    2
    #define PI 3.14
    #define sqrt(x) ((x)*(x))
    • 常量常用const定义
    • 注意line2在去掉字符串中x的括号时会引起运算错误:如果用sqrt(u+v)会输出u+v*u+v,由此体现宏替换只是简单的替换,并不会作出任何改变;如果有语法错误也只能在编译阶段发现
  • 宏使用时的其他指令
    • 避免头文件重复包含
      • #pragma指令:可以设置面一起状态或者指示编译器进行特定活动:
        • #pragma once:保证头文件只被编译一次。
        • #pragma message(“info”),在编译信息输出窗口中输出相应的信息,例如#pragma message("Hello")
        • #pragma warning,设置编译器处理编译警告信息的方式,例如#pragma warning(disable:4507 34;once : 4385;error:164)等价于#pragma warning(disable:4507 34)(不显示4507和34号警告信息)、#pragma warning(once:4385)(4385号警告信息仅报告一次)、#pragma warning(error:164)(把164号警告信息作为一个错误)。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #ifndef name //=if !def
    #define newName
    #else
    //程序段
    #endif

    // or

    #pragma once //保证物理上的同一个文件不会被编译多次
    • 用于debug输出,控制程序是否输出调试信息
      1
      2
      3
      4
      // #define DEBUG
      #ifdef DEBUG
      count<<"val:<<val<<endl;
      #endif
    • #error:指令使预处理器发出一条错误消息,然后停止执行预处理。
      1
      2
      #error info
      #error MFC requires C++ compilation

编译与连接

过程

  • 预处理:根据预处理指令对代码源文件处理,比如宏替换
  • 编译:检查语法
    • 第一遍执行语法分析与静态类型检查,把源代码解析为语法分析树的结构
    • 第二遍由代码生成器遍历语法分析树,把树的每个节点转换为汇编语言或机器代码,生成目标模块.o.obj文件
  • 汇编:汇编代码转换机器码,可以利用反汇编调试代码
  • 链接:将各目标文件中的各段代码进行地址定位,从而把一组目标模块链接为可执行程序,使操作系统可以执行它;处理目标模块中的函数或变量引用,必要时搜索库文件处理所有的引用。
    • 如果有外部函数声明但是没有函数实现,无法通过链接,但是可以通过编译

编译指令

g++ -c:只编译不链接
g++ -o ex1.out ex1.o:链接程序
g++ ex5_main.cpp func.cpp -o:直接编译

MAKE工具

通过写入MakeFile文件可以实现

程序命令行工具

GDB调试工具