C/C++中宏定義(#define)
#define是C語言中提供的宏定義命令,其主要目的是為程序員在編程時提供一定的方便,并能在一定程度上提高程序的運行效率,但學(xué)生在學(xué)習(xí)時往往不能 理解該命令的本質(zhì),總是在此處產(chǎn)生一些困惑,在編程時誤用該命令,使得程序的運行與預(yù)期的目的不一致,或者在讀別人寫的程序時,把運行結(jié)果理解錯誤,這對 C語言的學(xué)習(xí)很不利。
宏的定義在程序中是非常有用的,但是使用不當(dāng),就會給自身造成很大的困擾。通常這種困擾為:宏使用在計算方面。
本例子主要是在宏的計算方面,很多時候,大家都知道定義一個計算的宏,對于編譯和編程是多么的有用?,F(xiàn)在定義有以下一個計算 “乘法” 的宏。
#include <stdio.h>
#define MUL(a) ((a)*(a)*(a))
int main(int argc,char *argv[])
{
int i = 10;
int sum = MUL(i);
printf("MUL(%d) = %d\n",i,sum);
return 0;
}
</stdio.h>
上面程序的這種做法對于非負(fù)數(shù)而言那就是沒有問題的,比如,程序中的 變量 i=10,這個時候,調(diào)用宏得到的數(shù)據(jù)如下:
但是如何變量的數(shù)值是自加或者自減的操作的話,結(jié)果就不一樣了。
假如我們將上面的程序變?yōu)橄旅孢@樣的
#include <stdio.h>
#define MUL(a) ((a)*(a)*(a))
int main(int argc,char *argv[])
{
int i = 10;
int sum = MUL(++i);
printf("MUL(%d) = %d\n",i,sum);
return 0;
}
</stdio.h>
得到的結(jié)果并不是 11 * 11 *11 = 1331這個數(shù)據(jù),而是 1872,這時候有人會問為什么?
得到宏的朋友或者了解過宏在計算方面的朋友就會知道,這除了是宏的問題,還是本身程序員編寫這段代碼的問題。當(dāng)使用了 ++i 和 i++ 的時候,
要特別注意在宏中是全部使用 ++i或者i++的,變成的格式如下
MUL(i++) ((i++)*(i++)*(i++)) MUL(++i) ((++i)*(++i)*(++i))
上述的做法顯然不是我們想要的計算結(jié)果,可能在我們程序中看到的是MUL(++i) 或者 MUL(i++),認(rèn)為實際上是如下情況:
//當(dāng)i的初始化數(shù)值為10的時候,進行i++的 MUL(i++)宏計算,即是:int i = 10;
//MUL(i ++)的數(shù)值計算結(jié)果相比是 10 * 11 * 12的,這是沒有問題的,但是 i的值呢??是11嗎??顯然不是。 MUL(i++) = 10 * 11 *12;i = ??;
i的數(shù)值如下圖所示
誠然,i的數(shù)值變成了 13,這是為什么呢??
那就是因為這個MUL(a)這個宏和程序員的 “自加自減” 操作所造成的。這里先普及一下 C/C++語言的 “自加自減” 操作:
//自加自減的操作
i++ 和 ++i ----> 這里的操作屬于++后操作,可以替換成 i = i+1 的結(jié)果。
但是,當(dāng)它賦值給一個變量的時候,表示的內(nèi)容和含義就有不同: (假設(shè)i = 10)
1. sum1 = i++;
2. sum2 = ++i;
1中的sum1的數(shù)值就是 10, i為 11
2中的sum2的數(shù)值就是 11, i為 11
這是因為:
i++ 操作是 先賦值給 sum1后,自己在執(zhí)行 i = i+1的操作
++i 操作是 先進行 i = i+ 1的操作,然后再賦值給sum2
這樣得到的結(jié)果當(dāng)然不同了,但是i最終的結(jié)果是要加1的,只不過是賦值給變量的時候會有不同
通過對自加自減的操作進行說明,不知道大家是否明白為什么了嗎??
當(dāng) i = 10的時候,MUL(i++)就是為 (i++)*(i++)*(i++)的計算結(jié)果,考慮到C/C++的運算符結(jié)合性,
先計算第一個 i++,這是一個先計算后賦值的自加方式,那么這是后第一個 (i++)的數(shù)值待定為 10 ,那么第
二個的i是因為第一個數(shù)據(jù)的 (i++)起了作用而變化的,這時候第二個(i++)的數(shù)值為11,然后加1,這時候 根
據(jù)結(jié)合性,先計算前面兩個數(shù)據(jù),就是(i++) * (i++)的數(shù)值了,即為:10 * 11了,這時候的i數(shù)值是 12;
然后計算第三個 i++的數(shù)值,這時候第三個i++中的i數(shù)值為 12,計算后再加1,也就是說,10 * 11 * 12之后,
i= 12 的數(shù)值在進行i++變?yōu)?13了。所以 MUL(i++) = 10 * 11 * 12 = 1320?! ?/p>
另外,在進行++i的操作和上述的情況差不多,只不過是先做自加的運算,在進行賦值。
當(dāng) i = 10的時候,MUL(++i)實際上也為 (++i)*(++i)*(++i)的方式,這時候先計算第一個 (++i),這是一
個先計算后賦值的結(jié)合方式,那么 i = i+1 = 11;這時候準(zhǔn)備計算第二個(++i)的時候,因為需要先計算后賦值,
所以 第二個 ++i 之后的數(shù)值為12,但是因為i屬于同一個變量和屬性,那么第一個i也會變成 12了,這時候結(jié)合性
考慮應(yīng)該是計算前兩個(++i)的結(jié)果,再與第三個(++i)計算,即(++i)*(++i) = 12 * 12;然后,我們計算第三個
(++i)的數(shù)值,由于前面第二個++i的i值,所以第三個++i即為 13,此時,12 * 12 * 13。
有人可能顧慮,為什么最后不是13 * 13 * 13的呢?那不是最后都是13嗎?? ------》其實這種想法是錯誤的,
這必須先理解運算符的結(jié)合性。我們知道,當(dāng)計算中遇到了括號的時候,我們先計算括號的內(nèi)容,這是我們在數(shù)學(xué)中的慣性思維。但是對于計算機而言,計算機必須 有計算的優(yōu)先級,也就是運算符的優(yōu)先級問題。首先我們計算前面兩個括號的內(nèi)容,以為兩個括號之間有乘號(*),所以計算前面兩個(++i)之后,必須進行乘法計算,這就是優(yōu)先級中的乘法計算,自左向右計算。所以結(jié)果變?yōu)榱?12 * 12的最終結(jié)果在和第三個括號的(++i)計算,就是144 * (++ i) = 144 * 13;
所以MUL(++i)的結(jié)果如下:
總結(jié):
慎用宏在計算方面的,但是宏的有點還是很多的,對于C語言來說,宏可以減少運行的時間。在C++中,宏由于不會對類型進行檢查,安全性不夠,所以建議使用const來
進行使用,這樣可以保證類型一致。這是C/C++對宏的嚴(yán)謹(jǐn)性進行優(yōu)化的結(jié)果。
以上所述是小編給大家介紹的C/C++中宏(#define)定義知識,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對我們網(wǎng)站的支持!
上一篇:C/C++函數(shù)參數(shù)傳遞機制詳解及實例
欄 目:C語言
下一篇:C++ primer基礎(chǔ)之容器insert
本文標(biāo)題:C/C++中宏定義(#define)
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/1745.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實現(xiàn)與遞歸實現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點數(shù)在內(nèi)存中的存儲方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10C#中split用法實例總結(jié)
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10使用C語言求解撲克牌的順子及n個骰子


