2013年10月9日 星期三

[ C# ] Call by Reference

    剛踏入C#的領域裡面,從C/C++這領域跳過來後。以前一直超常使用指標跟參考的我,頓時覺得要用到指標跟參考時還要特別選擇unsafe mode感覺有點雞肋阿。

    難道真的只有一種方法嗎?最近剛好找到關鍵字 ref,一個可以用在方法宣告上把參數變成傳址的方式。突然有點想哭的感覺,這就是熟悉感阿阿阿阿阿!!!


code :

  class Program
  {

    static void Main( string[] args )
    {

      int refValu = 0;

      PrintText( ref refValu );
      PrintText( ref refValu );
      PrintText( ref refValu );

      Console.ReadKey( true );

    }

    static void PrintText( ref int count )
    {

      Console.WriteLine( count );

      count++;

    }

  }

2013年10月2日 星期三

[ .NET ] Framework 筆記


CLS ( Common Language Specification ) : 一個微軟定義的語言規範。凡是符合此規範,理論上都可以互相叫用。

MSIL ( Microsoft InterMediate Language ) : 凡符合CLS規範的compiler, 會將其程式碼編譯成MSIL, 一種中介語言,需要再被編譯才可使用。

CLR ( Common Language Runtime ) : MISL還不能執行,需要透過CLR去執行。換句話說,CLR是微軟板的JVM。

CTS ( Common Type System ) : 共通型態系統。.NET語言所共用的資料型態,也是跨語言的重要關鍵。相同的資料型態可能在不同語言內有不一樣的大小。

JIT Compiler : Just in time顧名思義就是需要時才動作。包含在CLR裡面,提供.NET能夠執行最主要的功能。


     在CLR所運行中的程式,都叫做Managed Code, 不是在CLR運行就不是Managed Code,亦即是Unmanaged Code。將VB語言用符合CLS的編譯器編譯過後,就變成了VB.NET, ASP.NET相同亦是。

     Assembly = IL + Metadata
     
     IL會和Metadata一起被包含在Assembly裡面。Assembly可能是.exe or .dll 型態,是無法被執行的。需要第二次編譯,將裡面的IL程式碼,參考Metadata, 轉成原生碼。


整理網路上的資料,對自己學習希望有點幫助。

出自:倍力資訊。
http://www.mpinfo.com.tw/TechnologyColumnFiles/PB_T_201006.pdf



  

2013年9月23日 星期一

[ C / C++ ] #define do { ... } while ( 0 ) 為何而用?

    在上班時間看到這篇文章,就很想紀錄一下。底下會有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.


[ C# ] var 隱含型別

    碰到C#後,有種型別叫做 var。此宣告後的變數型別會在編譯期決定。例如以下:


  • 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++ 裡面還蠻常使用到 null,到了C#中發現一般的型態不能指定為null。如下:







    只要將 宣告式後加上? 例如 int? tempValue; 後便可指定null type給變數了。自然在VS上也看不到錯誤了。

    特別注意的是假設此型別本身支援null type就不能特別宣告了,因為本身已經支援。

    Enjoy it.

[ C# ] 中實現 C/C++ System Pause 的方法

    剛接觸 C# 不久,一開始的第一個Hello World 程式在按下F5(偵錯)之後一瞬即逝。人在電腦前待了幾秒才發現 C# 的主控台應用程式不會像 C / C++ 一樣自動生成 pause,且也無類似的方法可供呼叫。

    幸好,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.