您好,登錄后才能下訂單哦!
本篇內容介紹了“C語言程序的編譯與預處理實例分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在ANSIC的任何一種實現中,存在兩個不同的環境:翻譯環境和執行環境
翻譯環境:源代碼被轉換為可執行的機器指令。
執行環境:實際執行代碼。
組成一個程序的每個源文件通過編譯分別轉換成目標文件(object code)。
每個目標文件由鏈接器(linker)捆綁在一起,形成一個單一而完整的可執行程序。
鏈接器同時也會引入標準C函數庫中任何被該程序所用到的函數,而且它可以搜索程序員個人的程序庫,將齊需要的函數也鏈接到程序中。
程序的執行環境:
1.程序必須載入內存中。在有操作系統的環境中:一般這個由操作系統完成。在獨立的環境中,程序的載入必須由手工安排,也可能是通過可執行代碼置入只讀內存來完成。
2.程序的執行便開始。接著便調用main函數。
3.開始執行程序代碼。這個時候程序將使用一個運行時堆棧(stack),存儲函數的局部變量和返回地址。程序同時也可以使用靜態(static)內存,存儲于靜態內存中的變量在程序的整個執行過程中一種保留它們的值。
4.終止程序。正常終止main函數,也有可能是意外終止。
#define 定義標識符
語法:
#define name stuff
#define MAX 100 #define REG register //為register創建一個簡短的名字 #define do_forever for(;;) //用符號來替換一種實現 #define PRINT printf("file:%s\tline:%d\tdate:%s\time:%s\n", \ __FILE__,__LINE__,__DATE__,__TIME__) //如果定義的stuff過長,可以分成幾行來寫,除了最后一行外,每行的后面都加一個反斜杠(續行符)。
在define定義標識符的時候,最后不要加(;)號。
#define機制包括了一個規定,允許把參數替換到文本中,這種實現通常稱為宏(macro)或定義宏(define macro)。
宏的聲明方式:
#define name ( parament - list ) stuff
其中的parament - list 是一個由逗號隔開的符號表,它們可能出現在stuff中。
參數列表的左括號必須與name緊緊相鄰。若兩者之間存在空白,參數列表就會被解釋為stuff的一部分。
#define SQUARE( x ) x * x
1.在調用宏時,首先對參數進行檢查,看看是否包含任何由#define定義的符號。如果是,它們將首先被替換。
2.替換文本隨后被插入到程序中原來文本的位置。對于宏,參數名被它們的值替換。
3.最后,再一次對結果文件進行掃描,看看是否還包含任何由#define定義的符號。如果是,就重復上述的過程。
注意:
1.宏參數和#define定義中可以出現其它#define定義的變量。但是對于宏,不能出現遞歸。
2.當預處理器搜索#define定義的符號的時候,字符串常量的內容并不被搜索。
如何把參數插入到字符串中?
#include<stdio.h> #define PRINT(n) printf("the value of "#n" is %d\n",n) int main() { int a = 7; PRINT(a); int b = 5; PRINT(b); return 0; }
##的作用:
當宏參數在宏的定義中出現超過一次的時候,如果參數帶有副作用,那么在使用這個宏的時候就可能會出現危險,導致不可預知的后果。副作用就是表達式求值的時候出現的永久性效果。
x+1;//不帶有副作用 x++;//帶有副作用
舉一個例子:
宏通常被應用于執行簡單的運算。例如在找出兩個數中的較大一個。
#define MAX(a, b) ((a)>(b)?(a):(b))
為什么不用函數來完成這個任務呢?有其下原因:
1.用于調用函數和從函數返回的代碼可能比實際執行這個小型計算工作所需要的時間更多。所以宏比函數在程序的規模和速度方面更勝一籌。
2.函數的參數必須聲明為特定的類型。所以函數只能在類型合適的表達式上使用。而這個宏可以適用于整形、長整型、浮點型等類型。宏是類型無關的。
宏和函數的對比:
一般來講函數和宏的使用語法非常相似。所以語法本身沒有辦法幫我們區分二者。
所以一般是:把宏名全部大寫,函數名不要全部大寫。
這條指令用于移除一個宏定義。
#undef NAME //如果現存的一個名字需要被重定義,那么它的舊名字首先要被移除
例如:
許多C的編譯器提供了一種功能,允許程序在命令行中定義符號。用于啟動編譯過程。
例如:當我們根據同一個源文件要編譯出不同的一個程序的不同版本的時候,這個特性就比較有用。(若某個程序中聲明了一個某長度的數組,若機器內存有限,我們需要一個很小的數組,若機器內存大一些,我們就需要一個大一點的數組)。
在編譯一個程序的時候如果要將一條語句或者一組語句編譯或者放棄是很方便的。可以用條件編譯指令。
常見的條件編譯指令:
#include指令可以使另外一個文件被編譯。
這種替換的方式:預處理先刪除這條指令,并用包含文件的內容替換。這樣一個源文件被包含幾次,那就實際被編譯幾次。
頭文件被包含的方式:
通常一個大型的項目會調用多個程序合并,那么如何避免頭文件的重復包含而提高效率呢?
常見的有一下兩種解決方法:
1.每個頭文件的開頭寫:
#ifndef __TEST_H__ #define __TEST_H__ //頭文件的內容 #endif
2.定義頭文件之前包含這一句話:
#pragma once
“C語言程序的編譯與預處理實例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。