書名: C#大學(xué)實用教程作者名: 匡松 張淮鑫編著本章字數(shù): 2189字更新時間: 2018-12-30 06:33:51
第3章 變量和表達式
本章主要介紹:C#的基本語法知識;變量的聲明和初始化;變量的命名及基本類型;表達式的基本組成元素以及命名空間的相關(guān)知識。

3.1 C#的基本語法
所謂語法,是指管理語言結(jié)構(gòu)和語句的一組規(guī)則。在用高級語言編寫程序時,設(shè)計人員必須嚴格按照語法規(guī)則構(gòu)造語句。
3.1.1 C#程序結(jié)構(gòu)
下面通過回顧第2章中的C#控制臺應(yīng)用程序示例來介紹C#的基本語法知識。
在Visual Studio 2008環(huán)境中打開該示例程序,選擇“視圖”菜單中的“解決方案資源管理器”命令,打開“解決方案資源管理器”窗口,如圖3-1所示。

圖3-1 “解決方案資源管理器”窗口
在項目的解決方案中可以看到由Visual Studio 2008自動生成的兩個源代碼文件AssemblyInfo.cs和Program.cs。其中,AssemblyInfo.cs文件用來設(shè)置項目的一些屬性。在創(chuàng)建項目時,可以查看賦給項目的屬性,并且可以使用自定義屬性向項目中添加信息。自定義屬性有以下兩組:
第1組屬性包括3個字段(Title、Description、Configuration)和5個有關(guān)公司或產(chǎn)品的自定義屬性(Trademark、Product、Company、Copyright、Culture)。這些屬性在System.Reflection命名的空間中使用8個類來表示。
第2組屬性包含在System.Runtime.CompilerServices命名空間中,是一些可以添加到代碼中的自定義屬性,并且這些信息在生成項目時添加到可執(zhí)行文件中。
AssemblyInfo.cs文件中的代碼如下:
using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices;
程序集的常規(guī)信息通過下列屬性集控制,更改這些屬性值可修改與程序集關(guān)聯(lián)的信息:
[assembly: AssemblyTitle("hello")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("swpu")] [assembly: AssemblyProduct("hello")] [assembly:AssemblyCopyright("版權(quán)所有 (C)swpu 2008")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")]
將ComVisible設(shè)置為false,使用此程序集中的類型對COM組件不可見。如果需要從COM訪問此程序集中的類型,則將該類型上的ComVisible屬性設(shè)置為true:
[assembly: ComVisible(false)]
如果此項目向COM公開,則下列GUID用于類型庫的ID
[assembly: Guid("ab5f952b-4f8e-4718-b703-41291eb44bf5")]
程序集的版本信息由下面4個值組成:主版本、次版本、內(nèi)部版本號、修訂號。
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
而Program.cs文件則包含程序所定義的類Program。從圖3-2所示的代碼中可以看出,C#應(yīng)用程序是在一個類(上例中的類為Program)中實現(xiàn)的。這個類中包含一個靜態(tài)成員方法——Main(),此方法叫做程序的入口方法。每當執(zhí)行應(yīng)用程序時,均從這個方法開始執(zhí)行。另外,在自動生成的代碼中,類的定義位于一個命名空間中。對于上例而言,就是Program類的定義位于命名空間hello中。這是因為.NET框架使用命名空間對類型進行邏輯分組,而C#應(yīng)用程序都是作為類型實現(xiàn)的。如果其他應(yīng)用程序要使用上例所創(chuàng)建的類Program,可以通過hello.Program來引用。

圖3-2 “代碼編輯器”窗口
下面就是Program.cs的代碼內(nèi)容:
using System; namespace hello { class Program { static void Main(string[] args) { Console.WriteLine("Hello Word"); //需顯示的字符串 Console.ReadLine(); } } }
3.1.2 C#程序入口
每個應(yīng)用程序都應(yīng)有一個入口點,表明該程序從何處開始執(zhí)行。為了讓系統(tǒng)能找到入口點,在C#程序中,入口方法名規(guī)定為Main()方法。從前面的C#程序可以看出,Main()方法在一個類中聲明,作為整個程序的入口;Main()方法必須是靜態(tài)的,此類不需要實例化,即可直接調(diào)用Main()方法。在Main()中,如果調(diào)用此類中的非靜態(tài)方法,必須先實例化此類,才能調(diào)用。在其他類中,Main()雖然屬于靜態(tài)方法,也不能調(diào)用類名.Main()方法,Main()靜態(tài)方法比較特殊;一個程序中有且只有一個Main()。Main()方法返回的類型可以是void(無返回值)或int(返回代表應(yīng)用程序錯誤級別的整數(shù))。因此,Main()可有以下4種形式:
① static void Main() ② static void Main(string[]args) ③ static int Main()
④ static int Main(string[]args)
如果需要,可以忽略這里討論的args。直到現(xiàn)在還在使用這個參數(shù)的原因,就是在Visual Studio中創(chuàng)建控制臺應(yīng)用程序時自動生成的Main()版本。上面的第③、④種形式返回一個int值,可以用于表示應(yīng)用程序如何終止,通常作為一種錯誤提示(但這不是強制的)。一般情況下,返回0,表示“正常”終止(即應(yīng)用程序執(zhí)行完畢,并安全地終止);返回1,則表示從命令行調(diào)用不成功。Main()的參數(shù)args是從應(yīng)用程序的外部接受信息的方法,這些信息在運行期間指定,其形式是命令行參數(shù)。在命令行傳輸參數(shù)時,存放在string數(shù)組args中。使用Length屬性來測試輸入?yún)?shù)的個數(shù),使用foreach語句來檢索所有的參數(shù)。
上面C#程序中的Program類的代碼內(nèi)容如下:
class Program { static void Main(string[] args) { Console.WriteLine("Hello Word"); //需顯示的字符串 } }
在上面的C#程序中,Main()方法就是Program類語句的一部分。C#應(yīng)用程序(可執(zhí)行)的入口點就是靜態(tài)Main()方法,它必須包含在一個類中。僅有一個類能使用該標志定義,除非告訴編譯器它應(yīng)使用哪一個Main()方法(否側(cè)會產(chǎn)生一個編譯錯誤)。與C++相比,Main的第一個字母是大寫的M,而不是小寫字母。在Main前還有一個修飾字“static”,表示此方法只在這個類中起作用,而不是在實例中。因為當程序剛開始執(zhí)行時,沒有對象實例存在。Main()方法指定執(zhí)行了代碼“Console.WriteLine("Hello Word")”。Console是名稱空間System的一個類。WriteLine()是Console類的一個方法,因此用操作符“.”將它們分開。
3.1.3 程序區(qū)塊
在C#語言中,每個應(yīng)用程序可以由一個或多個類組成,所有的程序都必須封裝在某個類中,每個類又可以包含一個或多個方法。類和方法都以“{”開始,以“}”結(jié)束。“{”和“}”共同定義了程序區(qū)塊。一個程序區(qū)塊可以由位于“{”和“}”中的多條語句組成,每個程序描述語句必須以分號“;”作為語句的結(jié)束標志。程序區(qū)塊可以嵌套,即程序區(qū)塊中還可以包含程序區(qū)塊。例如:
public class MyClass { public static void Main() { System.Console.Write("C#here"); //每一程序語句行都以分號結(jié)尾 } //標出Main()方法的區(qū)塊 } //標出MyClass類的區(qū)塊
從上面的代碼中可以發(fā)現(xiàn):為了提高程序的可讀性,代碼采用了縮進的格式,使代碼結(jié)構(gòu)層次清晰。
3.1.4 C#程序的注釋方法
在源代碼中加上注釋信息,是優(yōu)秀編程人員應(yīng)養(yǎng)成的良好習(xí)慣。注釋信息對程序的執(zhí)行不起作用,即:在編譯時,注釋不會被編譯進程序里,但必要的注釋有助于程序的閱讀。特別地,當需要對程序功能進行擴充時,可以極大地幫助程序員對原始程序的理解。C#語言添加注釋的方法有多種,最大的特點的是可以使用XML的格式添加注釋,從而減少了許多復(fù)雜的工作。
(1)常規(guī)注釋方式
① 單行注釋:以“//”開頭,表示從“//”開始到該行行尾都屬于注釋部分。例如:
namespace hello { class Program { static void Main(string[] args) { Console.WriteLine("Hello Word"); //需顯示的字符串 } } }
② 多行注釋:以符號“/*”開始,“*/”結(jié)束。任何介于這兩個標記之間的文字都被視為注釋信息。例如:
/* 這是一個C#控制臺程序示例 */ namespace hello { class Program { static void Main(string[] args) { Console.WriteLine("Hello Word"); //需顯示的字符串 } } }
延伸學(xué)習(xí)──XML注釋方式
(2)XML注釋方式
“///”符號是一種特殊的注釋方式,只要在用戶自定義的類型,如類、接口或類的成員上方,或者命名空間的聲明上方,連續(xù)輸入3個斜杠字符“/”,系統(tǒng)將自動生成對應(yīng)的XML標記。例如:
///<summary> /// ///</summary> ///<param name=”i”></param> ///<param name=”j”></param>
///<returns></returns> Public int add(int i, int j) { Return i+j; }
注意:使用XML注釋方式時,為了讓系統(tǒng)自動生成對應(yīng)的注釋標記,應(yīng)先編寫方法,然后在方法名的上方輸入“///”,否則不會自動生成對應(yīng)的參數(shù)注釋等標記。
3.1.5 命名空間
Microsoft.NET框架提供了1000多個類,用于完成各種各樣的功能。根據(jù)類的功能不同,這些類又被劃分到不同的命名空間中(Namespace)。命名空間包含可在程序中使用的類、結(jié)構(gòu)、枚舉、委托和接口。一個命名空間又可以包含其他命名空間。命名空間只是一種邏輯上的劃分,而不是物理上的存儲分類。命名空間是一種組織C#程序中出現(xiàn)的不同類型的方式。命名空間在概念上與計算機文件系統(tǒng)中的文件夾有些類似。與文件夾一樣,命名空間可使類具有唯一的完全限定名稱。一個C#程序包含一個或多個命名空間,每個命名空間或者由程序員定義,或者作為之前編寫的類庫的一部分定義。
C#程序主要是利用命名空間來組織的,函數(shù)庫即由一個個的命名空間來組成。每個命名空間都可以視為一個容器,容器里可以存放類、接口以及結(jié)構(gòu)等程序。.NET利用命名空間來對程序進行分類,把功能相似的類、結(jié)構(gòu)等程序放在同一個命名空間中,便于管理,也便于程序設(shè)計人員使用。最常見的命名空間是System命名空間,它包含了許多常用的結(jié)構(gòu)類型(例如int、bool)和許多類(如Console、Expection)。
C#語言使用命名空間來組織系統(tǒng)類型或用戶自定義的數(shù)據(jù)類型。如果沒有明確地聲明一個命名空間,則用戶代碼中所定義的類型將位于一個未命名的全局命名空間中。這個全局命名空間中的類型對于所有的命名空間都是可見的。不同命名空間中的類型可以具有相同的名字,但是同一命名空間中的類型的名字不能相同。在編寫C#程序時,通常都要先聲明一個命名空間,然后在這個命名空間中定義自己的類型。其語法為:
namespace名稱[.名稱] { …… }
命名空間作為一個容器,其里面的區(qū)域需要用一個大括號“{}”來標識,這與類(Class)和方法(Method)的定義一樣。如“Hello Word”的例子:
namespace hello { class Program { static void Main(string[] args) { Console.WriteLine("Hello Word"); //需顯示的字符串 } }
}
若要調(diào)用命名空間下某個類提供的方法,可以使用下面的語法之一:
① 命名空間. 命名空間……命名空間.類名稱.靜態(tài)方法名(參數(shù), ……); ② 命名空間. 命名空間……命名空間.實例名稱.方法名(參數(shù), ……);
例如,前面“Hello Word”例子中的字符串輸出語句可以寫成:
System. Console.WriteLine("Hello Word");
這條語句使用的命名空間為System。在System命名空間下,有一個Console類,該類提供了靜態(tài)的WriteLine方法,調(diào)用此方法來輸出字符串“Hello Word”。
顯然,從上面的例子可以看到,每條語句都加上命名空間太煩瑣了。為了加快引用需要的功能,一般可以在程序的開頭引用命名空間來簡化代碼的書寫形式。例如,上面的語句“System. Console.WriteLine("Hello Word");”,前綴“System.”表示Console類在System命名空間下,如果在程序的開頭寫上:
using System;
那么,語句中就不需要加上命名空間前綴了,而可以直接寫為:
Console.WriteLine("Hello Word");
這種形式體現(xiàn)了名稱空間的方便。前面的“Hello Word”例子中正是采用了這種形式。
在C#程序中,不管是簡單的數(shù)據(jù)類型,還是執(zhí)行其他復(fù)雜操作,都必須通過函數(shù)庫才能實現(xiàn)。.NET類庫(Library)中包含了許多類,如按鈕、復(fù)選框等。利用類庫,可以開發(fā)出具有優(yōu)美界面的應(yīng)用程序。
.NET類庫中還包含了許多可以實現(xiàn)其他豐富功能的類,如存取網(wǎng)絡(luò)、數(shù)據(jù)庫操作等,這些類庫使C#編寫的程序功能無比強大。
為了方便地運用這些函數(shù)庫,C#程序使用using關(guān)鍵字將函數(shù)庫包含進來。可以看到,C#的using與C/C++中的#include十分相似,都是為了使用已經(jīng)設(shè)計好的程序。
以下程序代碼的執(zhí)行結(jié)果是:在DOS命令窗口中,按提示輸入名字后,顯示一條歡迎信息,如圖3-3所示。如果去掉using這一行,則程序編譯無法通過。

圖3-3 運行結(jié)果
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關(guān)鍵字的主要目的是讓編譯器知道,程序中將使用定義在System中的所有類。程序設(shè)計人員在程序中便可以不必通過完整的類的名稱來使用類,如System.Console.Write。
如果不使用using關(guān)鍵字來設(shè)計C#程序,要實現(xiàn)范例中的功能也是可以的,只是此時編譯器不知道程序中會使用定義在System中的類,設(shè)計人員在使用System中的類時,則需要輸入完整的類名稱。例如,上面的范例程序在去掉using關(guān)鍵字的第一行程序后,程序修改如下:
System.Console.WriteLine("Please enter your name:"); //輸出提示信息 System.Console.ReadLine(); //從鍵盤讀入一行字符 System.Console.WriteLine("Welcome to the world of C#!"); //顯示歡迎信息
3.2 變量
當程序?qū)?shù)據(jù)進行讀、寫、運算等操作,需要保存特定的值或計算結(jié)果時,需要用到變量(Variable)。變量是用來描述一條信息的名稱,在變量中可以存儲各種類型的信息,如人的姓名、車票的價格、文件的長度等。
3.2.1 變量的命名
變量是計算機中占據(jù)一定內(nèi)存單元的存儲區(qū)域,通過指定變量的名稱來使用和管理變量。從數(shù)據(jù)存儲角度看,變量名相當于存儲數(shù)據(jù)的變量所占的存儲區(qū)域的標識名。
當需要訪問存儲在變量中的信息時,只需要使用變量的名稱即可。為變量起名時要遵守C#語言的規(guī)定:
⊙ 變量名必須以字母開頭。
⊙ 變量名只能由字母、數(shù)字和下劃線組成,不能包含空格、標點符號、運算符等其他符號。
⊙ 變量名不能與C#中的關(guān)鍵字名稱相同。
⊙ 變量名不能與C#中的庫函數(shù)名稱相同。
在C#中有一點是例外,即允許在變量名前加上前綴“@”。在這種情況下,可以使用前綴“@”加上關(guān)鍵字作為變量的名稱。這主要是為了與其他語言進行交互時避免沖突。因為前綴“@”實際上并不是名稱的一部分,其他編程語言會把它作為一個普通的變量名。在其他情況下,不推薦使用前綴“@”作為變量名的一部分。
在命名變量時,除了必須遵守C#規(guī)則以外,還應(yīng)遵守一些命名約定。良好的編程習(xí)慣有助于提高程序的正確性、可讀性、可維護性和可用性。常用數(shù)據(jù)類型的前綴如表3.1所示。
表3.1 常用數(shù)據(jù)類型的前綴

3.2.2 數(shù)據(jù)類型
C#程序完全由類型構(gòu)成,并且它的所有功能也都是通過各種類型來實現(xiàn)的。類型定義了允許的值以及在這些值上允許的操作,包括 .NET框架提供的類型以及用戶自定義的類型。
C#語言中的數(shù)據(jù)類型可以分為兩類:值類型(Value Type)和引用類型(Reference Type)。值類型包括:簡單類型(如char、int和float)、結(jié)構(gòu)類型和枚舉類型,而引用類型包括:類類型、接口類型、數(shù)組類型和委托類型。值類型和引用類型的區(qū)別在于,值類型的變量直接存放實際數(shù)據(jù),而引用類型的變量存放的則是數(shù)據(jù)的地址,即對象的引用。
在C#語言中,所有的值類型都是從System.Object類派生的,System.Object類是所有類型的基類,并且不能派生新的值類型。同時,所有的值類型都具有一個隱含的構(gòu)造函數(shù)用于初始化。C#的值類型可以分為以下幾種:簡單類型(Simple Type)、結(jié)構(gòu)類型(Struct Type)、枚舉類型(Enumeration Type)。
簡單類型有時也稱為純量類型,是直接由一系列元素構(gòu)成的數(shù)據(jù)類型。C#語言中的簡單類型包括:整數(shù)類型、布爾類型、實數(shù)類型和字符類型。本章重點介紹簡單數(shù)據(jù)類型,而其他數(shù)據(jù)類型的知識將在后續(xù)章節(jié)介紹。
1.整數(shù)類型
顧名思義,整數(shù)類型的變量的值為整數(shù)。數(shù)學(xué)上的整數(shù)可以從負無窮大到正無窮大,但是由于計算機的存儲單元是有限的,所以計算機語言提供的整數(shù)類型的值總是在一定范圍之內(nèi)。C#語言提供了9種整數(shù)類型:短字節(jié)型(sbyte)、字節(jié)型(byte)、短整型(short)、無符號短整型(ushort)、整型(int)、無符號整型(uint)、長整型(long)、無符號長整型(ulong)和字符型(char)。劃分的依據(jù)是根據(jù)該類型的變量在內(nèi)存中所占的位數(shù)。這些整數(shù)類型在數(shù)學(xué)上的表示以及在計算機中的取值范圍如表3.2所示。
表3.2 整數(shù)類型

【例3-1】整型變量的使用。創(chuàng)建一個控制臺程序,驗證短整型整數(shù)類型的取值范圍。
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(); //按回車鍵結(jié)束 } } }
說明:程序中的short類型整數(shù)x已經(jīng)超出了系統(tǒng)定義的范圍(-32768~32767)。
程序運行結(jié)果如圖3-4所示。

圖3-4 例3-1運行結(jié)果
2.布爾類型
布爾類型用來表示“真”和“假”。在C#語言中,布爾類型用bool表示,其值為true或false。例如:
bool a=true; int i=20; bool b=(i>0 && i<10);
注意:C#條件表達式的運算結(jié)果一定是布爾類型。另外,在C/C++中,可用0來表示“false”,其他任何非0的值可表示為“true”,但這在C#中已經(jīng)被廢棄。在C#中,true值不能被其他任何非0值所代替。在其他整數(shù)類型和布爾類型之間不再存在任何轉(zhuǎn)換,將整數(shù)類型轉(zhuǎn)換成布爾類型是不合法的。例如:
bool c=1; //錯誤,不允許這種寫法
3.實數(shù)類型
數(shù)學(xué)中的實數(shù)不僅包括整數(shù),還包括小數(shù)。帶小數(shù)的實數(shù)在C#中采用兩種數(shù)據(jù)類型來表示:單精度(float)和雙精度(double)。它們的差別在于取值范圍和精度不同。計算機對于浮點數(shù)的運算速度大大低于對整數(shù)的運算。在對精度要求不是很高的浮點數(shù)計算中,可以采用float型,而采用double型獲得的結(jié)果將更為精確。單精度型和雙精度型可統(tǒng)稱浮點類型,它們的具體說明如表3.3所示。
表3.3 浮點數(shù)類型

C#語言還提供了一種十進制類型(decimal),主要用于方便在金融和貨幣方面的計算。在現(xiàn)代的企業(yè)應(yīng)用程序中,不可避免地要進行大量的關(guān)于這方面的計算和處理。C#通過提供這種專門的數(shù)據(jù)類型,可更為快捷地開發(fā)有關(guān)金融和貨幣方面的應(yīng)用程序。
十進制類型是一種大范圍、高精度的數(shù)據(jù)類型,占16字節(jié),所表示的范圍大約為1.0×10-28~7.9×1028,可精確到28~29位有效數(shù)字。雖然十進制類型的取值范圍遠小于雙精度類型,但它更精確,特別適用于金融、貨幣等需要高精度數(shù)值的領(lǐng)域。當聲明一個decimal變量并賦值時,使用M/m類型指定符以表明它是一個十進制類型。例如:
decimal a=10000.56m;
如果省略m,在變量被賦值之前,它將被編譯器當作雙精度類型來處理。
4.字符類型
除了數(shù)字以外,計算機處理的信息主要就是字符了。字符包括數(shù)字字符、英文字符、符號等。C#提供的字符類型(char)按照國際上公認的標準,采用Unicode字符集。一個Unicode字符的標準長度為2字節(jié),共16位,可以表示世界上大多數(shù)語言。字符型變量可以用單引號括起來的字符直接賦值。字符型(char)還可表示無符號的16位整數(shù),它的可能值集與Unicode字符集相對應(yīng),雖然表示形式上與短整型(ushort)相同,但意義不同,ushort代表的是數(shù)值本身,而char代表的是一個字符。
3.2.3 變量的聲明
變量使用之前,必須先聲明,即給變量指定名稱和類型。聲明變量以后,便可以將它們用作存儲單元來存取相應(yīng)類型的數(shù)據(jù)。
聲明變量的一般形式如下:
① [附加聲明][訪問修飾符] 數(shù)據(jù)類型 變量名; ② [附加聲明][訪問修飾符] 數(shù)據(jù)類型 變量名=正確數(shù)據(jù)類型的初始值;
說明:[ ]表示該內(nèi)容為可選項,修飾符可以是public、private、internal、new等關(guān)鍵字。下面給出一些合法和非法的變量名的例子:
int i; //合法 string total; //合法
char use; //不合法,與關(guān)鍵字名稱相同 char@use; //合法 float Main; //不合法,與函數(shù)名稱相同
C#中允許在一條語句中命名多個類型相同的變量。如:
int a,b,c=50;
聲明變量后并對其賦值稱為變量的初始化。在上面給出的聲明變量的兩種格式中,第一種格式僅完成變量的聲明,而第二種格式既聲明了變量,同時又完成了變量的初始化。下面給出一些變量初始化的例子:
int i; i = 100; char name; name = 'a'; //上面兩個例子是先聲明變量,再賦值 int i = 100; char name = 'a'; //這兩個例子是在聲明變量的同時對其初始化
3.3 常量
所謂常量,就是其值固定不變的量。從數(shù)據(jù)類型角度來看,常量的類型可以是任何一種值類型或引用類型。一個常量的聲明就是聲明程序中要用到的常量的名稱和它的值。常量的命名規(guī)則同變量一樣。
常量有直接常量和符號常量兩種。
1.直接常量
直接常量即數(shù)據(jù)值本身。
(1)整型常量
整型常量通常有三種形式:
⊙ 十進制形式:123,+123,-123等。
⊙ 八進制形式:在數(shù)字前加0,如0123,+0123,-0123等。
⊙ 十六進制形式:在數(shù)字前加“0x”或“0X”,如0x123,+0X123,-0X123等。
(2)實型常量
實型常量通常有兩種形式:
⊙ 小數(shù)形式:0.123,-0.123等。
⊙ 指數(shù)形式:123e4,-123E-4等。
(3)字符(串)常量
單個字符用一對英文單引號界定,表示字符常量,如'A'、'中'、'+'等。一串字符用一對英文雙引號界定,表示字符串常量,如"歡迎學(xué)習(xí)C#!"、"你好!"、"hello!"等。
注意:單引號和雙引號也可以看成是字符常量,能不能也用上面的方法來表示呢?下面介紹有關(guān)“轉(zhuǎn)義符”的相關(guān)知識。
同C語言一樣,轉(zhuǎn)義字符是C#語言中的一種特殊的字符型常量表示形式,可以將轉(zhuǎn)義字符簡單地理解為“轉(zhuǎn)變了本身含義的字符”。例如,“\n”并非表示一個“\”和一個“n”,而是表示換行符。
使用轉(zhuǎn)義字符主要是由于以下三個原因:
⊙ 某些字符具有控制功能,直接的鍵盤按鍵不能輸入這些字符(如換行符、退格符等)。
⊙ 擴展的ASCII編碼可以有255字符,而計算機的標準鍵盤只能輸入基本的ASCII字符,而不能輸入擴展部分的字符,如字符“§”。
⊙ 某些字符在C#語言中具有特定的含義,不能作為普通字符處理。例如,單引號對作為字符型常量的定界符,如果使用“'''”的形式表示字符“'”,將出現(xiàn)語法錯誤。
在C#語言中也采用轉(zhuǎn)義符來表示一些特殊的字符,包括一些控制字符。在表3.4中列出了一些定義字符型數(shù)據(jù)和字符串類型數(shù)據(jù)時常用的轉(zhuǎn)義符。
表3.4 常用轉(zhuǎn)義符

【例3-2】轉(zhuǎn)義字符的使用。使用轉(zhuǎn)義字符控制輸出結(jié)果的顯示格式。
using System; namespace ConsoleApplication1 { class Test { public static void Main() { Console.WriteLine("\n\tHello\n\tWorld!"); Console.Read(); } } }
說明:程序中使用了換行字符“\n”和水平制表字符“\t”。在輸出的字符串中,“\n”產(chǎn)生換行效果,而“\t”引起屏幕位置向右移動8個字符位置,故稱為水平制表字符。
程序的運行結(jié)果如圖3-5所示。

圖3-5 例3-2運行結(jié)果
(4)布爾常量
布爾常量即布爾值:true或false。
2.符號常量
符號常量聲明的格式如下:
[附加聲明][訪問修飾符] const數(shù)據(jù)類型 常量名=正確數(shù)據(jù)類型的值;
說明:[ ]表示該內(nèi)容為可選項,修飾符可以是public、private、internal、new和protected。
例如:
public const double X=1.0, Y=2.0, Z=3.0;
同樣地,C#允許在一條語句中同時聲明多個常量。常量也有一個命名約定。習(xí)慣上,常量名全部使用大寫字母表示。
3.4 表達式
C#語言中的表達式類似于數(shù)學(xué)運算中的表達式,是操作符、操作對象和標點符號等連接而成的式子。操作符是用來定義類實例中表達式操作符的。表達式是指定計算的操作符、操作數(shù)序列。操作符指出了對操作數(shù)的操作。比如,操作符有+、-、/和new;操作數(shù)可以是文字、域、當前變量或表達式。單個的常量、變量和函數(shù)也可以看作是一個最簡單的表達式。
與運算類型相對應(yīng),包含某種運算符的表達式則稱為某種類型的表達式,因而C#語言主要有算術(shù)表達式、關(guān)系表達式、邏輯表達式、賦值表達式、條件表達式等。
表達式無論長短與否,最終應(yīng)該計算出一個確定的值,結(jié)果值的類型要取決于表達式的類型或表達式中混合運算時的類型轉(zhuǎn)換情況。
3.4.1 操作符
依照操作符作用的操作數(shù)的個數(shù)來分,C#中有三種類型的操作符。
⊙ 一元操作符:作用于一個操作數(shù)。一元操作符又包括前綴操作符和后綴操作符。
⊙ 二元操作符:作用于兩位操作數(shù),使用時在操作數(shù)中間插入操作符。
⊙ 三元操作符:C#中僅有一個三元操作符“?:”,三元操作符作用于三個操作數(shù),使用時在操作數(shù)中間插入操作符。
下面分別給出使用操作符的例子:
int x=5, y=10, z; x++; //后綴一元操作符 --x; //前綴一元操作符 z=x+y; //二元操作符 y=(x>10?0:1); //三元操作符
常用操作符如表3.5所示。
表3.5 常用操作符

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

技術(shù)要點
① 從表3.6中可以看出,一元運算符的優(yōu)先級高于二元和三元運算符。
② 不同種類運算符的優(yōu)先級有高低之分。算術(shù)運算符的優(yōu)先級高于關(guān)系運算符,關(guān)系運算符的優(yōu)先級高于邏輯運算符,邏輯運算符的優(yōu)先級高于條件運算符,條件運算符的優(yōu)先級高于賦值運算符。
③ 有些同類運算符優(yōu)先級也有高低之分。在算術(shù)運算符中,乘、除、求余的優(yōu)先級高于加、減;在關(guān)系運算符中,小于、大于、小于等于、大于等于的優(yōu)先級高于相等和不等;邏輯運算符的優(yōu)先級按從高到低為非、與、或。
④ 當一個操作數(shù)出現(xiàn)在兩個有相同優(yōu)先級的操作符之間時,操作符按照出現(xiàn)的順序由左至右執(zhí)行。
⑤ 為了提高表達式的可讀性,可以使用圓括號明確運算順序或改變運算順序。
⑥ 除了賦值操作符,所有的二進制的操作符都是左結(jié)合(left-associative)的,也就是說,操作按照從左向右的順序執(zhí)行。例如,x + y + z按(x + y) + z進行求值。
⑦ 賦值操作符和條件操作符(?:)按照右接合(right-associative)的原則,即操作按照從右向左的順序執(zhí)行,如x = y = z按照x = (y = z)進行求值。
3.4.2 算術(shù)表達式
C#中提供的算術(shù)操作符有5種:+,加法操作符;-,減法操作符;*,乘法操作符;/,除法操作符;%,求余操作符。
在表達式的運算中,表達式總是按它們本身書寫的順序求值。由算術(shù)操作符連接操作數(shù)而組成的表達式稱為算術(shù)表達式。
【例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。
程序的運行結(jié)果如圖3-6所示。

圖3-6 例3-3運行結(jié)果
【例3-4】 除法運算。演示同一操作符、不同操作數(shù)及不同數(shù)據(jù)類型得到不同的計算結(jié)果。
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)) } }
說明:在除法運算過程中,默認的返回值的類型與精度最高的操作數(shù)類型相同。比如5/2的結(jié)果為2,而5.0/2結(jié)果為2.5。如果兩個整數(shù)類型的變量相除又不能整除的話,返回的結(jié)果是不大于相除之值的最大整數(shù)。
程序運行的結(jié)果如圖3-7所示。

圖3-7 例3-4運行結(jié)果
3.4.3 賦值表達式
賦值就是給一個變量賦一個新值。C#中提供的賦值操作符有:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=。
賦值的左操作數(shù)必須是一個變量、屬性訪問器或索引訪問器的表達式。
C#中可以對變量進行連續(xù)賦值,這時賦值操作符是右關(guān)聯(lián)的,這意味著從右向左操作符被分組。例如,形如a = b = c的表達式等價于a = (b = c)。
如果賦值操作符兩邊的操作數(shù)類型不一致,則先進行類型轉(zhuǎn)換。賦值運算包括簡單賦值和復(fù)合賦值兩種。
(1)簡單賦值
“=”操作符被稱為簡單賦值操作符。在一個簡單賦值中,右操作數(shù)必須為某種類型的表達式,且該類型必須可以隱式地轉(zhuǎn)換成左操作數(shù)類型。該運算將右操作數(shù)的值賦給作為左操作數(shù)的變量、屬性或者索引器類型。簡單賦值表達式的結(jié)果是被賦值給左操作數(shù)的值。結(jié)果類型和左操作數(shù)的類型相同,且總是值類型。
(2)復(fù)合賦值
C#語言有把賦值號和其他的運算符結(jié)合起來,組成復(fù)合賦值運算符,使表達式的形式更加簡潔,提高了編譯的效率。復(fù)合賦值運算符形式是:
<變量名> <其他運算符>=<表達式>;
其功能相當于:
<變量名> = <變量名> <其他運算符> <表達式>;
形如x op = y的運算可以處理成形如x op y的二進制操作符重載方法。例如:
x+=5; //等于x=x+5 x%=3; //等于x=x%3 x*=y+1; //等于x=x*(y+1)
復(fù)合賦值進行的步驟如下:
① 如果所選操作符的返回類型可以隱式轉(zhuǎn)換成x的數(shù)據(jù)類型,執(zhí)行x = x op y的運算,除此之外,僅對x執(zhí)行一次運算。
② 否則,所選操作符是一個預(yù)定義操作符,所選操作符的返回值類型可以顯式地轉(zhuǎn)換成x的類型,且y可以隱式地轉(zhuǎn)換成x的類型,那么該運算等價于x = (T) (x op y)運算。這里T是x的類型,除此之外,x僅被執(zhí)行一次。
③ 否則,復(fù)合賦值是無效的,將產(chǎn)生編譯時錯誤。
【例3-5】復(fù)合賦值運算。
復(fù)合賦值運算符在使用過程中,關(guān)鍵需要掌握的是運算的基本規(guī)則和結(jié)合性問題。下面的例子用來說明復(fù)合賦值運算符的使用方法。
using System; class Test { public static void Main() { int a = 12; a += a -= a *= a; Console.WriteLine(a);
Console.Read(); } }
說明:由于賦值運算符是右結(jié)合性的,所以表達式a+=a-=a*=a等價于a+=(a-=(a*=a)),該表達式的求解過程為:
首先計算a*=a,則a=144;
接著計算a-=144,則a=12-144= -132;
最后計算a+=-132,則a= 12+(-132)=-120。
程序的運行結(jié)果為-120。
3.5 小結(jié)
本章介紹了C#語言的基礎(chǔ)知識,包括C#的基本語法知識、變量常量的命名規(guī)則、變量的聲明及初始化、直接常量的種類、符號常量的聲明,舉例說明了算術(shù)運算符和賦值運算符及其表達式的用法。
課外閱讀──算術(shù)溢出
算術(shù)運算符(+、-、*、/)產(chǎn)生的結(jié)果可能會超出涉及的數(shù)值類型可能值的范圍。一般情況下:
整數(shù)算術(shù)溢出或者引發(fā)OverflowException,或者丟棄結(jié)果的最高有效位。整數(shù)被零除總是引發(fā)DivideByZeroException。
浮點算術(shù)溢出或被零除從不引發(fā)異常,因為浮點類型基于IEEE 754,因此可以表示無窮和NaN(不是數(shù)字)。
小數(shù)算術(shù)溢出總是引發(fā)OverflowException。小數(shù)被零除總是引發(fā)DivideByZeroException。
當發(fā)生整數(shù)溢出時,產(chǎn)生的結(jié)果取決于執(zhí)行上下文,該上下文可為checked或unchecked。在checked上下文中引發(fā)OverflowException。在未選中的上下文中,放棄結(jié)果的最高有效位并繼續(xù)執(zhí)行。因此,C# 使您有機會選擇處理或忽略溢出。
除算術(shù)運算符以外,整型之間的強制轉(zhuǎn)換也會導(dǎo)致溢出(如將long強制轉(zhuǎn)換為int)并受checked或unchecked執(zhí)行的限制。然而,按位運算符和移位運算符永遠不會導(dǎo)致溢出。
練習(xí) 3
一、選擇題
1.C#語言屬于____。
A.機器語言
B.匯編語言
C.面向過程的語言
D.面向?qū)ο蟮某绦蛟O(shè)計語言
2.一個C#語言程序總是從____開始執(zhí)行。
A.書寫順序的第一個函數(shù)
B.書寫順序的第一條執(zhí)行語句
C.Main( )方法
D.不確定
3.把已經(jīng)編寫好的源程序翻譯成二進制的目標代碼的步驟是____。
A.編輯
B.編譯
C.連接
D.執(zhí)行
4.C#語言中的標識符只能由字母,數(shù)字和下劃線組成,且第一個字符____。
A.必須為字母
B.必須為下劃線
C.必須為字母或下劃線
D.可以是字母,數(shù)字或下劃線中任一種
5.以下選項中,不屬于C#語言數(shù)據(jù)類型的是____。
A.int
B.short
C.long
6.在C#語言中,合法的數(shù)據(jù)形式是____。
A.±23
B.±1.23
C.234
7.以下選項中,合法的字符常量是____。
A.'B'
B."A"
C.CD
8.以下選項中,合法的用戶標識符是____。
A.long
B._2Test
C.3Dmax
9.在C#語言中,下列運算符優(yōu)先級最高的是____。
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.下列數(shù)據(jù)類型不屬于C#整數(shù)類型的是____。
A.sbyte
B.short
C.ushort
D.string
12.關(guān)于數(shù)據(jù)類型float說法不正確的是____。
A.該數(shù)據(jù)類型用于表示實數(shù)
B.該數(shù)據(jù)類型占4個字節(jié)空間
C.該數(shù)據(jù)類型表示雙精度浮點數(shù)
D.該數(shù)據(jù)類型表示單精度浮點數(shù)
13.關(guān)于數(shù)據(jù)類型char說法不正確的是____。
A.該數(shù)據(jù)類型可用于表示單個字符
B.該數(shù)據(jù)類型可表示32位整數(shù)
C.該數(shù)據(jù)類型可表示16位無符號整數(shù)
D.該數(shù)據(jù)類型用于表示整數(shù)時與ushort在形式上類似,但意義不同
14.下列關(guān)于“聲明變量”的說法中,最準確的是____。
A.為變量命名
B.給變量賦值
C.在C#中,一次最多聲明一個變量
D.命名變量并說明變量的數(shù)據(jù)類型
15.在下列轉(zhuǎn)義符形式中,表示“回車符”的是____。
A.\0
B.\r
C.\n
D.\t
二、填空題
16.在C#語言中,每條語句都以____結(jié)束。
17.C#有多種注釋方法,其中 【A】 適用于單行注釋,【B】 適用于多行注釋。
18.在C#語言中,實數(shù)類型包含三種: 【A】 、 【B】 和 【C】。
19.C#語言規(guī)定變量在使用之前必須先____后使用。
20.在C#表達式中,可通過____改變運算符的運算順序,使表達式更清晰易懂。
21.在C#語言中,使用____關(guān)鍵字聲明符號常量。
22.在代碼中,明確指示將某一數(shù)據(jù)類型轉(zhuǎn)換為另一種數(shù)據(jù)類型稱為____。
23.在C#語言中,系統(tǒng)命名空間使用____關(guān)鍵字導(dǎo)入。
24.除了賦值操作符,所有的二進制的操作符都是____的,也就是說,操作按照從左向右的順序執(zhí)行。
25.不同種類運算符的優(yōu)先級有高低之分。【A】 的優(yōu)先級高于關(guān)系運算符,關(guān)系運算符的優(yōu)先級高于邏輯運算符,邏輯運算符的優(yōu)先級高于條件運算符,條件運算符的優(yōu)先級高于 【B】。
26.C#中的表達式類似于數(shù)學(xué)運算中的表達式,是由 【A】 、 【B】 和標點符號等連接而成的式子。
27.在C#中,有些字符不能直接放在單引號中作為字符常量,這就需要使用轉(zhuǎn)義符來表示這些字符常量,轉(zhuǎn)義符由____加字符組成。
三、求下列表達式的值
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;
四、將下列數(shù)學(xué)表達式改寫為等價的C#表達式
30.
31.(4+3x)2-abc
32.
五、問答題
33.簡述C#語言中變量的命名規(guī)則?
34.什么是命名空間?命名空間有何作用?
35.在C#代碼編寫中,使用縮進格式及注釋語句是C#的語法規(guī)則嗎?它們的作用是什么?
- JavaScript從入門到精通(微視頻精編版)
- JavaScript修煉之道
- Learning Docker
- 摩登創(chuàng)客:與智能手機和平板電腦共舞
- Windows系統(tǒng)管理與服務(wù)配置
- Web交互界面設(shè)計與制作(微課版)
- Mastering Kali Linux for Web Penetration Testing
- Learning Salesforce Einstein
- Java網(wǎng)絡(luò)編程核心技術(shù)詳解(視頻微課版)
- 深度學(xué)習(xí)原理與PyTorch實戰(zhàn)(第2版)
- App Inventor 2 Essentials
- Learning Grunt
- AMP:Building Accelerated Mobile Pages
- 會當凌絕頂:Java開發(fā)修行實錄
- Java高級程序設(shè)計