OOP 学习笔记(1)——编程环境与基本技能

OOP 学习笔记(1)——编程环境与基本技能

Contents

编程环境与基本技能

源程序结构

  1. 头文件与编译指令;
  2. 辅助函数定义;
  3. 主函数定义。

编译与链接

编译器

把源代码转化为汇编语言或机器指令。

链接器

把各段程序链接为一个完整的可执行程序。

实例

1

其中 g++ -c 是只编译不链接,后面的 g++ -o 代表把编译好的 1.o 文件链接成可执行文件 1.out

多个源文件的编译和链接

建议函数声明与定义分离,将声明放至对应名字的头文件 .h 中。

func.h 中:

int ADD(int a,int b);

func.cpp 中:

#include "func.h"
int ADD(int a,int b)
{
    return a+b;
}

main.cpp 中:

#include "func.h"
int main()
{
    //...
}

可以采用直接编译的方法:

g++ main.cpp func.cpp -o test1

(建议省略头文件)

也可以采用间接编译:

g++ -c main.cpp -o main.o
g++ -c func.cpp -o func.o
g++ main.o func.o -o test2

得到效果相同。

宏定义

利用部分提到过的宏定义可以防止头文件被重复包含:

#ifndef __BODYDEF_H__
#define __BODYDEF_H__
// 头文件内容
#endif

也可以更简单:

#pragma once
// 头文件内容

其可保证物理上的同一个文件不会被编译多次。

同样也可以利用宏定义来设置输出调试相关信息。

主流编译器以及 IDE

编译器

  • MinGW:Minimalist GNU For Windows,是用于 Windows 平台 C/C++、ADA、Fortran 语言的编译器。
  • TDM-GCC:Windows 版的编译器套件,结合了 GCC 工具集中最新的稳定发行版本。

其他系统安装

  • Linuxsudo apt-get install build-essential
  • Macbrew install gcc

IDE

  • DEV C++
  • Code::Blocks
  • Visual Studio
  • CLion
  • XCode

Editor

  • Notepad++
  • SublimeText
  • VIM
  • Visual Studio Code

CLion

C++11

本教程内容均使用 C++11 标准。

  1. g++ -v 可以确认 g++ 版本 $\ge 4.7$。

  2. 以 C++11 标准编译:

    g++ -std=c++11 1.cpp -o 1
    
  3. IDE 中一般也可以选择 C++ 标准。

MAKE 工具

  • 使得大型编译工作自动化的一种工具:
    • 减少编译程序花费的时间。
    • 确保使用正确的选项进行编译。
    • 确保链接正确的程序模块和程序库。
  • 根据其机制,还可以:
    • 简化任务的重复执行过程。
    • 减少说明文档的编写工作量。
    • 其它创新性的想法。

Makefile 编写规则

  • 如果工程没有编译过,则所有 .cpp 文件均要编译并被链接。
  • 如果某几个 .cpp 文件修改,只编译修改的 .cpp 文件,并链接目标程序。
  • 如果工程的头文件被改变了,需要编译引用了这几个头文件的 .cpp 文件,并链接目标程序。

格式

<target>: <prerequisites>
[tab]   <command>

prerequisites 中如果有至少一个文件比 target 文件要新的话, command 命令就会被执行。

注释以 # 开头即可

一个示例文件如下:

# OOP @ 20200130

all: main.exe test.exe

main.exe: main.cpp student.cpp
    g++ -o main.exe main.cpp student.cpp

test.exe: student.cpp student_test.cpp
    g++ -o test.exe student_test.cpp student.cpp

clean:
    del *.exe

编写 Makefile 的基本方法

  1. 从一个例子入手;
  2. 列出源程序清单;
  3. 搞清楚几个最基本的编译器参数选项;
  4. 更多 Make 用法:http://www.ruanyifeng.com/blog/2015/02/make.html

除此之外还有几个可以用于提高效率的 MAKE 宏:

  • $@ 代表目标的全名(含后缀)。
    • $@ 指代当前目标,也就是 Make 命令构建的目标。
    • 比如 make foo$@ 就指代 foo
  • $* 代表无后缀的目标名。
    • $* 指代匹配符 % 匹配的部分。
    • 比如 % 匹配 f1.txt 中的 f1$* 就表示 f1
  • $< 代表规则中的源程序名。
    • $< 代表第一个前置条件。
    • 比如,规则为:t: p1 p2,则 $< 指代 p1
  • %:比如 %.o: %.c 就相当于 f1.o: f1.cf2.o: f2.c 等等。

运行 Makefile 的基本方法

  1. make
  2. make 任务名
  3. make -f makefile的文件名
  4. make -f makefile的文件名 任务名

尝试理解一个开源项目中的 Makefile 文件

https://github.com/moses-smt/giza-pp

.PHONY: gizapp mkcls-v2

all: gizapp mkcls-v2

gizapp:
    $(MAKE) -C GIZA++-v2

mkcls-v2:
    $(MAKE) -C mkcls-v2

clean:
    $(MAKE) -C GIZA++-v2 clean
    $(MAKE) -C mkcls-v2 clean

其中 .PHONY 后内容无视目标文件存在与否都执行 command,避免与工作目录下同名文件夹冲突。

可以使用 Var = 字符串 的形式定义变量宏。

预定义:$(MAKE) = make

make -C [target]: 则表示切换到 [target] 文件夹执行 Make 命令。

make -p 可查看所有预定义。

make -h 可查看帮助。

子文件夹:GIZA++-v2 中 Makefile 文件

.SUFFIXES: .out .o .c .e .r .f .y .l .s .p .cpp .alpha2o .pentiumo .sgio .alphao            # 该Makefile所支持后缀类型

INSTALLDIR ?= /usr/local/bin/  # 使用“?=”进行赋值的时候如果该变量已经赋值过了,那么将跳过

CXX = g++                      # 后面统一使用 CXX 编译

CFLAGS = $(CFLAGS_GLOBAL) -Wall -Wno-parentheses
CFLAGS_OPT = $(CFLAGS) -O3 -funroll-loops -DNDEBUG -DWORDINDEX_WITH_4_BYTE -DBINARY_SEARCH_FOR_TTABLE
CFLAGS_PRF = $(CFLAGS) -O2 -pg -DNDEBUG -DWORDINDEX_WITH_4_BYTE
... ... 
LDFLAGS =

include Makefile.src 

OBJ_DIR_OPT = optimized/
OBJ_OPT = ${SRC:%.cpp=$(OBJ_DIR_OPT)%.o} # %为匹配符
        # 提取SRC中所有.cpp的前缀,构成OBJ_DIR_OPT+前缀值.o的集合
OBJ_DIR =

GIZA++: $(OBJ_DIR_OPT) $(OBJ_OPT) # 将.o文件一起链接为GIZA++
     $(CXX) $(OBJ_OPT) $(LDFLAGS) -o GIZA++

$(OBJ_DIR_OPT): $(OBJ_DIR)        # 创建文件夹 
    -mkdir $(OBJ_DIR_OPT)

$(OBJ_DIR_OPT)%.o: %.cpp  # 编译所有cpp
     $(CXX) $(CFLAGS_OPT) -c $< -o $@

... ...

其中 Makefile.src 中:

SRC = Parameter.cpp myassert.cpp ...

GIZA++-v2 文件夹下有 $30$ 个 .cpp 文件。

OBJ_DIR 为空但不影响理解。

 

点赞 1

Comments: 7

  1. skylee03说道:

    图片挂了

  2. skylee03说道:

    TDM-GCC 已经停更好久了。现在最新版 GCC 是 9.2,TDM 还是 5.1。

  3. skylee03说道:

    还有这个

Add your comment