C++ 学习之旅(1)——编译器Compiler
簡單來說,由C++代碼文件生成可執行文件的過程如下:
#mermaid-svg-rRxv2doRdH0QPyVV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-rRxv2doRdH0QPyVV .error-icon{fill:#552222;}#mermaid-svg-rRxv2doRdH0QPyVV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rRxv2doRdH0QPyVV .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-rRxv2doRdH0QPyVV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rRxv2doRdH0QPyVV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rRxv2doRdH0QPyVV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rRxv2doRdH0QPyVV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rRxv2doRdH0QPyVV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rRxv2doRdH0QPyVV .marker.cross{stroke:#333333;}#mermaid-svg-rRxv2doRdH0QPyVV svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rRxv2doRdH0QPyVV .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rRxv2doRdH0QPyVV .cluster-label text{fill:#333;}#mermaid-svg-rRxv2doRdH0QPyVV .cluster-label span{color:#333;}#mermaid-svg-rRxv2doRdH0QPyVV .label text,#mermaid-svg-rRxv2doRdH0QPyVV span{fill:#333;color:#333;}#mermaid-svg-rRxv2doRdH0QPyVV .node rect,#mermaid-svg-rRxv2doRdH0QPyVV .node circle,#mermaid-svg-rRxv2doRdH0QPyVV .node ellipse,#mermaid-svg-rRxv2doRdH0QPyVV .node polygon,#mermaid-svg-rRxv2doRdH0QPyVV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rRxv2doRdH0QPyVV .node .label{text-align:center;}#mermaid-svg-rRxv2doRdH0QPyVV .node.clickable{cursor:pointer;}#mermaid-svg-rRxv2doRdH0QPyVV .arrowheadPath{fill:#333333;}#mermaid-svg-rRxv2doRdH0QPyVV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rRxv2doRdH0QPyVV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rRxv2doRdH0QPyVV .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-rRxv2doRdH0QPyVV .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-rRxv2doRdH0QPyVV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rRxv2doRdH0QPyVV .cluster text{fill:#333;}#mermaid-svg-rRxv2doRdH0QPyVV .cluster span{color:#333;}#mermaid-svg-rRxv2doRdH0QPyVV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rRxv2doRdH0QPyVV :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}編譯鏈接C++文件--.cpp目標文件--.obj可執行程序--.exeC++代碼文件我們都不陌生,但實際上它的后綴名.cpp只是想對編譯器表明,自己需要被當作C++文件來編譯,所以即使你改為.txt后綴用記事本打開它一樣是可以的。
對于每一個.cpp文件,編譯器都會為它生成一個.obj文件,如下所示:
在VS里面對每一個cpp文件進行編譯(CTRl + F7),可以得到三個obj文件:
而在編譯之前,首先執行的是預處理語句,如#include #define #if #endif
#include的作用實際上就是找到對應文件,然后復制粘貼到當前文件而已,如下例:
我們可以創建一個頭文件Endbrace.h如下,里面只有一個右大括號:
//Endbrace.h }然后把Math.cpp改成這樣:
//Math.cpp int Multiply(int a, int b) {int result = a * b;return result; #include "EndBrace.h"完全沒有問題!這說明#include的功能就是復制粘貼而已。
我們可以通過如下設置看到預處理后的文件是怎么樣的(項目右鍵-屬性):
此時編譯就不會生成obj文件了,而是生成了一個.i文件,用記事本打開如下:
如果我們看下#include <iostream>后的結果就知道,里面會包含五萬多行的代碼,所以這就是為什么加上這個語句后編譯出來的obj文件會變得這么大。
#define則是把某個東西替換為另一個東西,如下:
//Math.cpp #define ZhengShu intZhengShu Multiply(int a, int b) {ZhengShu result = a * b;return result; }
可以看到預處理后的文件內容與原Math.cpp是一樣的。
#if #endif則是根據條件決定后面的內容是否存在,例如:
//Math.cpp #if 1int Multiply(int a, int b) {int result = a * b;return result; }#endif效果不變,而
//Math.cpp #if 0int Multiply(int a, int b) {int result = a * b;return result; }#endif
文件就變空了,因為#if后為0,不滿足條件。
最后講一下這個obj文件,直接打開的話是二進制,我們是看不懂的,但是我們可以把它變成匯編語言,設置如下:
現在進行編譯,我們會看到一個.asm文件,這就是匯編文件了:
用記事本打開如下(78行),imul就是乘法操作:
再再最后,關于VS中的Debug和Release,后者是經過優化的所以速度更快,但是不方便調試。如果我們想要在Debug中進行優化也是可以的,設置如下:
直接編譯會報錯,還需要以下設置:
優化之后編譯出來的文件(47行),很明顯就精簡不少了:
總結
以上是生活随笔為你收集整理的C++ 学习之旅(1)——编译器Compiler的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3年前吃过减肥药后有口臭至今好不了
- 下一篇: C++ 学习之旅(2)——链接器Link