A. 宏替換,宏展開到底分別在什麼時候進行
//在宏 使用的時候 分為
宏定義 和 宏展開, 你那個 宏替換就是展開
宏定義是你自己寫的 #define
然後展開在預編譯時候處理
這個時候編譯器先掃描一遍文件 把用到宏的地方都做字元替換
比如
#define M 1
int a = M;
那麼預編譯的時候就把 M 替換成1
注意宏只做文本替換,所以
比如 #define MUL(__x__, __y__) __x__ * __y__
int a = MUL(a + b, c+ d);
會被替換成 int a = a + b * c + d // 可能就會和初衷違背(如果你想做的是 (a + b) * (c + b))
從展開的角度來說 因為宏是可以嵌套的 所以宏在替換的時候 我們叫做展開
比如 做一個函數參數聲明
#define PARAMS_SET_1(__type__, __name__) __type__ __name__
#define PARAMS_SET_2(__type__, __name__) __type__ __name__##1, __type__ __name__##2
//... 定義N個 PARAMS_SET_N
#define PARAMS(__size__, __type__, __name__) PARAMS_SET_##__size__(__type__, __name__)
然後 定義函數
int foo(PARAMS(2, int, n));
那麼預編譯的時候宏會這樣展開
1, int foo(PARAMS_SET_2(int, n));
2, int foo(int n1, int n2);
另外注意就是編程的時候 由於宏只是文本替換,缺少類型檢測 以及運算順序這樣的功能,所以要少用宏
上面所有的宏都有替換的方案
#define M 1 替換方案
struct M
{enum {value = 1} };
int a = M::value;
#define MUL(__x__, __y__) __x__ * __y__ 替換方案
template<int x, int y>
struct MUL
{enum{value = x * y}};
int a = MUL<10 + 20, 10 + 30>::value;
最後一個PARAMS的替換方案就是函數重載
template<typename T>
int foo(T n1);
template<typename T>
int foo(T n1, Tn2);
//後面定義N個
B. 什麼是匯編程序,編譯程序,解釋程序分別說明他們的功能
【匯編程序】:把匯編語言書寫的程序翻譯成與之等價的機器語言程序的翻譯程序。
【編譯程序】:把用高級程序設計語言書寫的源程序,翻譯成等價的計算機匯編語言或機器語言的目標程序的翻譯程序。
【解釋程序】:對源程序邊解釋翻譯成機器代碼邊執行的高級語言程序。
高級語言的程序的執行的途徑:
1)源程序(高級語言)->【編譯程序】->目標程序(匯編語言)->【匯編程序】->目標程序(機器語言)->計算結果
2)源程序(高級語言)->【編譯程序】->目標程序(機器語言)->計算結果
3)源程序(高級語言)->【解釋程序】(逐條讀出源程序中的語句並解釋執行,即在解釋程序的執行過程中並不產生目標程序)->計算結果
C. 異常處理是在編譯時進行的
編譯時,不會處理程序的異常,只會處理程序的一些邏輯錯誤、語法錯誤等
D. 什麼是編譯程序 編譯程序的工作過程
編譯程序是變成語言在計算機上面運行的一種方式。
比如你現在編寫(編譯型語言)了你個程序文件並要運行它,但是計算機是不認識這個文件裡面的東西的(其實計算機只認識0和1這樣的數字),所以這里就需要把你自己寫的程序文件翻譯一遍,翻譯過後並生成一個計算機能夠識別的文件,把你原來的源文件翻譯成計算機能夠識別的文件的過程就叫編譯,其實計算機運行的真正文件是編譯過後的編譯文件。
E. C語言編譯系統對宏替換的處理是在什麼時候進行的
是正式工作開始之前的准備工作,所以宏替換是在對程序編譯之前進行的。
宏替換是C/C++的預處理中的一部分,對於宏定義中的形參,在替換列表中,如果不是作為#或##的操作數,那麼將對應實參完全展開(相當於對實參進行求值),然後將替換列表中的形參替換掉,如果是#或##的操作數。
(5)什麼是在程序編譯時進行的擴展閱讀:
宏的用途在於自動化頻繁使用的序列或者是獲得一種更強大的抽象能力。
計算機語言如C語言或匯編語言有簡單的宏系統,由編譯器或匯編器的預處理器實現。C語言的宏預處理器的工作只是簡單的文本搜索和替換,使用附加的文本處理語言如M4,C程序員可以獲得更精巧的宏。
宏的行為如同是函數對自身程序文本的變形,並且可以應用全部語言來表達這種變形。一個C宏可以定義一段語法的替換,然而一個Lisp的宏卻可以控制一節代碼的計算。
F. 程序執行的兩種方式是什麼分別是如何進行的,各有什麼特點
解釋執行和編譯執行
編譯方式是指利用事先編好的一個稱為編譯程序的機器語言程序,作為系統軟體存放在計算機內,當用戶將高級語言編寫的源程序輸入計算機後,編譯程序便把源程序整個地翻譯成用機器語言表示的與之等價的目標程序,然後計算機再執行該目標程序,以完成源程序要處理的運算並取得結果。
解釋方式是指源程序進入計算機後,解釋程序邊掃描邊解釋,逐句輸入逐句翻譯,計算機一句句執行,並不產生目標程序。
前者過程簡單,後者執行速度快
G. 什麼是編譯程序
編譯程序指將某一種程序設計語言寫的程序翻譯成等價的另一種語言的程序的程序, 稱之為編譯程序
編譯程序也稱為編譯器,是指把用高級程序設計語言書寫的源程序,翻譯成等價的機器語言格式目標程序的翻譯程序。編譯程序屬於採用生成性實現途徑實現的翻譯程序。
它以高級程序設計語言書寫的源程序作為輸入,而以匯編語言或機器語言表示的目標程序作為輸出。編譯出的目標程序通常還要經歷運行階段,以便在運行程序的支持下運行,加工初始數據,算出所需的計算結果。
編譯程序的實現演算法較為復雜,這是因為它所翻譯的語句與目標語言的指令不是一一對應關系,而是一多對應關系,同時也因為它要處理遞歸調用、動態存儲分配、多種數據類型,以及語句間的緊密依賴關系。
由於高級程序設計語言書寫的程序具有易讀、易移植和表達能力強等特點,編譯程序廣泛地用於翻譯規模較大、復雜性較高、且需要高效運行的高級語言書寫的源程序。
(7)什麼是在程序編譯時進行的擴展閱讀:
編譯流程分為了四個步驟:
1.預處理,生成預編譯文件(.文件)
2.編譯,生成匯編代碼(.s文件)
3.匯編,生成目標文件(.o文件)
4.鏈接,生成可執行文件
H. 給變數分配內存單元是在什麼時候進行的
這個涉及到局部變數還是全局變數的問題,函數中的變數屬於局部變數,所以再調用到之後才開辟內存空間,但局部變數所在函數調用完畢,局部變數就被取消了,然後所佔內存就被收回了。 而全局變數由於作用域很廣,一旦定義,編譯器就會分配內存,程序運行期間這塊內存單元一直有效,直到整個程序結束才由系統收回內存~~
I. C語言程序中的關於常量的計算是在編譯時進行的還是程序執行時進行的
編譯的時候,先會進行預編譯處理,就是把程序中所有的符號常量用數字常量替換,比如說你的例子中的N,注意只是發生替換,所有的計算都是在程序執行的時候進行的!
C是面向過程的,每次執行都會重新計算一次!
J. 請問java程序在編譯和運行時有什麼區別,系統分別都會做什麼
Java程序的編譯
使用命令: javac *.java
編譯時,會將寫的.java文件(高級語言),生成相應的位元組碼文件.class文件(二進制代碼)
Java程序的執行
使用命令:java *
流程: 載入到 -- 連接 ---- 初始化 ...
運行時,首先會由將相應的.class文件,載入到內存中,並驗證.class文件的有效性,將相應類的Class載入到內存中,並對類中的靜態變數進行初始化操作,然後就由 主 類開始執行
具體的可以看一下 JVM 類載入過程,以及jVM的內存分配機制