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

第3章 變量和表達式

本章主要介紹:C#的基本語法知識;變量的聲明和初始化;變量的命名及基本類型;表達式的基本組成元素以及命名空間的相關知識。

3.1 C#的基本語法

所謂語法,是指管理語言結構和語句的一組規則。在用高級語言編寫程序時,設計人員必須嚴格按照語法規則構造語句。

3.1.1 C#程序結構

下面通過回顧第2章中的C#控制臺應用程序示例來介紹C#的基本語法知識。

在Visual Studio 2008環境中打開該示例程序,選擇“視圖”菜單中的“解決方案資源管理器”命令,打開“解決方案資源管理器”窗口,如圖3-1所示。

圖3-1 “解決方案資源管理器”窗口

在項目的解決方案中可以看到由Visual Studio 2008自動生成的兩個源代碼文件AssemblyInfo.cs和Program.cs。其中,AssemblyInfo.cs文件用來設置項目的一些屬性。在創建項目時,可以查看賦給項目的屬性,并且可以使用自定義屬性向項目中添加信息。自定義屬性有以下兩組:

第1組屬性包括3個字段(Title、Description、Configuration)和5個有關公司或產品的自定義屬性(Trademark、Product、Company、Copyright、Culture)。這些屬性在System.Reflection命名的空間中使用8個類來表示。

第2組屬性包含在System.Runtime.CompilerServices命名空間中,是一些可以添加到代碼中的自定義屬性,并且這些信息在生成項目時添加到可執行文件中。

AssemblyInfo.cs文件中的代碼如下:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

程序集的常規信息通過下列屬性集控制,更改這些屬性值可修改與程序集關聯的信息:

[assembly: AssemblyTitle("hello")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("swpu")]
[assembly: AssemblyProduct("hello")]
[assembly:AssemblyCopyright("版權所有 (C)swpu 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

將ComVisible設置為false,使用此程序集中的類型對COM組件不可見。如果需要從COM訪問此程序集中的類型,則將該類型上的ComVisible屬性設置為true:

[assembly: ComVisible(false)]

如果此項目向COM公開,則下列GUID用于類型庫的ID

[assembly: Guid("ab5f952b-4f8e-4718-b703-41291eb44bf5")]

程序集的版本信息由下面4個值組成:主版本、次版本、內部版本號、修訂號。

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

而Program.cs文件則包含程序所定義的類Program。從圖3-2所示的代碼中可以看出,C#應用程序是在一個類(上例中的類為Program)中實現的。這個類中包含一個靜態成員方法——Main(),此方法叫做程序的入口方法。每當執行應用程序時,均從這個方法開始執行。另外,在自動生成的代碼中,類的定義位于一個命名空間中。對于上例而言,就是Program類的定義位于命名空間hello中。這是因為.NET框架使用命名空間對類型進行邏輯分組,而C#應用程序都是作為類型實現的。如果其他應用程序要使用上例所創建的類Program,可以通過hello.Program來引用。

圖3-2 “代碼編輯器”窗口

下面就是Program.cs的代碼內容:

using System;
namespace hello
{
  class Program
  {
    static void Main(string[] args)
    {
        Console.WriteLine("Hello Word");          //需顯示的字符串
        Console.ReadLine();
    }
  }
}

3.1.2 C#程序入口

每個應用程序都應有一個入口點,表明該程序從何處開始執行。為了讓系統能找到入口點,在C#程序中,入口方法名規定為Main()方法。從前面的C#程序可以看出,Main()方法在一個類中聲明,作為整個程序的入口;Main()方法必須是靜態的,此類不需要實例化,即可直接調用Main()方法。在Main()中,如果調用此類中的非靜態方法,必須先實例化此類,才能調用。在其他類中,Main()雖然屬于靜態方法,也不能調用類名.Main()方法,Main()靜態方法比較特殊;一個程序中有且只有一個Main()。Main()方法返回的類型可以是void(無返回值)或int(返回代表應用程序錯誤級別的整數)。因此,Main()可有以下4種形式:

①  static void Main()
②  static void Main(string[]args)
③  static int Main()
④  static int Main(string[]args)

如果需要,可以忽略這里討論的args。直到現在還在使用這個參數的原因,就是在Visual Studio中創建控制臺應用程序時自動生成的Main()版本。上面的第③、④種形式返回一個int值,可以用于表示應用程序如何終止,通常作為一種錯誤提示(但這不是強制的)。一般情況下,返回0,表示“正常”終止(即應用程序執行完畢,并安全地終止);返回1,則表示從命令行調用不成功。Main()的參數args是從應用程序的外部接受信息的方法,這些信息在運行期間指定,其形式是命令行參數。在命令行傳輸參數時,存放在string數組args中。使用Length屬性來測試輸入參數的個數,使用foreach語句來檢索所有的參數。

上面C#程序中的Program類的代碼內容如下:

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Hello Word");              //需顯示的字符串
  }
}

在上面的C#程序中,Main()方法就是Program類語句的一部分。C#應用程序(可執行)的入口點就是靜態Main()方法,它必須包含在一個類中。僅有一個類能使用該標志定義,除非告訴編譯器它應使用哪一個Main()方法(否側會產生一個編譯錯誤)。與C++相比,Main的第一個字母是大寫的M,而不是小寫字母。在Main前還有一個修飾字“static”,表示此方法只在這個類中起作用,而不是在實例中。因為當程序剛開始執行時,沒有對象實例存在。Main()方法指定執行了代碼“Console.WriteLine("Hello Word")”。Console是名稱空間System的一個類。WriteLine()是Console類的一個方法,因此用操作符“.”將它們分開。

3.1.3 程序區塊

在C#語言中,每個應用程序可以由一個或多個類組成,所有的程序都必須封裝在某個類中,每個類又可以包含一個或多個方法。類和方法都以“{”開始,以“}”結束。“{”和“}”共同定義了程序區塊。一個程序區塊可以由位于“{”和“}”中的多條語句組成,每個程序描述語句必須以分號“;”作為語句的結束標志。程序區塊可以嵌套,即程序區塊中還可以包含程序區塊。例如:

public class MyClass
{
  public static void Main()
  {
    System.Console.Write("C#here");         //每一程序語句行都以分號結尾
  }                                         //標出Main()方法的區塊
}                                           //標出MyClass類的區塊

從上面的代碼中可以發現:為了提高程序的可讀性,代碼采用了縮進的格式,使代碼結構層次清晰。

3.1.4 C#程序的注釋方法

在源代碼中加上注釋信息,是優秀編程人員應養成的良好習慣。注釋信息對程序的執行不起作用,即:在編譯時,注釋不會被編譯進程序里,但必要的注釋有助于程序的閱讀。特別地,當需要對程序功能進行擴充時,可以極大地幫助程序員對原始程序的理解。C#語言添加注釋的方法有多種,最大的特點的是可以使用XML的格式添加注釋,從而減少了許多復雜的工作。

(1)常規注釋方式

① 單行注釋:以“//”開頭,表示從“//”開始到該行行尾都屬于注釋部分。例如:

namespace hello
{
  class Program
  {
    static void Main(string[] args)
    {
        Console.WriteLine("Hello Word");          //需顯示的字符串
    }
  }
}

② 多行注釋:以符號“/*”開始,“*/”結束。任何介于這兩個標記之間的文字都被視為注釋信息。例如:

/*   這是一個C#控制臺程序示例    */
namespace hello
{
  class Program
  {
    static void Main(string[] args)
    {
        Console.WriteLine("Hello Word");          //需顯示的字符串
    }
  }
}

延伸學習──XML注釋方式

(2)XML注釋方式

“///”符號是一種特殊的注釋方式,只要在用戶自定義的類型,如類、接口或類的成員上方,或者命名空間的聲明上方,連續輸入3個斜杠字符“/”,系統將自動生成對應的XML標記。例如:

///<summary>
///
///</summary>
///<param name=”i”></param>
///<param name=”j”></param>
///<returns></returns>
Public int add(int i, int j)
{
  Return i+j;
}

注意:使用XML注釋方式時,為了讓系統自動生成對應的注釋標記,應先編寫方法,然后在方法名的上方輸入“///”,否則不會自動生成對應的參數注釋等標記。

3.1.5 命名空間

Microsoft.NET框架提供了1000多個類,用于完成各種各樣的功能。根據類的功能不同,這些類又被劃分到不同的命名空間中(Namespace)。命名空間包含可在程序中使用的類、結構、枚舉、委托和接口。一個命名空間又可以包含其他命名空間。命名空間只是一種邏輯上的劃分,而不是物理上的存儲分類。命名空間是一種組織C#程序中出現的不同類型的方式。命名空間在概念上與計算機文件系統中的文件夾有些類似。與文件夾一樣,命名空間可使類具有唯一的完全限定名稱。一個C#程序包含一個或多個命名空間,每個命名空間或者由程序員定義,或者作為之前編寫的類庫的一部分定義。

C#程序主要是利用命名空間來組織的,函數庫即由一個個的命名空間來組成。每個命名空間都可以視為一個容器,容器里可以存放類、接口以及結構等程序。.NET利用命名空間來對程序進行分類,把功能相似的類、結構等程序放在同一個命名空間中,便于管理,也便于程序設計人員使用。最常見的命名空間是System命名空間,它包含了許多常用的結構類型(例如int、bool)和許多類(如Console、Expection)。

C#語言使用命名空間來組織系統類型或用戶自定義的數據類型。如果沒有明確地聲明一個命名空間,則用戶代碼中所定義的類型將位于一個未命名的全局命名空間中。這個全局命名空間中的類型對于所有的命名空間都是可見的。不同命名空間中的類型可以具有相同的名字,但是同一命名空間中的類型的名字不能相同。在編寫C#程序時,通常都要先聲明一個命名空間,然后在這個命名空間中定義自己的類型。其語法為:

namespace名稱[.名稱]
{
  ……
}

命名空間作為一個容器,其里面的區域需要用一個大括號“{}”來標識,這與類(Class)和方法(Method)的定義一樣。如“Hello Word”的例子:

namespace hello
{
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Hello Word");               //需顯示的字符串
    }
  }
}

若要調用命名空間下某個類提供的方法,可以使用下面的語法之一:

①  命名空間. 命名空間……命名空間.類名稱.靜態方法名(參數, ……);
②  命名空間. 命名空間……命名空間.實例名稱.方法名(參數, ……);

例如,前面“Hello Word”例子中的字符串輸出語句可以寫成:

System. Console.WriteLine("Hello Word");

這條語句使用的命名空間為System。在System命名空間下,有一個Console類,該類提供了靜態的WriteLine方法,調用此方法來輸出字符串“Hello Word”。

顯然,從上面的例子可以看到,每條語句都加上命名空間太煩瑣了。為了加快引用需要的功能,一般可以在程序的開頭引用命名空間來簡化代碼的書寫形式。例如,上面的語句“System. Console.WriteLine("Hello Word");”,前綴“System.”表示Console類在System命名空間下,如果在程序的開頭寫上:

using System;

那么,語句中就不需要加上命名空間前綴了,而可以直接寫為:

Console.WriteLine("Hello Word");

這種形式體現了名稱空間的方便。前面的“Hello Word”例子中正是采用了這種形式。

在C#程序中,不管是簡單的數據類型,還是執行其他復雜操作,都必須通過函數庫才能實現。.NET類庫(Library)中包含了許多類,如按鈕、復選框等。利用類庫,可以開發出具有優美界面的應用程序。

.NET類庫中還包含了許多可以實現其他豐富功能的類,如存取網絡、數據庫操作等,這些類庫使C#編寫的程序功能無比強大。

為了方便地運用這些函數庫,C#程序使用using關鍵字將函數庫包含進來。可以看到,C#的using與C/C++中的#include十分相似,都是為了使用已經設計好的程序。

以下程序代碼的執行結果是:在DOS命令窗口中,按提示輸入名字后,顯示一條歡迎信息,如圖3-3所示。如果去掉using這一行,則程序編譯無法通過。

圖3-3 運行結果

using System;
namespace ConsoleApplication1
{
  class Class1
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Please enter your name:");         //輸出提示信息
      Console.ReadLine();                                //從鍵盤讀入一行字符
      Console.WriteLine("Welcome to the world of C#!");       //顯示歡迎信息
    }
  }
}

程序中使用了System下的一個叫做Console的類。利用Console類,該程序在DOS命令窗口里輸出、讀入字符信息。

第一行語句使用using關鍵字的主要目的是讓編譯器知道,程序中將使用定義在System中的所有類。程序設計人員在程序中便可以不必通過完整的類的名稱來使用類,如System.Console.Write。

如果不使用using關鍵字來設計C#程序,要實現范例中的功能也是可以的,只是此時編譯器不知道程序中會使用定義在System中的類,設計人員在使用System中的類時,則需要輸入完整的類名稱。例如,上面的范例程序在去掉using關鍵字的第一行程序后,程序修改如下:

System.Console.WriteLine("Please enter your name:");      //輸出提示信息
System.Console.ReadLine();                               //從鍵盤讀入一行字符
System.Console.WriteLine("Welcome to the world of C#!"); //顯示歡迎信息

3.2 變量

當程序對數據進行讀、寫、運算等操作,需要保存特定的值或計算結果時,需要用到變量(Variable)。變量是用來描述一條信息的名稱,在變量中可以存儲各種類型的信息,如人的姓名、車票的價格、文件的長度等。

3.2.1 變量的命名

變量是計算機中占據一定內存單元的存儲區域,通過指定變量的名稱來使用和管理變量。從數據存儲角度看,變量名相當于存儲數據的變量所占的存儲區域的標識名。

當需要訪問存儲在變量中的信息時,只需要使用變量的名稱即可。為變量起名時要遵守C#語言的規定:

⊙ 變量名必須以字母開頭。

⊙ 變量名只能由字母、數字和下劃線組成,不能包含空格、標點符號、運算符等其他符號。

⊙ 變量名不能與C#中的關鍵字名稱相同。

⊙ 變量名不能與C#中的庫函數名稱相同。

在C#中有一點是例外,即允許在變量名前加上前綴“@”。在這種情況下,可以使用前綴“@”加上關鍵字作為變量的名稱。這主要是為了與其他語言進行交互時避免沖突。因為前綴“@”實際上并不是名稱的一部分,其他編程語言會把它作為一個普通的變量名。在其他情況下,不推薦使用前綴“@”作為變量名的一部分。

在命名變量時,除了必須遵守C#規則以外,還應遵守一些命名約定。良好的編程習慣有助于提高程序的正確性、可讀性、可維護性和可用性。常用數據類型的前綴如表3.1所示。

表3.1 常用數據類型的前綴

3.2.2 數據類型

C#程序完全由類型構成,并且它的所有功能也都是通過各種類型來實現的。類型定義了允許的值以及在這些值上允許的操作,包括 .NET框架提供的類型以及用戶自定義的類型。

C#語言中的數據類型可以分為兩類:值類型(Value Type)和引用類型(Reference Type)。值類型包括:簡單類型(如char、int和float)、結構類型和枚舉類型,而引用類型包括:類類型、接口類型、數組類型和委托類型。值類型和引用類型的區別在于,值類型的變量直接存放實際數據,而引用類型的變量存放的則是數據的地址,即對象的引用。

在C#語言中,所有的值類型都是從System.Object類派生的,System.Object類是所有類型的基類,并且不能派生新的值類型。同時,所有的值類型都具有一個隱含的構造函數用于初始化。C#的值類型可以分為以下幾種:簡單類型(Simple Type)、結構類型(Struct Type)、枚舉類型(Enumeration Type)。

簡單類型有時也稱為純量類型,是直接由一系列元素構成的數據類型。C#語言中的簡單類型包括:整數類型、布爾類型、實數類型和字符類型。本章重點介紹簡單數據類型,而其他數據類型的知識將在后續章節介紹。

1.整數類型

顧名思義,整數類型的變量的值為整數。數學上的整數可以從負無窮大到正無窮大,但是由于計算機的存儲單元是有限的,所以計算機語言提供的整數類型的值總是在一定范圍之內。C#語言提供了9種整數類型:短字節型(sbyte)、字節型(byte)、短整型(short)、無符號短整型(ushort)、整型(int)、無符號整型(uint)、長整型(long)、無符號長整型(ulong)和字符型(char)。劃分的依據是根據該類型的變量在內存中所占的位數。這些整數類型在數學上的表示以及在計算機中的取值范圍如表3.2所示。

表3.2 整數類型

【例3-1】整型變量的使用。創建一個控制臺程序,驗證短整型整數類型的取值范圍。

using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      short x=32766;                    //聲明一個短整型變量x,并賦值為32766
      x++;                              //將變量x的值加1
      Console.WriteLine(x);             //輸出x的值
      x++;                              //將變量x的值加1
      Console.WriteLine(x);             //輸出x的值
      Console.Read();  //按回車鍵結束
    }
  }
}

說明:程序中的short類型整數x已經超出了系統定義的范圍(-32768~32767)。

程序運行結果如圖3-4所示。

圖3-4 例3-1運行結果

2.布爾類型

布爾類型用來表示“真”和“假”。在C#語言中,布爾類型用bool表示,其值為true或false。例如:

bool a=true;
int i=20;
bool b=(i>0 && i<10);

注意:C#條件表達式的運算結果一定是布爾類型。另外,在C/C++中,可用0來表示“false”,其他任何非0的值可表示為“true”,但這在C#中已經被廢棄。在C#中,true值不能被其他任何非0值所代替。在其他整數類型和布爾類型之間不再存在任何轉換,將整數類型轉換成布爾類型是不合法的。例如:

bool c=1;                             //錯誤,不允許這種寫法

3.實數類型

數學中的實數不僅包括整數,還包括小數。帶小數的實數在C#中采用兩種數據類型來表示:單精度(float)和雙精度(double)。它們的差別在于取值范圍和精度不同。計算機對于浮點數的運算速度大大低于對整數的運算。在對精度要求不是很高的浮點數計算中,可以采用float型,而采用double型獲得的結果將更為精確。單精度型和雙精度型可統稱浮點類型,它們的具體說明如表3.3所示。

表3.3 浮點數類型

C#語言還提供了一種十進制類型(decimal),主要用于方便在金融和貨幣方面的計算。在現代的企業應用程序中,不可避免地要進行大量的關于這方面的計算和處理。C#通過提供這種專門的數據類型,可更為快捷地開發有關金融和貨幣方面的應用程序。

十進制類型是一種大范圍、高精度的數據類型,占16字節,所表示的范圍大約為1.0×10-28~7.9×1028,可精確到28~29位有效數字。雖然十進制類型的取值范圍遠小于雙精度類型,但它更精確,特別適用于金融、貨幣等需要高精度數值的領域。當聲明一個decimal變量并賦值時,使用M/m類型指定符以表明它是一個十進制類型。例如:

decimal a=10000.56m;

如果省略m,在變量被賦值之前,它將被編譯器當作雙精度類型來處理。

4.字符類型

除了數字以外,計算機處理的信息主要就是字符了。字符包括數字字符、英文字符、符號等。C#提供的字符類型(char)按照國際上公認的標準,采用Unicode字符集。一個Unicode字符的標準長度為2字節,共16位,可以表示世界上大多數語言。字符型變量可以用單引號括起來的字符直接賦值。字符型(char)還可表示無符號的16位整數,它的可能值集與Unicode字符集相對應,雖然表示形式上與短整型(ushort)相同,但意義不同,ushort代表的是數值本身,而char代表的是一個字符。

3.2.3 變量的聲明

變量使用之前,必須先聲明,即給變量指定名稱和類型。聲明變量以后,便可以將它們用作存儲單元來存取相應類型的數據。

聲明變量的一般形式如下:

①   [附加聲明][訪問修飾符] 數據類型  變量名;
②   [附加聲明][訪問修飾符] 數據類型  變量名=正確數據類型的初始值;

說明:[ ]表示該內容為可選項,修飾符可以是public、private、internal、new等關鍵字。下面給出一些合法和非法的變量名的例子:

int i;                           //合法
string total;                    //合法
char use;                     //不合法,與關鍵字名稱相同
char@use;                   //合法
float Main;                    //不合法,與函數名稱相同

C#中允許在一條語句中命名多個類型相同的變量。如:

int a,b,c=50;

聲明變量后并對其賦值稱為變量的初始化。在上面給出的聲明變量的兩種格式中,第一種格式僅完成變量的聲明,而第二種格式既聲明了變量,同時又完成了變量的初始化。下面給出一些變量初始化的例子:

int i;
i = 100;
char name;
name = 'a';
//上面兩個例子是先聲明變量,再賦值
int i = 100;
char name = 'a';
//這兩個例子是在聲明變量的同時對其初始化

3.3 常量

所謂常量,就是其值固定不變的量。從數據類型角度來看,常量的類型可以是任何一種值類型或引用類型。一個常量的聲明就是聲明程序中要用到的常量的名稱和它的值。常量的命名規則同變量一樣。

常量有直接常量和符號常量兩種。

1.直接常量

直接常量即數據值本身。

(1)整型常量

整型常量通常有三種形式:

⊙ 十進制形式:123,+123,-123等。

⊙ 八進制形式:在數字前加0,如0123,+0123,-0123等。

⊙ 十六進制形式:在數字前加“0x”或“0X”,如0x123,+0X123,-0X123等。

(2)實型常量

實型常量通常有兩種形式:

⊙ 小數形式:0.123,-0.123等。

⊙ 指數形式:123e4,-123E-4等。

(3)字符(串)常量

單個字符用一對英文單引號界定,表示字符常量,如'A'、'中'、'+'等。一串字符用一對英文雙引號界定,表示字符串常量,如"歡迎學習C#!"、"你好!"、"hello!"等。

注意:單引號和雙引號也可以看成是字符常量,能不能也用上面的方法來表示呢?下面介紹有關“轉義符”的相關知識。

同C語言一樣,轉義字符是C#語言中的一種特殊的字符型常量表示形式,可以將轉義字符簡單地理解為“轉變了本身含義的字符”。例如,“\n”并非表示一個“\”和一個“n”,而是表示換行符。

使用轉義字符主要是由于以下三個原因:

⊙ 某些字符具有控制功能,直接的鍵盤按鍵不能輸入這些字符(如換行符、退格符等)。

⊙ 擴展的ASCII編碼可以有255字符,而計算機的標準鍵盤只能輸入基本的ASCII字符,而不能輸入擴展部分的字符,如字符“§”。

⊙ 某些字符在C#語言中具有特定的含義,不能作為普通字符處理。例如,單引號對作為字符型常量的定界符,如果使用“'''”的形式表示字符“'”,將出現語法錯誤。

在C#語言中也采用轉義符來表示一些特殊的字符,包括一些控制字符。在表3.4中列出了一些定義字符型數據和字符串類型數據時常用的轉義符。

表3.4 常用轉義符

【例3-2】轉義字符的使用。使用轉義字符控制輸出結果的顯示格式。

using System;
namespace ConsoleApplication1
{
  class Test
  {
    public static void Main()
    {
      Console.WriteLine("\n\tHello\n\tWorld!");
      Console.Read();
    }
  }
}

說明:程序中使用了換行字符“\n”和水平制表字符“\t”。在輸出的字符串中,“\n”產生換行效果,而“\t”引起屏幕位置向右移動8個字符位置,故稱為水平制表字符。

程序的運行結果如圖3-5所示。

圖3-5 例3-2運行結果

(4)布爾常量

布爾常量即布爾值:true或false。

2.符號常量

符號常量聲明的格式如下:

[附加聲明][訪問修飾符]  const數據類型  常量名=正確數據類型的值;

說明:[ ]表示該內容為可選項,修飾符可以是public、private、internal、new和protected。

例如:

public const double X=1.0, Y=2.0, Z=3.0;

同樣地,C#允許在一條語句中同時聲明多個常量。常量也有一個命名約定。習慣上,常量名全部使用大寫字母表示。

3.4 表達式

C#語言中的表達式類似于數學運算中的表達式,是操作符、操作對象和標點符號等連接而成的式子。操作符是用來定義類實例中表達式操作符的。表達式是指定計算的操作符、操作數序列。操作符指出了對操作數的操作。比如,操作符有+、-、/和new;操作數可以是文字、域、當前變量或表達式。單個的常量、變量和函數也可以看作是一個最簡單的表達式。

與運算類型相對應,包含某種運算符的表達式則稱為某種類型的表達式,因而C#語言主要有算術表達式、關系表達式、邏輯表達式、賦值表達式、條件表達式等。

表達式無論長短與否,最終應該計算出一個確定的值,結果值的類型要取決于表達式的類型或表達式中混合運算時的類型轉換情況。

3.4.1 操作符

依照操作符作用的操作數的個數來分,C#中有三種類型的操作符。

⊙ 一元操作符:作用于一個操作數。一元操作符又包括前綴操作符和后綴操作符。

⊙ 二元操作符:作用于兩位操作數,使用時在操作數中間插入操作符。

⊙ 三元操作符:C#中僅有一個三元操作符“?:”,三元操作符作用于三個操作數,使用時在操作數中間插入操作符。

下面分別給出使用操作符的例子:

int x=5, y=10, z;
x++;  //后綴一元操作符
--x;  //前綴一元操作符
z=x+y;  //二元操作符
y=(x>10?0:1);  //三元操作符

常用操作符如表3.5所示。

表3.5 常用操作符

當一個表達式包含多個操作符時,表達式的值就由各操作符的優先級決定。表3.6列出了常見操作符的優先級(從高到低)。

表3.6 操作符的優先級

技術要點

① 從表3.6中可以看出,一元運算符的優先級高于二元和三元運算符。

② 不同種類運算符的優先級有高低之分。算術運算符的優先級高于關系運算符,關系運算符的優先級高于邏輯運算符,邏輯運算符的優先級高于條件運算符,條件運算符的優先級高于賦值運算符。

③ 有些同類運算符優先級也有高低之分。在算術運算符中,乘、除、求余的優先級高于加、減;在關系運算符中,小于、大于、小于等于、大于等于的優先級高于相等和不等;邏輯運算符的優先級按從高到低為非、與、或。

④ 當一個操作數出現在兩個有相同優先級的操作符之間時,操作符按照出現的順序由左至右執行。

⑤ 為了提高表達式的可讀性,可以使用圓括號明確運算順序或改變運算順序。

⑥ 除了賦值操作符,所有的二進制的操作符都是左結合(left-associative)的,也就是說,操作按照從左向右的順序執行。例如,x + y + z按(x + y) + z進行求值。

⑦ 賦值操作符和條件操作符(?:)按照右接合(right-associative)的原則,即操作按照從右向左的順序執行,如x = y = z按照x = (y = z)進行求值。

3.4.2 算術表達式

C#中提供的算術操作符有5種:+,加法操作符;-,減法操作符;*,乘法操作符;/,除法操作符;%,求余操作符。

在表達式的運算中,表達式總是按它們本身書寫的順序求值。由算術操作符連接操作數而組成的表達式稱為算術表達式。

【例3-3】遞增運算。后綴一元操作符的使用。

using System;
class Test
{
  static void F(int x,int y,int z)
  {
    Console.WriteLine("x={0},y={1},z={2}",x,y,z);
  }
  public static void Main()
  {
    int i=1;
    F(i++,i++,i++);
  }
}

說明:程序中的i變量依次遞增1。

程序的運行結果如圖3-6所示。

圖3-6 例3-3運行結果

【例3-4】 除法運算。演示同一操作符、不同操作數及不同數據類型得到不同的計算結果。

using System;
class Test
{
  public static void Main()
  {
    Console.WriteLine(5/3);
    Console.WriteLine(4/3);
    Console.WriteLine((5/3)= =(4/3));
    Console.WriteLine(5.0/3);
    Console.WriteLine(4.0/3);
    Console.WriteLine((5.0/3)= =(4.0/3))
  }
}

說明:在除法運算過程中,默認的返回值的類型與精度最高的操作數類型相同。比如5/2的結果為2,而5.0/2結果為2.5。如果兩個整數類型的變量相除又不能整除的話,返回的結果是不大于相除之值的最大整數。

程序運行的結果如圖3-7所示。

圖3-7 例3-4運行結果

3.4.3 賦值表達式

賦值就是給一個變量賦一個新值。C#中提供的賦值操作符有:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=。

賦值的左操作數必須是一個變量、屬性訪問器或索引訪問器的表達式。

C#中可以對變量進行連續賦值,這時賦值操作符是右關聯的,這意味著從右向左操作符被分組。例如,形如a = b = c的表達式等價于a = (b = c)。

如果賦值操作符兩邊的操作數類型不一致,則先進行類型轉換。賦值運算包括簡單賦值和復合賦值兩種。

(1)簡單賦值

“=”操作符被稱為簡單賦值操作符。在一個簡單賦值中,右操作數必須為某種類型的表達式,且該類型必須可以隱式地轉換成左操作數類型。該運算將右操作數的值賦給作為左操作數的變量、屬性或者索引器類型。簡單賦值表達式的結果是被賦值給左操作數的值。結果類型和左操作數的類型相同,且總是值類型。

(2)復合賦值

C#語言有把賦值號和其他的運算符結合起來,組成復合賦值運算符,使表達式的形式更加簡潔,提高了編譯的效率。復合賦值運算符形式是:

<變量名>  <其他運算符>=<表達式>;

其功能相當于:

<變量名> = <變量名> <其他運算符> <表達式>;

形如x op = y的運算可以處理成形如x op y的二進制操作符重載方法。例如:

x+=5;  //等于x=x+5
x%=3;  //等于x=x%3
x*=y+1;  //等于x=x*(y+1)

復合賦值進行的步驟如下:

① 如果所選操作符的返回類型可以隱式轉換成x的數據類型,執行x = x op y的運算,除此之外,僅對x執行一次運算。

② 否則,所選操作符是一個預定義操作符,所選操作符的返回值類型可以顯式地轉換成x的類型,且y可以隱式地轉換成x的類型,那么該運算等價于x = (T) (x op y)運算。這里T是x的類型,除此之外,x僅被執行一次。

③ 否則,復合賦值是無效的,將產生編譯時錯誤。

【例3-5】復合賦值運算。

復合賦值運算符在使用過程中,關鍵需要掌握的是運算的基本規則和結合性問題。下面的例子用來說明復合賦值運算符的使用方法。

using System;
class Test
{
  public static void Main()
  {
    int a = 12;
    a += a -= a *= a;
    Console.WriteLine(a);
    Console.Read();
  }
}

說明:由于賦值運算符是右結合性的,所以表達式a+=a-=a*=a等價于a+=(a-=(a*=a)),該表達式的求解過程為:

首先計算a*=a,則a=144;

接著計算a-=144,則a=12-144= -132;

最后計算a+=-132,則a= 12+(-132)=-120。

程序的運行結果為-120。

3.5 小結

本章介紹了C#語言的基礎知識,包括C#的基本語法知識、變量常量的命名規則、變量的聲明及初始化、直接常量的種類、符號常量的聲明,舉例說明了算術運算符和賦值運算符及其表達式的用法。

課外閱讀──算術溢出

算術運算符(+、-、*、/)產生的結果可能會超出涉及的數值類型可能值的范圍。一般情況下:

整數算術溢出或者引發OverflowException,或者丟棄結果的最高有效位。整數被零除總是引發DivideByZeroException。

浮點算術溢出或被零除從不引發異常,因為浮點類型基于IEEE 754,因此可以表示無窮和NaN(不是數字)。

小數算術溢出總是引發OverflowException。小數被零除總是引發DivideByZeroException。

當發生整數溢出時,產生的結果取決于執行上下文,該上下文可為checked或unchecked。在checked上下文中引發OverflowException。在未選中的上下文中,放棄結果的最高有效位并繼續執行。因此,C# 使您有機會選擇處理或忽略溢出。

除算術運算符以外,整型之間的強制轉換也會導致溢出(如將long強制轉換為int)并受checked或unchecked執行的限制。然而,按位運算符和移位運算符永遠不會導致溢出。

練習 3

一、選擇題

1.C#語言屬于____。

A.機器語言

B.匯編語言

C.面向過程的語言

D.面向對象的程序設計語言

2.一個C#語言程序總是從____開始執行。

A.書寫順序的第一個函數

B.書寫順序的第一條執行語句

C.Main( )方法

D.不確定

3.把已經編寫好的源程序翻譯成二進制的目標代碼的步驟是____。

A.編輯

B.編譯

C.連接

D.執行

4.C#語言中的標識符只能由字母,數字和下劃線組成,且第一個字符____。

A.必須為字母

B.必須為下劃線

C.必須為字母或下劃線

D.可以是字母,數字或下劃線中任一種

5.以下選項中,不屬于C#語言數據類型的是____。

A.int

B.short

C.long

6.在C#語言中,合法的數據形式是____。

A.±23

B.±1.23

C.234

7.以下選項中,合法的字符常量是____。

A.'B'

B."A"

C.CD

8.以下選項中,合法的用戶標識符是____。

A.long

B._2Test

C.3Dmax

9.在C#語言中,下列運算符優先級最高的是____。

A.!

B.*

C.>

D.number

D.D123

D.1

D.Area

D.%

10.下列變量的聲明方式不正確的是____。

A.int a;

B.int a=b;

C.char a;

D.string ab="ab";

11.下列數據類型不屬于C#整數類型的是____。

A.sbyte

B.short

C.ushort

D.string

12.關于數據類型float說法不正確的是____。

A.該數據類型用于表示實數

B.該數據類型占4個字節空間

C.該數據類型表示雙精度浮點數

D.該數據類型表示單精度浮點數

13.關于數據類型char說法不正確的是____。

A.該數據類型可用于表示單個字符

B.該數據類型可表示32位整數

C.該數據類型可表示16位無符號整數

D.該數據類型用于表示整數時與ushort在形式上類似,但意義不同

14.下列關于“聲明變量”的說法中,最準確的是____。

A.為變量命名

B.給變量賦值

C.在C#中,一次最多聲明一個變量

D.命名變量并說明變量的數據類型

15.在下列轉義符形式中,表示“回車符”的是____。

A.\0

B.\r

C.\n

D.\t

二、填空題

16.在C#語言中,每條語句都以____結束。

17.C#有多種注釋方法,其中 【A】 適用于單行注釋,【B】 適用于多行注釋。

18.在C#語言中,實數類型包含三種: 【A】【B】【C】

19.C#語言規定變量在使用之前必須先____后使用。

20.在C#表達式中,可通過____改變運算符的運算順序,使表達式更清晰易懂。

21.在C#語言中,使用____關鍵字聲明符號常量。

22.在代碼中,明確指示將某一數據類型轉換為另一種數據類型稱為____。

23.在C#語言中,系統命名空間使用____關鍵字導入。

24.除了賦值操作符,所有的二進制的操作符都是____的,也就是說,操作按照從左向右的順序執行。

25.不同種類運算符的優先級有高低之分。【A】 的優先級高于關系運算符,關系運算符的優先級高于邏輯運算符,邏輯運算符的優先級高于條件運算符,條件運算符的優先級高于 【B】

26.C#中的表達式類似于數學運算中的表達式,是由 【A】【B】 和標點符號等連接而成的式子。

27.在C#中,有些字符不能直接放在單引號中作為字符常量,這就需要使用轉義符來表示這些字符常量,轉義符由____加字符組成。

三、求下列表達式的值

28.

  int a=1, b=4, c=3;
  float d=10.4, e=4.1, f
  f=(a + b)/c + e * 1.1/c + d;

29.

  int a=7, b=3, c=5;
  float d;
  d=b + a % 3 + (b + c) % 2 / 4;

四、將下列數學表達式改寫為等價的C#表達式

30.

31.(4+3x)2-abc

32.

五、問答題

33.簡述C#語言中變量的命名規則?

34.什么是命名空間?命名空間有何作用?

35.在C#代碼編寫中,使用縮進格式及注釋語句是C#的語法規則嗎?它們的作用是什么?

主站蜘蛛池模板: 民和| 贺州市| 龙山县| 弋阳县| 聂拉木县| 长沙县| 南皮县| 五指山市| 淮北市| 平安县| 平邑县| 青铜峡市| 中方县| 三江| 望江县| 五莲县| 湖州市| 宣威市| 广南县| 景洪市| 普定县| 合作市| 太原市| 浪卡子县| 葫芦岛市| 龙口市| 贵南县| 福贡县| 辉县市| 洞头县| 宝坻区| 正镶白旗| 锡林浩特市| 郓城县| 原平市| 昔阳县| 托克逊县| 铜川市| 体育| 和政县| 盖州市|