官术网_书友最值得收藏!

3.3 變量

如前所述,變量關系到數據的存儲。實際上,可以把計算機內存中的變量看成架子上的盒子。在這些盒子中,可以放入一些東西,再把它們取出來,或者只是看看盒子里是否有東西。變量也是這樣,數據可放在變量中,可以從變量中取出數據或查看它們。

盡管計算機中的所有數據事實上都是相同的東西(一組0和1),但變量有不同的內涵,稱為類型。下面再用盒子來類比,盒子有不同的形狀和尺寸,某些東西只適合放在特定的盒子中。建立這個類型系統的原因是,不同類型的數據需要用不同的方法來處理。將變量限定為不同的類型可以避免混淆。例如,組成數字圖片的0和1序列與組成聲音文件的0和1序列,其處理方式是不同的。

要使用變量,需要聲明它們,即給變量指定名稱和類型。聲明變量后,就可以把它們用作存儲單元,存儲所聲明的數據類型的數據。

聲明變量的C#語法是指定類型和變量名,如下所示:

        <type> <name>;

如果使用未聲明的變量,代碼將無法編譯,但此時編譯器會告訴我們出現了什么問題,所以這不是一個災難性錯誤。另外,使用未賦值的變量也會產生一個錯誤,編譯器會檢測出這個錯誤。

3.3.1 簡單類型

簡單類型就是組成應用程序中基本構件的類型,例如,數值和布爾值(true或false)。與復雜類型不同,簡單類型沒有子類型或特性。大多數簡單類型都是存儲數值的,初看起來有點奇怪,使用一種類型來存儲數值不可以嗎?

有很多數值類型是因為在計算機內存中,把數字作為一系列的0和1來存儲。對于整數值,用一定的位(單個數字,可以是0或1)來存儲,用二進制格式來表示。以N位來存儲的變量可以表示任何介于0到(2N_1)之間的數。大于這個值的數因為太大,所以無法存儲在這個變量中。

例如,有一個變量存儲了兩位,在整數和表示該整數的位之間的映射應如下所示:

        0 = 00
        1 = 01
        2 = 10
        3 = 11

如果要存儲更多數字,就需要更多的位(例如,3位可以存儲0到7的數)。

這樣得到的結論是要存儲每個可以想象得到的數,就需要非常多的位,這并不適合PC。即使可以用足夠多的位來表示每一個數,用這么多的位存儲一個表示范圍很小的變量(例如0到10)的效率非常低下,因為存儲器被浪費了。其實表示0到10之間的數,4位就足夠了,這樣就可以用相同的內存空間存儲這個范圍內的更多數值。

相反,許多不同的整數類型可用于存儲不同范圍的數值,占用不同的內存空間(至多64位),這些類型如表3-1所示。

表3-1 整數類型

注意:這些類型中的每一種都利用了.NET Framework中定義的標準類型。如第1章所述,使用標準類型可以在語言之間交互操作。在C#中這些類型的名稱是Framework中定義的類型的別名,表3-1列出了這些類型在.NET Framework庫中的名稱。

一些變量名稱前面的“u”是unsigned的縮寫,表示不能在這些類型的變量中存儲負數,參見表3-1中的“允許的值”一列。

當然,還需要存儲浮點數,它們不是整數。可以使用的浮點數變量類型有3種:float、double和decimal。前兩種可以用+/-m×2e的形式存儲浮點數,m和e的值因類型而異。decimal使用另一種形式:+/-m×10e。這3種類型、m和e的值,以及它們在實數中的上下限如表3-2所示。

表3-2 浮點類型

除數值類型外,另外還有3種簡單類型,如表3-3所示。

表3-3 文本和布爾類型

注意組成string的字符數量沒有上限,因為它可以使用可變大小的內存。

布爾類型bool是C#中最常用的一種變量類型,類似的類型在其他語言的代碼中非常豐富。當編寫應用程序的邏輯流程時,一個可以是true或false的變量有非常重要的分支作用。例如,考慮一下有多少問題可以用true或false(或yes和no)來回答。執行變量值之間的比較或檢查輸入的有效性就是后面使用布爾變量的兩個編程示例。

介紹了這些類型后,下面用一個簡短示例來聲明和使用它們。在下面的示例中,要使用一些簡單的代碼來聲明兩個變量,給它們賦值,再輸出這些值。

試一試:使用簡單類型的變量:Ch03Ex01\Program.cs

(1)在目錄C:\BegVCSharp\Chapter03下創建一個新的控制臺應用程序Ch03Ex01。

(2)在Program.cs中添加如下代碼:

        static void Main(string[] args)
        {
          int myInteger;
          string myString;
          myInteger = 17;
          myString = "\"myInteger\" is";
          Console.WriteLine($"{myString} {myInteger}");
          Console.ReadKey();
        }

(3)運行代碼,結果如圖3-1所示。

圖3-1

示例說明

我們添加的代碼完成了以下3項任務:

● 聲明兩個變量

● 給這兩個變量賦值

● 將這兩個變量的值輸出到控制臺

變量聲明使用下述代碼:

        int myInteger;
        string myString;

第一行聲明一個類型為int的變量myInteger,第二行聲明一個類型為string的變量myString。

注意:變量的命名是有限制的,不能使用任意字符序列。“變量的命名”一節將介紹變量的命名規則。

接下來的兩行代碼為變量賦值:

        myInteger = 17;
        myString = "\"myInteger\" is";

使用=賦值運算符(在本章的“表達式”一節中將詳細介紹)給變量分配兩個固定的值(在代碼中稱為字面值)。把整數值17賦給myInteger,把字符串"myInteger\" is(包括引號)賦給myString。

        "myInteger" is

以這種方式給字符串賦予字面值時,必須用雙引號把字符串括起來。因此,如果字符串本身包含雙引號,就會出現錯誤,必須用一些表示這些字符的其他字符(即轉義序列)來替代它們。本例使用序列\"來轉義雙引號:

        myString = "\"myInteger\" is";

如果不使用這些轉義序列,而輸入如下代碼:

        myString = ""myInteger" is";

就會出現編譯錯誤。

注意給字符串賦予字面值時,必須小心換行—— C#編譯器會拒絕分布在多行上的字符串字面值。要添加一個換行符,可在字符串中使用換行符的轉義序列,即\n。例如,賦值語句:

        myString = "This string has a\nline break.";

會在控制臺視圖中顯示兩行代碼,如下所示:

        This string has a
        line break.

所有轉義序列都包含一個反斜杠符號,后跟一個字符組合(詳見后面的內容),因為反斜杠符號的這種用途,它本身也有一個轉義序列,即兩個連續的反斜杠\\。

下面繼續解釋代碼,還有一行沒有說明:

        Console.WriteLine($"{myString} {myInteger}");

這是C# 6中的一個新功能,稱為字符串插入,它看起來類似于第一個示例中把文本寫到控制臺的簡單方法,但本例指定了變量。這里不詳細討論這行代碼,只需要知道這是本書第I部分用于給控制臺窗口輸出文本的一種技巧。

在后面的示例中,就使用這種給控制臺輸出文本的方式顯示代碼的輸出結果。最后一行代碼在前面的示例中也出現過,用于在程序結束前等待用戶輸入內容:

        Console.ReadKey();

這里不詳細探討這行代碼,但后面的示例會常常用到它。現在只需要知道,它暫停代碼的執行,等待用戶按下一個鍵。

3.3.2 變量的命名

如上一節所述,不能把任意序列的字符作為變量名。但沒必要為此感到擔心,因為這種命名系統仍是非常靈活的。

基本的變量命名規則如下:

● 變量名的第一個字符必須是字母、下劃線(_)或@。

● 其后的字符可以是字母、下劃線或數字。

另外,有一些關鍵字對于C#編譯器而言具有特定的含義,例如前面出現的using和namespace關鍵字。如果錯誤地使用其中一個關鍵字,編譯器會產生一個錯誤,我們馬上就會知道出錯了,所以不必擔心。

例如,下面的變量名是正確的:

        myBigVar
        VAR1
        _test

下列變量名有誤:

        99BottlesOfBeer
        namespace
        It's-All-Over

3.3.3 字面值

在前面的示例中,有兩個字面值示例:整數(17)和字符串("\"myInteger\" is")。其他變量類型也有相關的字面值,如表3-4所示。其中有許多涉及后綴,即在字面值的后面添加一些字符來指定想要的類型。一些字面值有多種類型,在編譯時由編譯器根據它們的上下文確定其類型(同樣見表3-4)。

表3-4 字面值

字符串字面值

本章前面介紹了幾個可在字符串字面值中使用的轉義序列,表3-5是這些轉義序列的完整列表,以便以后引用。

表3-5 字符串字面值的轉義序列

表3-5中的“字符的Unicode值”列是字符在Unicode字符集中的十六進制值。除了上面這些,還可以使用Unicode轉義序列指定其他任何Unicode字符,該轉義序列包括標準的\字符,后跟一個u和一個4位十六進制值(例如,表3-5中x后面的4位數字)。

下面的字符串是等價的:

        "Benjamin\'s string."
        "Benjamin\u0027s string."

顯然,Unicode轉義序列還有更多用途。

也可以一字不變地指定字符串,即兩個雙引號之間的所有字符都包含在字符串中,包括行末字符和原本需要轉義的字符。唯一的例外是必須指定雙引號字符的轉義序列,以免結束字符串。這種方法需要在字符串之前加一個@字符:

        @"Verbatim string literal."

也可以用普通方式指定這個字符串,但下面的字符串就必須使用@字符:

        @"A short list:
        item 1
        item 2"

一字不變的字符串在文件名中非常有用,因為文件名中大量使用了反斜杠字符。如果使用一般字符串,就必須在字符串中使用兩個反斜杠,例如:

        "C:\\Temp\\MyDir\\MyFile.doc"

而有了一字不變的字符串字面值,這段代碼就更便于閱讀。下面的字符串與上面的等價:

        @"C:\Temp\MyDir\MyFile.doc"

注意:從本書的后面可以看出,字符串是引用類型,而本章中的其他類型都是值類型。所以,字符串也可以被賦予null值,表示字符串變量不引用字符串(或其他任何東西)。

主站蜘蛛池模板: 文成县| 锡林浩特市| 齐齐哈尔市| 常州市| 龙州县| 湟源县| 轮台县| 满城县| 广宗县| 常熟市| 舟曲县| 教育| 西盟| 永平县| 富源县| 苍溪县| 华容县| 武隆县| 会昌县| 怀仁县| 昂仁县| 荥经县| 孝感市| 定襄县| 云南省| 屏东市| 五指山市| 绥棱县| 镇安县| 湖南省| 乳源| 开阳县| 四子王旗| 陇西县| 柘城县| 喀什市| 崇阳县| 庆城县| 敦化市| 馆陶县| 陇西县|