linux---------------g++的使用

来源:互联网 发布:手机触摸屏控制软件 编辑:程序博客网 时间:2024/05/21 15:23
一、C++中的一些文件后缀
.a静态库 (archive).C
.c
.cc
.cp
.cpp
.cxx
C++源代码(需要编译预处理).hC或者C++源代码头文件.iiC++源代码(不需编译预处理).o对象文件.s汇编语言代码.so动态库<none>标准C++系统头文件

二、gcc/g++执行的四个步骤

        g++命令在最后生成可执行文件之前经历了四个步骤,分别是预处理、编译、汇编和链接。我们通过使用g++的命令选项来查看g++命令执行过程中的步骤和每一步的生成文件。

(1)预处理器(预处理器cpp)

g++ -E main.cpp > main.i

       上面的命令只激活预处理,该过程并不生成文件,我们采用输出重定向到main.i文件中。预处理主要是语法的检查、宏替换、注释的消除和找到相应的库文件。

(2)将预处理后的文件转换成汇编语言程序(编译器egcs)

g++ -S main.i

       上面的命令执行完成后生成main.s文件,这是一个汇编语言源程序。

(3)将汇编语言源程序转换成为目标文件二进制机器码(汇编器as)

g++ -c main.s

       该命令执行之后生成main.o目标文件,这就是二进制机器码。

(4)链接目标文件生成可执行程序(链接器ld)

g++ main.o

       该命令执行之后便默认生成一个a.out的可执行文件,该过程是将main.o和所需的其他库文件链接生成可执行文件。

       上面的四个步骤就是g++将源代码生成可执行文件经历的四个步骤。

三、编译c/c++代码的时候,有人用gcc,有人用g++,于是各种说法都来了,譬如c代码用gcc,而 c++代码用g++,或者说编译用gcc,链接用g++,一时也不知哪个说法正确,如果再遇上个extern "C",分歧就更多了,这里我想作个了结,毕竟知识的目的是令人更清醒,而不是更糊涂。

误区一:gcc只能编译c代码,g++只能编译c++代码

两者都可以,但是请注意:

1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序;后缀为.cpp的,两者都会认为是c++程序,注意,虽然c++是c的超集,但是两者对语法的要求是有区别的,例如:
#include
int main(int argc, char* argv[]) {
   if(argv == 0) return;
   printString(argv);
   return;
}
int printString(char* string) {
  sprintf(string, "This is a test.\n");
}
如果按照C的语法规则,OK,没问题,但是,一旦把后缀改为cpp,立刻报三个错:“printString未定义”;
“cannot convert `char**' to `char*”;
”return-statement with no value“;
分别对应前面红色标注的部分。可见C++的语法规则更加严谨一些。
从单个源文件生成可执行程序

下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码:

1234567
/* helloworld.cpp */#include <iostream>
int main(int argc,char *argv[]){    std::cout << "hello, world\n";    return(0);}

程序使用标准输入流对象cout,向标准输出写入一个简单的字符串。该代码可用以下命令编译为可执行文件:

$ g++ helloworld.cpp

编译器 g++ 通过检查命令行中指定的文件的后缀名可识别其为 C++ 源代码文件。编译器默认的动作:编译源代码文件生成对象文件(object file)(又称目标文件),链接对象文件和 libstdc++ 库中的函数得到可执行程序。然后删除对象文件(又称目标文件)。由于命令行中未指定可执行程序的文件名,编译器采用默认的 a.out。程序可以这样来运行:

12
$ ./a.outhello, world

更普遍的做法是通过 -o 选项指定可执行程序的文件名。下面的命令将产生名为 helloworld 的可执行文件:

$ g++ helloworld.cpp -o helloworld

在命令行中输入程序名可使之运行:

12
$ ./helloworldhello, world

程序 g++ 是将 gcc 默认语言设为 C++ 的一个特殊的版本,链接时它自动使用 C++ 标准库而不用 C 标准库。通过遵循源码的命名规范并指定对应库的名字,用 gcc 来编译链接 C++ 程序是可行的,如下例所示:

$ gcc helloworld.cpp -lstdc++ -o helloworld

选项 -l (ell) 通过添加前缀 lib 和后缀 .a 将跟随它的名字变换为库的名字 libstdc++.a。而后它在标准库路径中查找该库。gcc 的编译过程和输出文件与 g++ 是完全相同的。

在大多数系统中,GCC 安装时会安装一名为 c++ 的程序。如果被安装,它和 g++ 是等同,如下例所示,用法也一致:

$ c++ helloworld.cpp -o helloworld
多个源文件生成可执行程序

如果多于一个的源码文件在 g++ 命令中指定,它们都将被编译并被链接成一个单一的可执行文件。下面是一个名为 speak.h 的头文件;它包含一个仅含有一个函数的类的定义:

1234567
/* speak.h */#include <iostream>class Speak{    public:        void sayHello(const char *);};

speak.cpp 的内容:包含 sayHello() 函数的函数体:

123456
/* speak.cpp */#include "speak.h"void Speak::sayHello(const char *str){    std::cout << "Hello " << str << "\n";}

文件 hellospeak.cpp 内是一个使用 Speak 类的程序:

12345678
/* hellospeak.cpp */#include "speak.h"int main(int argc,char *argv[]){    Speak speak;    speak.sayHello("world");    return(0);}

下面这条命令将上述两个源码文件编译链接成一个单一的可执行程序:

$ g++ hellospeak.cpp speak.cpp -o hellospeak

[tip]
这里说一下为什么在命令中没有提到“speak.h“该文件(原因是:在“speak.cpp“中包含有”#include”speak.h”“这句代码,它的意思是搜索系统头文件目录之前将先在当前目录中搜索文件“speak.h“。而”speak.h“正在该目录中,不用再在命令中指定了)。

0 0
原创粉丝点击