程式環境和預處理
一、程式環境
我們知道計算機是沒有辦法認識除了二進位制之外的語言的,所以我們現在編出來的程式碼要想讓計算機認識並實現,就必須把它轉換成二進位制語言。我們把這個過程叫做程式的翻譯過程。
程式的翻譯過程又分為四個階段:
1、預處理:
在這個階段,它做了四個工作:巨集替換、去註釋、標頭檔案展開和條件編譯。
2、編譯:
在這個階段,它只做了一件事情,那就是將c語言編譯成為組合語言。
3、彙編:
在這個階段,它也只是做了一件事情,把組合語言變為目標二進位制。
4、連結:
最後一步,將目標二進位制檔案和庫函式連結形成可執行程式。
那麼,就會有人問了,為什麼不直接將c語言轉換成二進位制呢?
這就要從c語言的發展來說起了。起初,是沒有程式語言的,有的只是紙段,紙段上打眼來編寫程式,放入計算機中來計算,這種方法往往效率低並且計算複雜。而後,有了組合語言,人們拜託了紙段的束縛。但是,人們嫌組合語言還是不夠精簡,也就是使用複雜,所以才出現了c語言。這就解釋了為什麼從c語言到二進位制語言翻譯的時候,先翻譯成了組合語言,再翻譯成二進位制了。因為歷史是這麼發展的,二進位制->組合語言->c語言,所以從c語言到二進位制也是應該從後到前一步一步來。
二、預處理詳解
1、預定義符號
__FILE__ //進行編譯的原始檔
__LINE__ //檔案當前的行號
__DATE__ //檔案被編譯的日期
__TIME__ //檔案被編譯的時間
__STDC__ //如果編譯器遵循ANSI C,其值為1,否則未定義
這些預定義符號都是語言內建的。舉個例子:
printf("file:%s line:%d\n",__FILE__,__LINE__);
2、#define
(1)#define定義識別符號
#define name stuff //把name替換為stuff
一個小問題:define定義識別符號的時候,要不要在後面加上“;”?
比如:#define MAX 1000;,不建議加“;”,因為會報錯,c語言會單純地把1000;都賦給MAX。
(2)#define定義巨集
#define name(parament-list) stuff //其中的parament-list是一個由符號隔開的符號表,它們可能出現在stuff中。
**注意:**引數列表的左括號必須與name緊鄰。如果兩者之間有任何空白存在,引數列表就會被解釋為stuff的一部分。
如:
#define SQUARE(x) x*x
這個巨集接收一個引數x。如果在上述宣告之後,你把
SQUARE(5)
置於程式中,前處理器就會用下面這個表示式替換上面的表示式:
5*5
那如果我們輸入:
SQUARE(5+1)
結果會是多少呢?會是36嗎?
答案是11。為什麼呢?因為(5+1)當成了x,就成為了5+1*5+1,按照運算規則,結果就是11。
所以我們要想讓它輸出36,就必須加上小括號。
SQUARE(x) (x)*(x)
提示:當我們需要用巨集計算時,須在能加上小括號的地方都加上小括號。
(3)#和##
a.#的作用:把一個巨集引數程式設計對應的字串。
b.##的作用:可以把位於它兩邊的符號合成一個符號。它允許巨集定義從分離的文字片段建立識別符號。
(4)巨集和函式的對比
巨集通常用來執行簡單的運算。比如在兩個數中找出較大的一個:
#define MAX(a,b) ((a)>(b))?(a):(b))
巨集相對於函式的優點-------巨集計算的速度快,並且巨集還可以傳型別。
巨集相對於函式的缺點-------巨集會增加程式的長度。巨集沒有辦法除錯。巨集由於與型別無關,也就不夠嚴謹。巨集由於優先順序的問題,導致程式容易出錯。
提示:我們優先用函式。
(5)條件編譯
條件編譯語句的特徵就是語句前面有一個“#”。
常用的:
#ifndef __TEST_H__
#define __TEST_H__
//標頭檔案的內容
#endif //__TEST_H__
這個是用來避免標頭檔案的重複引入。
(6)標頭檔案的包含
標頭檔案可以用雙引號,也可以用尖括號。
如:
#include "stdio.h"//本地檔案包含
查詢策略:先在原始檔所在目錄下查詢,如果該標頭檔案未找到,編譯器就像查詢庫函式標頭檔案一樣在標準位置查詢標頭檔案。如果找不到就提示編譯錯誤。效率低。
#include<stdio.h>//庫檔案包含
查詢標頭檔案直接去標準路徑下去查詢,如果找不到就提示編譯錯誤。
相關文章
- 批處理-刪除環境變數變數
- PHP視訊處理器安裝環境搭建PHP
- 預處理指令、構建大型程式
- 資料預處理和特徵工程特徵工程
- 如何在ES5與ES6環境下處理函式預設引數函式
- 模型訓練:資料預處理和預載入模型
- 環境互動設計,如何處理掩體的放置?
- Mac環境下MySQL無法啟動的處理方法MacMySql
- K8S環境的Jenkin效能問題處理K8S
- Python環境安裝及資料基本預處理-大資料ML樣本集案例實戰Python大資料
- 影像預處理
- 自動部署模組所需環境依賴--bat批處理BAT
- 從產品經理被打看你所處環境的危機
- Go多協程併發環境下的錯誤處理Go
- 搭建雲網站資料處理的環境——安裝docker網站Docker
- 中斷和中斷處理程式
- 影像預處理方法
- 資料預處理
- [APUE] 程式環境
- C語言程式設計——9,預處理命令C語言程式設計
- 自然語言處理之:搭建基於HanLP的開發環境自然語言處理HanLP開發環境
- RabbitMQ學習系列三:.net 環境下 C#程式碼訂閱 RabbitMQ 訊息並處理MQC#
- 資料預處理 demo
- 搭建程式碼環境
- Xcode配置測試環境和線上環境XCode
- 惡劣的網路環境下,Netty是如何處理寫事件的?Netty事件
- 文字資料預處理:sklearn 中 CountVectorizer、TfidfTransformer 和 TfidfVectorizerORM
- Js 和Url預設位址列編碼等處理JS
- LeanCloud 雲引擎支援預覽環境Cloud
- Windows多版本Python環境下修改預設Python和IPython版本WindowsPython
- 【scikit-learn基礎】--『預處理』之 缺失值處理
- 多對一處理 和一對多處理的處理
- SAP雲平臺CloudFoundry環境裡route 超過quota的錯誤處理Cloud
- win10系統jdk 1.7環境變數不生效怎麼處理Win10JDK變數
- 生產環境故障處理演練-mysql資料庫主從恢復MySql資料庫
- 關於vue-cli開發環境中跨域的處理-配置代理Vue開發環境跨域
- win10新增環境變數無效怎麼辦 win10配置環境變數沒反應處理方法Win10變數
- Python資料預處理:Dask和Numba並行化加速!Python並行