点击链接加入群【C语言】:http://jq.qq.com/?_wv=1027&k=2H9sgjG


    

在上一小节中,我们分析了多维数组与简单的函数指针,这里就不再絮叨了,但是大家心里要明白哦。

今天,我们来研究一下C语言中的其它一些知识。

什么叫预处理?

所谓预处理就是指给你一篇文档,你进行一下简单处理,比如 把所有的N个连续空格都换成一个空格,

比如把里面的ABC都替换成abc,其实我们经常会做这种文件处理,不是嘛?那么这种处理放在C里面就叫预处理啦。只是换了个名字,我们可以简单的这样理解哦。比如,我们在处理一个文档的时候,可能会用WORD,可能会用NOTEPAD,可能会用WORDPAD,或者UE,或者editplus等工具,那么C里面在进行预处理的时候是由谁处理的呢?答案是预处理器,那么它在哪里?我也不知道,不过LINUX系统下是有的,不过我忘了名字了,大家想知道可以百度一下哦,在我们的VC6的安装目录里有一个文件夹

G:\VC\VC98\Bin 这个目录里存放的是一些工具,里面有一个 cl.exe, 如图所示

C语言入门篇-09_C语言学习


这个CL.EXE,如果我们把鼠标放在它的图标上,看一下提示信息,会看到 complier driver的字样,编译器不就是complier吗,为什么再加上个driver呢? 这个driver是驱动器的意思,它是一个工具集,接收不同的参数会执行的操作会不一样,所以它其实只是一个驱动器,而不是编译器,当我们给它传递 -C 参数的时候 它就执行编译操作,当然这些参数怎么获取,我们可以先设置好环境变量(如果你不会,你需要百度一下这个东西啦),然后在CMD窗口中 输入 cl /? > c:\cl.txt 会在C盘下生成cl.txt,这里面有详细的参数说明,不过我们没有必要全部研究啦,只说几个有助于我们学习C语言的

下面是我导出的CL.TXT文档,大家可以看看

C/C++ COMPILER OPTIONS


-OPTIMIZATION-


/O1 minimize space            /Op[-] improve floating-pt consistency

/O2 maximize speed            /Os favor code space

/Oa assume no aliasing          /Ot favor code speed

/Ob<n> inline expansion (default n=0)  /Ow assume cross-function aliasing

/Od disable optimizations (default)   /Ox maximum opts. (/Ogityb1 /Gs)

/Og enable global optimization      /Oy[-] enable frame pointer omission

/Oi enable intrinsic functions


-CODE GENERATION-


/G3 optimize for 80386          /Gy separate functions for linker

/G4 optimize for 80486          /Ge force stack checking for all funcs

/G5 optimize for Pentium         /Gs[num] disable stack checking calls

/G6 optimize for Pentium Pro       /Gh enable hook function call

/GB optimize for blended model (default) /GR[-] enable C++ RTTI

/Gd __cdecl calling convention      /GX[-] enable C++ EH (same as /EHsc)

/Gr __fastcall calling convention    /Gi[-] enable incremental compilation

/Gz __stdcall calling convention     /Gm[-] enable minimal rebuild

/GA optimize for Windows Application   /EHs enable synchronous C++ EH

/GD optimize for Windows DLL       /EHa enable asynchronous C++ EH

/Gf enable string pooling        /EHc extern "C" defaults to nothrow

/GF enable read-only string pooling   /QIfdiv[-] enable Pentium FDIV fix

/GZ enable runtime debug checks     /QI0f[-] enable Pentium 0x0f fix


-OUTPUT FILES-


/Fa[file] name assembly listing file   /Fo<file> name object file

/FA[sc] configure assembly listing    /Fp<file> name precompiled header file

/Fd[file] name .PDB file         /Fr[file] name source browser file

/Fe<file> name executable file      /FR[file] name extended .SBR file

/Fm[file] name map file


-PREPROCESSOR-


/C don't strip comments         /FI<file> name forced include file

/D<name>{=|#}<text> define macro     /U<name> remove predefined macro

/E preprocess to stdout         /u remove all predefined macros

/EP preprocess to stdout, no #line    /I<dir> add to include search path

/P preprocess to file          /X ignore "standard places"


-LANGUAGE-


/Zi enable debugging information     /Zl omit default library name in .OBJ

/ZI enable Edit and Continue debug info /Zg generate function prototypes

/Z7 enable old-style debug info     /Zs syntax check only

/Zd line number debugging info only   /vd{0|1} disable/enable vtordisp

/Zp[n] pack structs on n-byte boundary  /vm<x> type of pointers to members

/Za disable extensions (implies /Op)   /noBool disable "bool" keyword

/Ze enable extensions (default)


-MISCELLANEOUS-


/?, /help print this help message    /V<string> set version string

/c compile only, no link         /w disable all warnings

/H<num> max external name length     /W<n> set warning level (default n=1)

/J default char type is unsigned     /WX treat warnings as errors

/nologo suppress copyright message    /Yc[file] create .PCH file

/Tc<source file> compile file as .c   /Yd put debug info in every .OBJ

/Tp<source file> compile file as .cpp  /Yu[file] use .PCH file

/TC compile all files as .c       /YX[file] automatic .PCH

/TP compile all files as .cpp      /Zm<n> max memory alloc (% of default)


-LINKING-


/MD link with MSVCRT.LIB         /MDd link with MSVCRTD.LIB debug lib

/ML link with LIBC.LIB          /MLd link with LIBCD.LIB debug lib

/MT link with LIBCMT.LIB         /MTd link with LIBCMTD.LIB debug lib

/LD Create .DLL             /F<num> set stack size

/LDd Create .DLL debug libary      /link [linker options and libraries]


第一个就是-PREPROCESSOR- 下面的 /P 选项,就是进行预处理的啦,也就是我们编辑好文档,然后执行cl /P 文档名 就会生成 一个 被预处理完的文档,一般是以 .i 结尾的哦。

我们测试一下

#defineAAA"aaaaaaaaaa"

#defineBBB"bbbbbbb"

AAA + BBB

AAA

BBB

BBB

BBB

AAAABBB

BBAAABBBB

我们新建一个a.cpp,在里面输入这些内容,#define大家都知道是宏定义啦,然后我们预处理一下它,然后我们观察a.i

#line 1 "a.cpp"



"aaaaaaaaaa" + "bbbbbbb"

"aaaaaaaaaa"

"bbbbbbb"

"bbbbbbb"

"bbbbbbb"

AAAABBB

BBAAABBBB

,怎么样,进行了等价替换,就是把原代码中出现的单个的AAA和BBB进行了等价替换。这就是预处理指令#define的作用。当预处理器看到由它定义的内容后,就会进行等价替换啦,怎么样,你明白了吗?


我们没有必要去关心预处理到底是怎么做,其它这也无所谓,预处理完就要进行汇编啦,不过我未发现CL提供参数来生成相应的汇编文件,不过它提供了一个在生成.OBJ文件的同时生成汇编文件的参数,我们可以调用 cl -c /FA a.cpp 来进行生成,这个a.cpp 如下,必须满足C的要求,暂时不要带头文件,如下

int fun(int a,int b)

{

return a+b;

}

int main()

{

int a=1;

int b=2;

int c=fun(a,b);

return 0;

}

那么会在相应目录生成a.asm和a.obj,cl -c是用于编译用的,编译其实是调用两个DLL中的函数来完成的,DLL的名字也在那个目录里,我们可以在上图中找到 c1.dll c1xx.dll c2.dll ,前两个是相同功能的不同版本,负责编译过程的前部分处理,第三个负责编译过程的后部分处理,我们应该可以猜想到cl -c 调用的就是这3个DLL中的相关函数啦,这个过程叫编译,主要是生成.OBJ文件用的,我们有了.OBJ文件,就可以用链接器进行链接啦,link.exe也在那个目录里,我们可以看到它的提示信息里有个incremental linker ,关于这个增量链接,我们以后再做介绍,现在就知道它是链接器,可以将 库函数 与我们的函数 链接在一起,好了。关于这部分知识,先简单介绍到这里,其实大家可以多看参数表,慢慢理解其功能,而这些参数都是对应于 VC界面中的 工程-设置 对话框中的 相关设置,如图

C语言入门篇-09_C语言学习_02

好了,今天主要分析了 预处理,编译,链接使用到的工具啦。