在上班時間看到這篇文章,就很想紀錄一下。底下會有link。
主要是看到一篇文章問,為何 #define do { ... } while ( 0 ) 跟inline會交叉互用,本來提問者以為是等同的意思。但以我對inline的初淺了解,inline內的code展開與否的決定權仍然在compiler上。#define則是前處理器要處理的,所以勢必得展開了。
問題來了,為何要用 #define do { ... } while ( 0 ) 這樣的方式去定義一個function呢?回答的前輩有趣得以一個問題當開頭:
假設一個function以#define來看
#define sq(a) (a*a)
int answer = sq(5); // 答案是 25
好像一般簡單的應用沒什麼問題,假設變成以下呢?
int answer = sq(5+1) // 答案不是 36 啊.....
因為基本上前處理器會幫我們展開,但是不會幫我們注意括號,因而變成 5 + 1 * 5 + 1 變成11了。
所以我們得注意#define時候括號的重要性。變成以下就不會產生錯誤的答案:
#define sq(a) ((a)*(a))
但是inline時候就不會發生這類的問題了。
回到此篇的主軸,為何要使用 #define do { ... } while ( 0 ) 去定義我們的函數呢?它是有其特殊意義的。
#define swap(x,y) { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; }
這樣的函數代入以下會如何呢?
if ( x > y )
swap(x,y);
else
otherthing();
展開它。
if ( x > y )
{ int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; };
else
otherthing();
聰明的你,發現問題了嗎?多出了一個分號!
if ( x > y ) {
int tmp_n ;
tmp_n = x
x = y
y = tmp_n;
}
; <---- 這邊多分號,慘了 ~~~~
else
otherthing();
這邊就會產生編譯錯誤了,所以才導入 #define do { ... } while ( 0 )來解決,此段程式碼就會變成:
if ( x > y )
do {
int tmp_n ;
tmp_n = x;
x = y;
y = tmp_n;
} while(0);
else
otherthing();
神奇吧!跟我一樣佩服這位前輩替咱們解惑吧!
出自:http://phorum.study-area.org/index.php?topic=56407.0
Enjoy it.
2013年9月23日 星期一
[ C# ] var 隱含型別
碰到C#後,有種型別叫做 var。此宣告後的變數型別會在編譯期決定。例如以下:
覺得蠻有感覺的一句話,型別 / 型態 是右式做決定的。至於 var 的功用、起源及優點等,網路上很多例子及樣板可以找到就不累述了。
Enjoy it.
- var intVar = 10;
- var strVar = "Hi";
- var charVar = 'C';
宣告完後,用GetType()方法取得Name屬性就可以知道在編譯期時,變數被宣告成哪種型別。
- Console.WriteLine( intVar.GetType().Name );
- Console.WriteLine( strVar.GetType().Name );
- Console.WriteLine( charVar.GetType().Name );
可以得到型別方別是: Int32 / String / Char。
我在找尋 var 型別的運用及範例時,看到由前輩分享的一句話:
右決議型別
覺得蠻有感覺的一句話,型別 / 型態 是右式做決定的。至於 var 的功用、起源及優點等,網路上很多例子及樣板可以找到就不累述了。
Enjoy it.
2013年9月22日 星期日
[ C# ] Null Type
[ C# ] 中實現 C/C++ System Pause 的方法
剛接觸 C# 不久,一開始的第一個Hello World 程式在按下F5(偵錯)之後一瞬即逝。人在電腦前待了幾秒才發現 C# 的主控台應用程式不會像 C / C++ 一樣自動生成 pause,且也無類似的方法可供呼叫。
幸好,google search後發現有啟動但不偵錯的方法:Ctrl + F5。
但畢竟是一個coder,就想找幾個實現他的方法。有以下兩種:
Call dll :
Enjoy it.
幸好,google search後發現有啟動但不偵錯的方法:Ctrl + F5。
但畢竟是一個coder,就想找幾個實現他的方法。有以下兩種:
Call dll :
- 在程式開頭加入 using System.Runtime.InteropServices;
- 然後 in class 內加入
- [DllImport( "msvcrt.dll" )]
- static extern bool system( string str );
Code :
- Console.Write( "Press any key to continue . . . " );
- Console.ReadKey( true );
Enjoy it.
訂閱:
文章 (Atom)