C++ Primer:源码编译运行说明


1. 背景

  最近刚看完《C++ primer 中文版(第5版)》第一章,写完源码后想比较一下官方示例的源码,发现其说明文档是英文,大致看懂后记录一下官方是如何编译运行它的源码。

2. 相关资料与环境

C++ primer源码官方下载地址:
http://www.informit.com/store/c-plus-plus-primer-9780321714114
C++ primer

下载MS Visual Studio 2012

下载版本说明
GCC 4.7.0适用于gcc 4.7.0及以上的版本
MS Visual Studio 2012适用于VS2012及以上的版本
GCC pre-C++ 11 compilers 2012适用于VS2012以下的版本
Microsoft pre-C++ 11 compilers适用于gcc 4.7.0以下的版本

由于电脑中VS2017,故直接下载MS Visual Studio 2012。以下的编译运行在VS环境下运行。

MS Visual Studio 2012文件目录

MS Visual Studio 2012文件目录说明:

  1. 文件夹1~文件夹19代表C++ primer19个章节的源码。
  2. Version_test.h是部分源码所需头文件,如文件夹1的Sales_data.h就引用Version_test.h。
  3. CompilerNotes.pdf和Visual Studio 2012 README.pdf是总体文档说明。
  4. runpgms.bat从文件夹1遍历到文件夹19,runp.bat跳转到各个文件夹内部,执行里面runpgms.bat。
  5. makefile和MS_makefile_template是nmake默认执行文件,用于编译目录下所有源码,并生成对应.exe文件。

第1章节的文件夹目录

第1章节文件夹目录说明:

  1. data文件夹存放部分cpp文件执行所需输入的数据。
  2. .cpp文件是第一章所有源码。
  3. Sales_item.h是部分cpp文件执行所需头文件。
  4. runpgms.bat用于执行.exe文件,它会自动导入data文件夹中的数据并输出结果。若此文件夹中无对应的.exe文件,runpgms.bat执行失败。
  5. README.txt章节文档说明
  6. makefile是nmake默认执行文件,用于编译此目录下所有源码,并生成对应.exe文件。

由此文件夹中所有的makefile都是用nmake运行,故需要创建compile.bat来调用VS的vsvars32.bat搭建nmake运行环境。当双击compile.bat时,系统打开cmd,所有编译命令都是在上面执行。
compile.bat代码:

@echo off
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"
cmd

提示:使用需修改vsvars32.bat地址,本文所用vsvars32.bat地址如下:

vsvars32.bat地址

3. 编译运行

3.1 单文件编译运行

  将compile.bat复制粘贴到文件所在的目录,双击运行compile.bat,在弹出的cmd窗口输入编译命令即可。编译命令如下所示,其中/EHsc启动异常处理,/nologo禁止版权声明。

// add.cpp编译成add.obj
cl /EHsc /nologo /c add.cpp
// add.obj编译成add.exe
cl /EHsc /nologo add.obj
// 一步到位,add.cpp编译成add.exe
cl /EHsc /nologo add.cpp

多步编译:
多步编译
单步编译:
一步编译
编译结果:
编译结果

3.2 文件重定向

  通过文件重定向可以在运行.exe时,无需输入,直接将data文件夹中的文件作为输入文件,并计算输出结果。

data/add_item数据:

0-201-78345-X 3 20.00
0-201-78345-X 2 25.00

编译命令:

// add_item.cpp编译成add_item.exe
cl /EHsc /nologo add_item.cpp
// 自动导入data/add_item计算结果
add_item.exe <data/add_item

编译结果:
运行结果

注意:如果出现如下编译错误,其原因是add_item.cpp中引用#include “Sales_item.h”,而Sales_item.h又引用#include “Version_test.h”。故需要在编译命令中添加"/I…",表示引用上级目录,即主目录。也可以将主目录的Version_test.h拷贝到本目录上。

编译出错

修改后的编译命令:

cl /EHsc /nologo /I.. add_item.cpp

编译结果:
文件目录

  当文件夹下所有.cpp都存在对应.exe时,点击runpgms.bat便可输出多个.exe文件重定向后的计算结果。若cmd一闪而过,需要在runpgms.bat最后一行加上“pause”用于暂停。
runpgms.bat

runpgms.bat修改前:

echo on
add < data/add 
add_item < data/add_item
add_item2 < data/add_item
avg_price < data/book_sales
item_io < data/book_sales 
occurs < data/occurs
mysum < data/mysum

for %%i in ( for_ex forcount main_only whilecount) do %%i

runpgms.bat修改后:

echo on
add < data/add 
add_item < data/add_item
add_item2 < data/add_item
avg_price < data/book_sales
item_io < data/book_sales 
occurs < data/occurs
mysum < data/mysum

for %%i in ( for_ex forcount main_only whilecount) do %%i
pause

运行结果

3.3 多文件编译运行

  若觉得一个文件一个文件的编译运行太麻烦,可以使用compile.bat运行makefile,通过以下三个命令实现对所有源码的编译,对.obj和.exe的清除。

// 编译目录下所有源码
nmake
// 删除文件夹下所有.obj
nmake clean
// 删除文件夹下所有.obj和.exe
namke clobber

nmake

nmake执行结果

nmake clean

nmake clean执行结果

namke clobber

namke clobber执行结果

注意:在编译运行第2章节文件夹中的inits.cpp时,会出现“error C2732: 链接规范与“lround” 的早期规范冲突”的错误,这需将Version_test.h中的“#ifndef LROUND”修改为“#ifdef LROUND”。

inits.cpp所在目录

image.png

修改前:

#ifndef LROUND
inline long lround(double d)
{
    return (d >= 0) ? long(d + 0.5) : long(d - 0.5);
}
#endif

修改后:

// #ifndef LROUND
#ifdef LROUND
inline long lround(double d)
{
    return (d >= 0) ? long(d + 0.5) : long(d - 0.5);
}
#endif

4. 总结

  1. 编译环境不重要,用gcc,g++或cl都可以,重要的是代码编写和程序编译过程。
  2. 了解文件重定向和makefile的使用,会让编程更高效。

5. 参考资料

  1. [tips]2018-08-08 关于c++ primer 1.6节 Sales_item.h 头文件 在VS2015社区版(免费)中的相关问题及解决办法
  2. 运行 NMAKE
  • 13
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值