首页 > 代码库 > Linux C++

Linux C++

一、gcc和g++的区别(转)

  GCC:GNU Compiler Collection。

  gcc:GUN C Compiler。

  g++:GUN C++ Compiler。

  就本质而言,gcc和g++并不是编译器,也不是编译器的集合,它们只是一种驱动器,根据参数中要编译的文件的类型,调用对应的GUN编译器而已,比如,用gcc编译一个c文件的话,会有以下几个步骤:

    Step1:Call a preprocessor, like cpp

    Step2:Call an actual compiler, like cc or cc1

    Step3:Call an assembler, like as

    Step4:Call a linker, like ld

  由于编译器是可以更换的,gcc不仅仅可以编译C文件,所以,更准确的说法是:gcc调用了C compiler,而g++调用了C++ compiler。

  gcc和g++的主要区别:

    1. 对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的);

    2. 对于 *.c和*.cpp文件,g++则统一当做cpp文件编译;

    3. 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL;

    4. gcc在编译C文件时,可使用的预定义宏是比较少的;

    5. gcc在编译cpp文件时/g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏,这些宏如下:

      #define __GXX_WEAK__ 1
      #define __cplusplus 1
      #define __DEPRECATED 1
      #define __GNUG__ 4
      #define __EXCEPTIONS 1
      #define __private_extern__ extern

    6. 在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价

 

二、-std=c++11 和 -std=gnu++11的区别(不确定)

  GNU对于C++的扩展中,有一些扩展是违反C++标准的,使用-std=gnu+++11时,默认启用这些扩展,而使用-std=c++11时,不违反C++标准的扩展项才会被启用。

  原文见stackoverflow,有关GNU对C++的扩展在此处有详细描述。

 

三、main()函数的形参。

  一般来说,main()函数可以写为:int main(int argc, char *argv[], char *envp[]),其中char *argv[]也可写为char **argv。

  int argc:表示在命令行下输入命令的时候,一共有多少个参数。包含可执行文件的文件名(可能以及文件路径)在内的字符串的个数即为argc的大小。

  char *argv[]:用字符串表示所输入的参数。

  如对于命令D:\>test.exe arg1 arg2,其argc = 3,即argv部分包含test.exe共有三个字符串作为参数,分别是:argv[0] = D:\>test.exe, argv[1] = arg1, argv[2] = arg2。

  char *envp[]:用来取得系统环境变量,使用较少。

  在UNIX下,环境变量的保存格式为:

    PATH=/usr/bin;/local/bin;

    HOME=/home/administrator;

  即 环境变量名=值。环境变量一般为程序提供附加信息。

  下面是一个示例程序:

#include<stdio.h>
#include<iostream>
using namespace std;
int main(int argc, char *argv[], char *envp[])
{
    int i;
    cout<<"You have inputed total "<<argc<<" argments"<<endl;
    for(i=0; i<argc; i++)
    {
        cout<<argv[i]<<endl;
    }
    cout<<endl;
    printf("The follow is envp:\n");
    for(i=0; envp[i]; i++)
    {
        cout<<envp[i]<<endl;
    }
    return   0;
}

  通过Codeblocks编译之后在CMD中输入: D:\Study\Algorithms>argtest.exe This is a test program of main()‘s arguments后返回的结果为:

You have inputed total 9 argments
argtest.exe
This
is
a
test
program
of
main()‘s
arguments

The follow is envp:
ALLUSERSPROFILE=C:\ProgramData
APPDATA=http://www.mamicode.com/C:/Users/Dracula/AppData/Roaming
CommonProgramFiles=C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=NEVERWINTER
ComSpec=C:\Windows\system32\cmd.exe
configsetroot=C:\Windows\ConfigSetRoot
FP_NO_HOST_CHECK=NO
HOMEDRIVE=C:
...

  可以看出在CB下编译出的代码并未将可执行程序所在的路径也作为参数的一部分,argv[0]只是可执行文件名。

  在MSDN上对envp[]的说明如下:

    1. 用于保存用户环境变量的字符串,以NULL结尾,所以可以通过if(envp[i])来判断是否打印完毕。

    2. envp可以是char *[]类型变量或者char**类型变量,如果使用unicode字符集(一般来说是使用ASCI字符集),则应使用相应的wmain()或者_tmain(),并使用wchar*[]、_tchar型的envp。

    3. envp传入main()程序的是字符串常量,不会改变。可以使用putenv()实时改变环境变量,或者getenv()实时查看环境变量,但是envp本身不会改变,因此可以作为恢复环境变量的依据。

  原文见Argument Definitions

  另外,有关_tmain()和main()的区别(大概是这样):

    1. main()是标准C++的函数入口。标准C++的程序入口点函数,默认字符编码格式ANSI,函数签名为int main(int argc, char* argv[])

    2. _tmain()是微软操作系统(windows)提供的对unicode字符集和ANSI字符集进行自动转换用的程序入口点函数。函数签名为int _tmain(int argc, TCHAR *argv[])

    3. 当程序当前的字符集为unicode时,int _tmain(int argc, TCHAR *argv[])会被翻译成int wmain(int argc, wchar_t *argv[]);当程序当前的字符集为ANSI时,则会被翻译成int main(int argc, char *argv[])。

 

Linux C++