⑴ c語言中x*(y)+z和x*y+z 的區別
這是宏替換的特點!
宏替換是在編譯時,將源程序中與宏定義符合的代碼進行「傻瓜」式替換。
如:
#define MAX(x,y,z) x*(y)+z
printf("%d/n", MAX(a+b.b+c,c+a) ); 在編譯時替換成printf("%d/n", a+b*(b+c)+c+a );
而
#define MAX(x,y,z) x*y+z
printf("%d/n", MAX(a+b.b+c,c+a) ); 在編譯時替換成printf("%d/n", a+b*b+c+c+a );
可見兩個表達式在編譯後的結果是不同的,因而結果不同!
⑵ c語言中宏替換時先求出實參表達式的值,然後再帶入形參中運算求值,對不對啊為什麼啊
不是這樣的,宏替換是在預編譯時將整個宏的表達式進行替換再進行編譯的,舉個例子講如果你定義了如下宏:
#define fun(a) (a*a)
下面用的時候
int main()
{
int i = 5, j = 4;
int k = fun(i+j)
}
那麼在預編譯時首選會先將fun(i+j)替換成 i+j*i+j,即此時計算的時候會先算乘法i*j,那麼k的值最終就是5+4*5+4 = 29,而不是(i+j)*(i+j)=81,當然如果你想實現後一種結果,則宏定義方法應該是下面這樣的
#define fun(a) ((a)*(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個
⑷ C語言中,下面有關宏替換的敘述中,不正確的是
宏替換是在預編譯時完成的,預編譯的功能是將頭文件引入,並且將定義的宏按字面完成「傻瓜」式替換(即將符合宏的樣式的字元串,替換成宏定義的字元串),宏名沒有類型區分,它只是個字元串。因此,D是錯的
⑸ 宏替換是在程序編譯時完成的,不佔用程序運行時間
是正確的,編譯時預處理,不分配內存空間
⑹ C語言編譯系統對宏替換的處理是在什麼時候進行的
是正式工作開始之前的准備工作,所以宏替換是在對程序編譯之前進行的。
宏替換是C/C++的預處者遲橋理中的一部分,對於宏定義中的形參,在替首猛換列表中,如果不是作為#或##的操作數,那麼將對應實參完全展旦高開(相當於對實參進行求值),然後將替換列表中的形參替換掉,如果是#或##的操作數。
(6)宏替換是在編譯擴展閱讀:
宏的用途在於自動化頻繁使用的序列或者是獲得一種更強大的抽象能力。
計算機語言如C語言或匯編語言有簡單的宏系統,由編譯器或匯編器的預處理器實現。C語言的宏預處理器的工作只是簡單的文本搜索和替換,使用附加的文本處理語言如M4,C程序員可以獲得更精巧的宏。
宏的行為如同是函數對自身程序文本的變形,並且可以應用全部語言來表達這種變形。一個C宏可以定義一段語法的替換,然而一個Lisp的宏卻可以控制一節代碼的計算。
⑺ 宏替換只是字元替換,不佔用編譯時間是不是正確
宏是在預編譯期間進行的,將代碼中的指定字元轉換
轉換結束後,再進行編譯
所以不佔用編譯時間