<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 56,  comments - 12,  trackbacks - 0
                                      1 緒論
    c# 是一種簡練,時髦(?),面向對象(object oriented),類型可靠(type-safe)的
    編程語言。它(發音:C sharp)是從c/c++發展而來的(?俺覺得更象是java),和c/c++
    是一個語系。所以,很容易被c/c++的程序員接受。c#的目標是結合Visual Basic的高產和
    C++質樸的力量。

    c#將會是vs7的一分子。vs7還支持vb,vc和標記語言——VBScript和JScript。所有這些語言
    都會在Next Generation Windows Services (NWGS) platform 中得到支持(c#就需要一個
    NWGS SDK包,可以在m$的網站上下載)。有了這個東東(NWGS),c#就不需要自己的類庫,
    而使用vc或vb這樣一些成熟的庫。c#也確實沒有自己的類庫。
    廢話完了。

    1。1 一個老土的例子(就不能換換嗎?)*/
    /* idontlikeHelloworld.cs : such a out sample :( */
    1: using System;
    2: class idontlikeHelloworld
    3: {
    4: static void Main() {
    5: Console.WriteLine("i dont like Hello world");
    6: Console.ReadLine();
    7: }
    8: }
    /* 如果俺要出書的話,會考慮換個好點的例子。 ^&^

    先說說怎樣運行。首先,你需要windows2000!(是的,就是它,請各位不要隨地丟果皮——
    整個香蕉丟給俺就可以了。)然后,需要NWGS SDK!(82.4mb,不算很大噢。嘿嘿,好在
    它沒有自己的類庫。)安裝后,在你的程序所在的目錄下鍵入:

    csc idontlikeHelloworld.cs (加上一個回車鍵)

    是不是有點復古的味道?這個操作會在和你的*.cs相同目錄下產生一個
    idontlikeHelloworld.exe文件。雙擊它,距可以看見:

    i dont like Hello world

    回車就可以結束它,非常簡單。不過,也可以這樣:把它存成后綴為.c的文件更好
    (即:idontlikeHelloworld.c)。這樣就可以用vc的IDE進行打字,編輯。vc的
    txt editor是最棒的噢(又要vc,NO!!!)。然后:

    csc idontlikeHelloworld.c (加上一個回車鍵)

    最終效果是完全一樣的。好,現在分析語法:(c#在語法上完全沒有新意 :-| )

    1: using System;

    using 其實是c++的關鍵字,在c#中的含義也相仿(就是說俺還不敢100%肯定,抱歉)。using
    用在另一個關鍵字namespace之后。還是先看看namespace。
    語法(syntax):(from MSDN)

    namespace [identifier] { namespace-body }

    俺的理解:
    identifier:在這里就是System(請記住:c#和c/c++一樣,是區分大小寫的!)。System
                必須在使用它的范圍內是唯一的。即,不能夠有第二個System,但可以有system。
                而“它的范圍”,俺不想詳細解說,只有在實踐中才可能掌握。而且,初學者根本
                不必知道!俺也是近來才知道還有個namespace和using。 :)

    在{ namespace-body }中的是真正有用的東東,包括第五行的“Console.WriteLine”的聲明和
    定義(后面還會提到)。System是由NWGS定義的,咱們只需用(using)它即可。至于System在
    什么文件里定義,咱就不用管了!交給編譯器(就是剛才那個“csc.exe”)去尋找。這就代替
    了c/c++中的“#i nclude”,可以說是近了一步,避免大量煩人的細節。如果你沒學過c/c++,
    就不用理會。namespace 在后面還會談到。

    2: class idontlikeHelloworld

    class:是c語系中另一個關鍵字“類”。表示一系列的特性(官方說法:屬性)和行為方法,有
    了它你的程序就可以“另類”,創造與別不同的有你特色的東東噢!在這里,俺就定義了
    “idontlikeHelloworld”。注意:這也是c#強制的,對于每一個可執行的程序都必須有。你想干
    的事就可以記錄在緊跟著你定義的class后面的一對花括號。注意:“{”和“}”一一對應的,
    “(”和“)”同樣。

    4: static void Main() {

    Main()是本例子第一個動作(行為方法),干的第一件事。它是屬于俺定義的idontlikeHelloworld
    類的方法。并且是c#強制的,是程序的真正開始!在緊跟在它后面的“{}”中的語句順序,就是程序
    的運行順序!本例中只有一行(第六行干嘛用?你可以去掉再編譯一次看看),輸出一句話。

    5: Console.WriteLine("i dont like Hello world");

    非常奇怪,Console(再次提醒:注意大小寫)不是俺定義的,從何而來?它其實是屬于System
    namespace 的一個class。WriteLine()是Console類中的一個方法,用來顯示一句話(字符串)。
    這里只是用了這個方法的1/18!并且是最簡單之一!其他的有機會再說。你也可以用
    “Console.WriteLine”在“NGWS SDK Documentaion”中搜索“Console.WriteLine”,記住復選
    “僅搜索標題”,它會列出19項。好啦,完了!其實,還有“.”沒說呢!呵呵...lei si la!!!!
    (續前)
    “.”被稱為分隔符(separator),用來連接名字,如上面的“Console.WriteLine”,就把類和它的
    方法連接。通過這種方式,咱們就可以使用現成方法集合。這里再回顧一下俺的例子,看看namespace和
    “.”是如何連用的,還有為什么要使用namespace這個關鍵字。把例子稍微改一下:*/
    /* idontlikeHelloworld.cs */
    1: //using System;
    2: class idontlikeHelloworld
    3: {
    4: static void Main() {
    5: System.Console.WriteLine("i dont like Hello world");
    6: System.Console.ReadLine();
    7: }
    8: }

    /* 看見了,當俺注銷掉“using System;”后,在第五行和第六行加了“System”。程序的結果不會改
    變。但是,很明顯的這樣比較羅嗦,所以引入了“namespace”。其實,class應該可以完成同樣的功能。
    不過,設計者可能不想讓一個關鍵字涵蓋太多的功能。記得在c向c++發展的時候,引入了“class”,而
    不是擴展“struct”關鍵字的功能;又比如“=”只用于賦值,“==”只用于判斷相等。這是c/c++和c#
    在語法上其中一個重要的特點。這樣設計的好處很多。有機會再聊噢。
    如果你沒學過c/c++,以下的內容可以跳過。c#與c/c++在語法上還是有區別的,比如:
    1。c#根本沒有“::”;“->”只在程序中很小的片斷中。在c#中應采用“.”。
    2。c#無須先聲明定義,再使用。與java相同。
    3。c#取消了用“#i nclude”導入其他的程序文本文件,而采用象征性的句柄引入他人的代碼。這樣一來,
       就排除了編程語言間的障礙,方便地使用其它語言編寫的庫。如“Console”類可以是c#或者是其他任一種語言編寫的。

    1。2 自動化的內存管理(Automatic memory management)
    手動管理內存需要程序員自行分配和釋放內存塊。這要求程序員有清晰的頭腦和對整個運行過程有十分的
    把握(好難!)。而c#把程序員從這難以承擔的任務中解放出來。在多數的情況下,這種自動內存管理提
    高代碼的質量和程序員的生產力。并且,不會對程序的意圖和執行產生幅面的影響(?俺可不相信m$的鬼
    話)。不過,估計比java的回收站好一點吧。因為c#出道遲嘛(盡胡扯)。好了,來看看例子。*/

    using System;
    public class Stack
    {
      private Node first = null;
      public bool Empty {
        get {
              return (first == null);
            }
      }
      public object Pop() {
        if (first == null)
          throw new Exception("Can't Pop from an empty Stack.");
        else {
                object temp = first.Value;
                first = first.Next;
                return temp;
             }
      }
      public void Push(object o) {
        first = new Node(o, first);
      }
      class Node
      {
        public Node Next;
        public object Value;
        public Node(object value): this(value, null) {}
        public Node(object value, Node next) {
          Next = next;
          Value = value;
        }
      }
    }

    class Test
    {
      static void Main() {
        Stack s = new Stack();
        for (int i = 0; i < 10; i++)
          s.Push(i);
        while (!s.Empty)
          Console.WriteLine(s.Pop());
      }
    }
    /*
    stack類實現了一系列Node的實例。大家可以看看stack類的Push方法。Node的實例就是在Push方法中創建的。
    就是“first = new Node(o, first);”。請記住這個“new”噢。它就是用來創建類實例的。相關的語法太
    多,遛到后面用一節詳細講。這里只是要了解自動內存管理(Automatic memory management)好處?!“new”
    是負責初始化類實例。而在c/c++中釋放這些實例要用另一個關鍵字“delete”。但是在什么時候用delete呢,
    這通常是很費神的活,老手也會陰溝里翻船。何況是俺呢!但在c#中有不用了。例子里就沒有用“delete”。
    當Node的實例不需要時,垃圾收集器(garbage collector)自動銷毀它,不用俺操心嘍。這點到和java挺
    像的(可能是抄的)。

    在一個test類里,俺用了一個循環,對stack類的實例的Push方法賦值十次。于是,Push創建了Node的十個實
    例(instance)。然后用Pop把它們顯示出來。其順序正好與創建的順序相反。
    這個例子相當的好,是stack
    的一個典型,也很好的表述了自動內存管理的機制。但也不好懂,好在這一節不是寫給毫無基礎的網友看的。
    俺自個都花了幾分鐘看明白,各位大蝦更是沒問題。

    其實,當顯示完了“10”以后,就會有一個Node的實例符合被釋放的條件,但垃圾收集器并不一定會這樣做。
    也就是說,它的行為并不確定(這和java一樣,俺猜)。有時候,這種行為會帶來一些負面影響。起碼是性
    能降低。自動內存管理本身也是有問題的。因為它很難管理一些特殊情況。有一些關于java的垃圾收集器的
    文章也有提到。m$也不會好得了多少。所以,m$有個不安全代碼的術語(unsafe code),用來為高級用戶服
    務。即,用戶可以不采用垃圾收集器。但必須用“unsafe”關鍵字顯式聲明之。這樣就避免了用戶不經意以
    外使用不安全代碼。下面是一個例子:*/

    using System;
    class Test
    {
      unsafe static void WriteLocations(byte[] arr) {
        fixed (byte *p_arr = arr) {
          byte *p_elem = p_arr;
          for (int i = 0; i < arr.Length; i++) {
            byte value = *p_elem;
            string addr = int.Format((int) p_elem, "X");
            Console.WriteLine("arr[{0}] at 0x{1} is {2}", i,  addr, value);
            p_elem++;
          }
        }
      }
      static void Main() {
        byte[] arr = new byte[] {1, 2, 3, 4, 5};
        WriteLocations(arr);
      }
    }
    /*
    俺對這個例子不是很滿意,也讓俺有點迷惑,有機會再自己寫一個。很簡單,只是可以用指針了!萬歲!
    其實,俺對這一節最沒有把握了!有不少地方都不能自圓其說!所以,請各位大蝦大力批評。*/

    1。3 類型 
    c#支持兩種基本的類型:一種是值(value types),一種是引用(reference types)。值包括簡單類型
    (char、int、和float),枚舉(enum)和結構(struct)。引用包括類(class),界面(interface),
    代表(delegate)和數組陣列(array)。值與引用不同之處在于:值直接存儲它的數據內容;而引用存儲對象
    的引用。是不是粉費解?!打個比方吧。你在某地買了套別墅(好棒噢)。卻從未去過,只知道地址,怎
    么辦?你可以坐出租車,司機看了地址就知道怎樣走不用你操心。你手里的地址就好像對象的名字,你把
    它寫在程序中,就好像把地址給了司機。司機就是你的編譯器,它知道該去哪。你豪華的房子就好比那個
    NGWS SDK開發包(82mb噢,夠豪華了!俺的m啊--就這樣燒嘍)。房子里有你想要的東東,比如你想寫一句
    話(i dont like Hello world),就好像上面例子,要用到“WriteLine”。于是,你就給出“WriteLine”
    的地址,比如:“Console.WriteLine”。明白?!俺可累了。zzz...  (強打精神)不知道你想到沒有,
    值和引用的區別可以引出一個重要特性。值的變量和變量存儲的數據是一一對應的,唯一性。而引用則不
    然。引用中不同的變量可以引用同一個對象的實例。當其中一個變量改變實例的值時,其他引用這個實例的
    變量也會受到影響(當然,變量本身并沒有改變,即,地址沒變)。瞧,變量只是說明存儲對象的位置(地
    址),而不是對象本身。就好像你漂亮的房子被燒了,但你的地址并沒有改變,但地址對應的房子就沒了。
    也許是別人也有這個地址,他去燒了你的房子!好了,在給個例子:*/

    1: using System;
    2: class CValue
    3: {
    4: public int Value = 0;
    5: }
    6: class Test
    7: {
    8: static void Main() {
    9: int val1 = 0;
    10: int val2 = val1;
    11: val2 = 123;
    12: CValue ref1 = new CValue();
    13: CValue ref2 = ref1;
    14: ref2.Value = 123;
    15: Console.WriteLine("Values: {0}, {1}", val1, val2);
    16: Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
    17: }
    18: }

    /* 下面是輸出的結果:
    Values: 0, 123
    Refs: 123, 123

    啊哈,應該粉清楚了吧。變量val1和變量val2互不影響,它們各自有自己的存儲空間。而ref2復制
    了ref1,所以,它們引用了同一個對象的實例。當改變它們其中一個的時候,就會影響到另一個的
    值。
    1。5 數組類型(Array types) 

    數組可以是一維的,也可是多維的。數祖的成員可以是整齊的,也可以是變長(jagged)的。

    一維的數組是最普通,最簡單的。這里值給出一個例子,就不多解釋了。*/
    using System;
    class Test
    {
     static void Main() {
      int[] arr = new int[5];
      for (int i = 0; i < arr.Length; i++)
       arr[i] = i * i;
      for (int i = 0; i < arr.Length; i++)
       Console.WriteLine("arr[{0}] = {1}", i, arr[i]);
     }
    }

    /* 結果如下:
    arr[0] = 0
    arr[1] = 1
    arr[2] = 4
    arr[3] = 9
    arr[4] = 16

    我們還可以比較的看看多維,規則,變長的數組的定義和賦值:*/
    class Test
    {
     static void Main() {
      int[] a1 = new int[] {1, 2, 3};                     //一維
      int[,] a2 = new int[,] {{1, 2, 3}, {4, 5, 6}};      //二維
      int[,,] a3 = new int[10, 20, 30];                   //三維
      int[][] j2 = new int[3][];                          //變長
      j2[0] = new int[] {1, 2, 3};
      j2[1] = new int[] {1, 2, 3, 4, 5, 6};
      j2[2] = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
     }
    }
    /*
    上面的例子給出了各種樣式的數組。變量a1、a2和a3是規則數組。j2則是變長的數組。
    規則數組很容易就可以計算出它們的長度。比如a3的長度是:10*20*30=6000。相反,變長
    數組就有點不同,它的每一個維度都必須單獨定義。如j2的第一維度是3,第二個是6,第
    三個是9,所以總長度是:1*3+1*6+1*9=18。

    上面對數組的賦值是嚴謹的風格,在某種情況下,我們可以簡化寫法,但我總覺得這種簡化
    應用限制太多,容易出錯。在這里就不作介紹了。這里再給一個例子說明函數中的參數如何
    賦值*/
    class Test
    {
     static void F(long[] arr) {}
     static void Main() {
      F(new longt[] {1, 2, 3});
     }
    }
    趕出一編!請指正! 
    1。6 統一系統類型(Type system unification)
    c#獨創了一種類型——統一系統類型(為了這個累刑,我頭疼死了。誰有更好的名字,請務必告訴
    我)。總之,所有的其他類型,包括值和引用,都可以被當作統一系統類型來對待。從概念上說,
    所有的類型都從它派生。這樣,其他的類型就可以使用統一系統類型的屬性和方法。包括一些“簡
    單”類型,如:int。還是給個例子吧:*/
    using System;
    class Test
    {
      static void Main() {
        Console.WriteLine(3.ToString());
      }
    }
    /*“3.ToString()”調用了object的“ToString()”方法。相信學過c/c++的朋友都知道要輸出一個
    數字有多麻煩,現在就省事了。再看一個:*/
    class Test
    {
      static void Main() {
        int i = 123;
        object o = i;    // boxing
        int j = (int) o;  // unboxing
      }
    }
    /* 這個像帽子戲法的例子中,從“int”轉換成“object”,又轉換回來。這樣一來,在值和引用
    之間就架起了一座橋梁。這樣有什么用呢。即興舉一個常見的例子...就min把。在c/c++中:*/
    // c/c++ code

    void min(int i, int j)
    {
      return ((i < j) ? i : j);
    }

    /* 如果比較的不是int,或者說可能是int,也可能是float、double呢?可以這樣:*/

    template<class T>
    T min (T i, T j)
    {
      return ((i < j) ? i : j)
    }

    /* 用c#可以:*/
    void swap (object a, object b)
    {
      return ((i < j) ? i : j);
    }

    /* 我想大家一定看出來第二個例子要比較一個int和一個float的話,還需要一些轉換,而第三個
    例子就可以比較所有的變量!這個靈活度簡直太大了。所以,我私以為,大家使用時一定要小心!
    它在比較一個int和一個class的時候決不會報錯的。呵呵,我發現我的翻譯總是越跑越遠,總是
    扣不住原文。篡改甚多,敬請原諒!
     
    1。7 語句(Statements) 

    c#借用了c/c++大多數的語句方法,不過仍然有些值得注意的地方。還有些地方是有所改動的。
    在這里,我只提一些c#特有的東東。

    1。7。10 “foreach”語句
    “foreach”語句列舉一個集合內的所有元素,并對這些元素執行一系列的操作。還是看看例子吧:*/

    using System;
    using System.Collections;
    class Test
    {
      static void WriteList(ArrayList list) {
        foreach (object o in list)
        {
          int i = (int) o;//如果是for語句,這里一定會報錯!
          Console.WriteLine(0);
          Console.WriteLine(++i);
        }
      }
      static void Main() {
        ArrayList list = new ArrayList();
        for (int i = 0; i < 10; i++)
          list.Add(i);
        WriteList(list);
      }
    }
    /*這個例子用“foreach”掃描了整個“list”,并把“list”中所有的元素打印出來。有時候還是
    挺方便的。

    1。7。15 安全檢查開關(The checked and unchecked statements)
    “checked”和“unchecked”語句用來控制數學運算和完整類型轉換的檢查工作。“checked”檢查它
    作用的域中可能出現的違例,并拋出一個異常;而“unchecked”則阻止所有的檢查。舉個例子:*/

    using System;
    class Test
    {
       static int x = 1000000;
       static int y = 1000000;
       static int F() {
          checked {return (x * y);}     // 拋出 OverflowException
       }
       static int G() {
          unchecked {return (x * y);}   // 返回 -727379968
       }
       static int H() {
          return x * y;              // 缺省狀態。
       }
       static void Main() {
         F();                        //可以注銷掉此行試試。
         Console.WriteLine(G());
         Console.WriteLine(H());
       }
    }

    /*
    在編譯過程中不會有任何錯誤出現。因為“checked”和“unchecked”只在運行時才起作用。值得一說的是
    H()。它的缺省狀態和編譯器當前的缺省溢出檢查的狀態有關。但返回的結果肯定和F()或G()中的任一個相同。
    再看一個例子:*/

    using System;
    class Test
    {
       const int x = 1000000;
       const int y = 1000000;
       static int F() {
          checked {return (x * y);}    // 編譯器警告(Compile warning):溢出(overflow)
       }
       static int G() {
          unchecked {return (x * y);}  // 返回 -727379968
       }
       static int H() {
          return x * y;                // 編譯器警告(Compile warning):溢出(overflow)
       }
       static void Main() {
         Console.WriteLine(F());       //可以注銷掉此行試試。
         Console.WriteLine(G());
         Console.WriteLine(H());       //可以注銷掉此行試試。
       }
    }

    /* 當F()和H()求值的時候,就會引起一個編譯警告。而在G()中,因為有了“unchecked”,屏蔽了這個警
    告。要注意的是“checked”和“unchecked”都不能對函數的返回值進行操作!比如:*/
    class Test
    {
       static int Multiply(int x, int y) {
          return x * y;
       }
       static int F() {
          checked{ return Multiply(1000000, 1000000); } // 與 return Multiply(1000000, 1000000);
       }                                                // 有相同的效果。
    }
    /* 其實大家稍微想一下知道為什么m$沒有這么做!對這個內容的討論超出本文的范圍和俺的能力之外哦。

    在c#中,所有的十六進制數都是uint。如果用強制類型轉換會引起編譯器報錯。用“unchecked”則可以
    跳過這個機制,把uint的十六進制數轉化為int。如:*/

    class Test
    {
       public const int AllBits = unchecked((int)0xFFFFFFFF);
       public const int HighBit = unchecked((int)0x80000000);
    }

    /* 上例所有的常數都是uint,而且超過了int的范圍,沒有“unchecked”,這種轉換會引發一個編譯器錯
    誤。注意:上面用的是“unchecked”操作符。不是語句。不過它們之間除了一個用“()”,另一個用
    “{}”以外,幾乎一樣。BTW,“checked”同樣。

    1。7。16 “lock”語句(The lock statement)
    “lock”獲得一個相互排斥的對象鎖定。(俺查過一些資料,但都沒有清晰說明,暫不介紹)


    苦笑枯 2007-01-19 00:14 發表評論

    文章來源:http://www.tkk7.com/kuxiaoku/articles/94806.html
    posted on 2007-01-19 00:14 苦笑枯 閱讀(315) 評論(0)  編輯  收藏 所屬分類: C#
    收藏來自互聯網,僅供學習。若有侵權,請與我聯系!

    <2007年1月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(2)

    隨筆分類(56)

    隨筆檔案(56)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲国产成人久久综合区| 成人毛片手机版免费看| 亚洲人成人无码网www电影首页| 国产成人 亚洲欧洲| 免费看男女下面日出水视频| 亚洲av第一网站久章草| 国产无遮挡吃胸膜奶免费看视频| 国产成人亚洲精品电影| 又色又污又黄无遮挡的免费视| 亚洲Av无码国产一区二区| 永久免费av无码网站大全| 国产大陆亚洲精品国产| 亚洲国产精品自产在线播放| 丁香花在线观看免费观看图片 | 精品国产综合成人亚洲区| 七次郎成人免费线路视频| 国产亚洲美女精品久久久2020| 国产午夜成人免费看片无遮挡 | 午夜电影免费观看| 国产午夜亚洲精品不卡| 国产成人精品亚洲精品| 国内精品一级毛片免费看| 亚洲伦理中文字幕| 又大又黄又粗又爽的免费视频| 色www永久免费网站| 亚洲国产情侣一区二区三区| 国产精品无码一区二区三区免费| 边摸边吃奶边做爽免费视频99| 亚洲熟妇av一区二区三区漫画| **aaaaa毛片免费| 亚洲.国产.欧美一区二区三区| 亚洲精品NV久久久久久久久久| 免费91最新地址永久入口| 亚洲va成无码人在线观看| 亚洲国产精品毛片av不卡在线| 久操免费在线观看| 亚洲av午夜国产精品无码中文字| 亚洲真人无码永久在线| 青娱乐免费视频在线观看| 永久免费无码网站在线观看个 | 亚洲AV噜噜一区二区三区|