如何在Unix控制台或Mac终端中编译和运行C/C++代码?

176

我该如何在Unix控制台或Mac终端中编译/运行C或C++代码?


相关的错误信息通常是“命令未找到”、“a.out:命令未找到”或“/a.out:没有这样的文件或目录”。 - Peter Mortensen
19个回答

234

如果这是一个简单的单一源代码程序,

make foo

如果源文件是 foo.c, foo.cpp 等,则甚至不需要一个 makefile。make 已经内置了足够的规则将您的源文件构建为同名的可执行文件,减去扩展名。

运行刚刚构建的可执行文件与运行任何程序相同 - 但通常需要指定可执行文件的路径,因为 shell 只会在 $PATH 中搜索可执行文件,并且大多数情况下不包括当前目录(.)。

因此,要运行已构建的可执行文件 foo

./foo

今天我才意识到在调用make时,内置规则会传播到指定的目标。今天学到了新东西 =) - Branan
“-bash: make: command not found” <- 你必须下载开发工具和额外的组件。 - dmgig
27
不是要“make main.cpp”,而是要“make main”。 - Craig McMahon
1
"./" 在 "./foo" 中的作用是什么? - Fabian Amran
3
它指的是当前目录。除非在运行程序时指定路径,否则shell仅在$PATH环境变量列出的目录中查找要执行的程序。通常出于安全原因,.(当前目录)不会被包括在$PATH中。 - camh

132
gcc main.cpp -o main.out
./main.out

36
作为一名新手,我因未在执行命令时包含“./”而遭受了很多烦恼。 - funk-shun
15
我使用了命令"gcc main.cpp -o main.out",但出现了这个错误:Undefined symbols for architecture x86_64: "std::__1::locale::use_facet(std::__1::locale::id&) const", ... 后来我发现原因是,gcc默认链接的库是libc。而使用g++则会链接到libstdc++。因此,使用命令"g++ main.cpp -o main.out"可能会更好。 - Rachel
4
关于 Undefined symbols for architecture x86_64 问题,我将命令修改为 gcc -lstdc++ main.cpp -o main.out,在我的Mac上可以正常工作。 链接:https://dev59.com/dmct5IYBdhLWcg3wvf_K?lq=1 - rotoava
如果使用了std::cout(例如一个*Hello, World!*程序),则可能需要使用g++而不是gcc - Peter Mortensen
此处所述。 - Peter Mortensen

79

这是在所有 Unix 系统中都可以使用的命令...我在 Linux/Ubuntu 上使用它,但它也可以在 OS X 上工作。在终端应用程序中键入以下命令。

g++ -o lab21 iterative.cpp

-o 表示字母O,不是数字0

lab21 将是你的可执行文件

iterative.cpp 是你的C++文件

在运行该命令后,在终端中输入以下内容以运行程序:

./lab21

36

我的两个步骤:

第一步:

make foo

那么:

./foo

1
很抱歉,我是一个绝对的新手。这里的foo是什么? - HarshDarji

15

在 Unix(Linux、Mac OS X、AIX 等)环境中,所有应用程序的执行都依赖于可执行文件搜索路径。

您可以使用以下命令在终端显示此路径:

echo $PATH

在 Mac OS X 上(默认情况下),这将显示以下以冒号分隔的搜索路径:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin

因此,列出的目录中的任何可执行文件都可以通过输入其名称来运行。例如:

cat mytextfile.txt

这将运行/bin/cat并将 mytextfile.txt 显示到终端。

要运行不在可执行文件搜索路径中的任何其他命令,需要限定可执行文件的路径。所以,假设我在 Mac OS X 的主目录下有一个名为 MyProgram 的可执行文件,我可以这样完全限定它:

/Users/oliver/MyProgram

如果您在靠近要执行的程序的位置,则可以使用部分路径限定名称。例如,如果 MyProgram 在目录 /Users/oliver/MyProject 中,而我在我的主目录中,则可以像这样限定可执行文件名,并使其执行:

MyProject/MyProgram

或者,假设我在目录 /Users/oliver/MyProject2 中,想要执行 /Users/oliver/MyProject/MyProgram,我可以使用相对路径来执行它:

../MyProject/MyProgram

同样地,如果我在与 MyProgram 相同的目录中,则需要使用“当前目录”相对路径。您所在的当前目录是点字符后跟一个斜杠。例如:

./MyProgram

要确定您当前所在的目录,请使用 pwd 命令。

如果您通常会将程序放置在硬盘上的某个位置,并希望无需限定名称即可运行它们。例如,如果您在主目录中有一个“bin”目录,用于存放经常使用的 shell 脚本或其他程序,那么修改可执行文件搜索路径可能是明智的。

这可以通过创建或编辑您主目录中现有的 .bash_profile 文件并添加以下行来轻松完成:

#!/bin/sh
export PATH=$PATH:~/bin

这里波浪符(~)被用作快捷方式表示 /Users/oliver。同时注意,哈希叹号(#!)行需要成为文件的第一行(如果不存在的话)。还要注意,这种技术需要你的登录 shell 是 bash(Mac OS X 和大多数 Linux 发行版默认使用 bash)。此外,请注意,如果您想让安装在~/bin中的程序优先于系统可执行文件使用,则应按照以下顺序重新排序导出语句:

export PATH=~/bin:$PATH

看起来是个好主意。 编辑:算了,我有点讽刺。只是所有的$PATH东西让我想起了Windows的“环境变量”,你不应该太多地去搞它们。 - cmarangu
解开:“这看起来是个好主意。编辑:算了吧——我只是在讽刺。只是所有的$PATH东西让我想起了Windows的“环境变量”,你不应该太过于乱搞。” - Peter Mortensen
macOS在macOS v10.15(Catalina)中将默认shell更改为Z shell。这对它有用吗? - Peter Mortensen

11

请在“终端”中执行以下操作。

要使用G++编译器,您需要进行以下操作:

  1. 导航到存储*.cpp文件的目录。

    cd ~/programs/myprograms/ (~是您的主目录的快捷方式,即/Users/Ryan/programs/myprograms/,请将其替换为实际使用的位置。)

  2. 编译它

    g++ input.cpp -o output.bin(output.bin可以是任何带有任何扩展名的文件,.bin扩展名在Unix上很常见.)

    如果成功,则不会返回任何内容,这是可以的。通常只有失败时才会返回内容。

    但是,如果您键入ls,则会看到相同目录中的文件列表。例如,您会看到其他文件夹、input.cpp和output.bin

  3. 从目录内部,现在使用./output.bin来执行它


谢谢,这行得通。你知道任何教程可以解释这些东西吗?比如 G++ 到底是什么意思,'o' 开关是什么以及可能出现的其他任何内容? - Ryan
添加一条注释,说明make无法工作,因为没有makefile文件。 - week
Ryan,你可以在终端中输入“man g++”来获取“man页面”(即手册,我猜测苹果已经嵌入了)。我还没有看到任何很好的教程。虽然,关于g++的man页面可能会深入介绍CFLAGS和各种高级编译选项。 - nerdwaller
挑剔一点:如果成功了,就不应该有任何输出,这是可以接受的。通常情况下,失败时会有输出。无论如何都会有一个返回值,成功时为0,失败时为非0。 - sepp2k
合并自http://stackoverflow.com/questions/13714436/hello-world-in-c-says-nothing-more-to-be-done(试图整合一些基本指令) - Shog9

10

一个简洁的方式是这样做:

make foo && ./$_

拥有一行命令很好,这样您就可以轻松地再次运行可执行文件。


8
假设当前目录不在路径中,语法为./[程序名称]
例如: ./a.out

2
很好!点和斜杠之所以放在那里,是因为在许多系统中,当前目录(Unix术语中的“.”)不是Shell搜索路径的一部分。因此,添加它可以明确指出要运行哪个程序。 - unwind

8
要编译C或C++程序,有一个常用的命令:
  1. make filename

  2. ./filename

make 会将您的源文件编译成同名的可执行文件。但如果您想使用标准方式,可以使用 gcc 编译器来构建C程序,使用 g++ 来构建C++程序。
对于C:
gcc filename.c

./a.out

对于C++:

g++ filename.cpp

./a.out

7

添加以下内容以获得最佳警告,您不会后悔。如果可以,请使用WISE(警告即错误)进行编译。

- Wall -pedantic -Weffc++ -Werror

为什么要在“-”和“Wall”之间加空格?难道不是-Wall吗? - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接