主頁 > .NET開發 > C#入門到精通系列課程——第3章變數及運算子

C#入門到精通系列課程——第3章變數及運算子

2021-04-25 06:16:35 .NET開發

◆本章內容

(1)變數是什么

(2)變數的宣告及初始化

(3)常量

(4)運算子

(5)資料型別轉換

(6)運算子優先級及結合性

(7)難點解答

◆本章簡述

很多人認為學習C#之前必須要學習C++,其實并非如此,產生這種錯誤的認識是因為很多人在學習C#之前都學過C++,事實上,C#比C++更容易掌握,要掌握并熟練應用C#,就需要對C#語言基礎進行充分的了解,本章將對C#語言的基礎語法進行詳細講解,對于初學者來說,應該對本章內容進行仔細的閱讀和深入的思考,這樣才能達到事半功倍的效果,

知識框架

 

 

 3.1  為什么要使用變數

變數關系到資料的存盤,計算機是使用記憶體來存盤計算時所使用的資料,那么記憶體是如何存盤資料的呢?通過生活常識,我們知道資料是各式各樣的,比如整數、小數、字串等等,那么,在記憶體中存盤這些資料時,就首先需要根據資料的需求(即型別)為它申請一塊合適的空間,然后在這個空間中存盤相應的值,實際上,記憶體就像一個賓館,客人如果到一個賓館住宿,首先需要開房間,然后再入住,而在開房間時,客人需要選擇是開單間、開雙人間、還是開總統套房等等,這其實就對應一個變數的資料型別選擇問題,

在記憶體中為資料分配一定的空間之后,如果要使用定義的這個資料,由于記憶體中的資料是以二進制格式進行存盤的,而這些二進制資料都對應相應的記憶體地址,因此,必須通過一種技術使用戶能夠方便地訪問到二進制資料的記憶體地址,這種技術就是變數,

3.2  變數是什么

變數主要用來存盤特定型別的資料,用戶可以根據需要隨時改變變數中所存盤的資料值,變數具有名稱、型別和值,其中,變數名是變數在程式源代碼中的標識,型別用來確定變數所代表的記憶體的大小和型別,變數值是指它所代表的記憶體塊中的資料,在程式執行程序中,變數的值可以發生變化,使用變數之前必須先宣告變數,即指定變數的型別和名稱,

這里以上面的客人入住賓館為例,說明一個變數所需要的基本要素,首先,客人需要選擇房間型別,也就是確定變數型別的程序;選擇房間型別后,需要選擇房間號,這是確定變數的名稱;完成以上操作后,這個客人就可以順利入住,這樣,這個客人就相當于這個房間中存盤的資料,示意圖如圖3.1所示,

 

 

 

3.3  變數的宣告及初始化

好比一個新生兒必須有一個名字一樣,使用變數時,也需要首先對變數進行命名,對變數命名的程序,其實就是宣告一個變數,變數在使用之前,必須進行宣告并初始化,本節將對變數的宣告、簡單資料型別、變數初始化,以及變數的作用域進行詳細講解,

3.3.1  宣告變數

1.宣告變數

宣告變數就是指定變數的名稱和型別,變數的宣告非常重要,未經宣告的變數本身并不合法,也無法在程式中使用,在C#中,宣告一個變數是由一個型別和跟在后面的一個或多個變數名組成,多個變數之間用逗號分開,宣告變數以分號結束,語法如下:

 

 

 例如,宣告一個整型變數mr,然后再同時宣告3個字串型變數mr_1.mr_2和mr_3,代碼如下:

 

 

 

2.變數的命名規則

在宣告變數時,要注意變數的命名規則,C#的變數名是一種識別符號,應該符合識別符號的命名規則,另外,需要注意的一點是:C#中的變數名是區分大小寫的,比如num和Num是兩個不同的變數,在程式中使用時是有區別的,下面列出變數的命名規則:

◆變數名只能由數字、字母和下劃線組成,

◆變數名的第一個字符只能是字母或下劃線,不能是數字,

◆不能使用C#中的關鍵字作為變數名,

◆一旦在一個陳述句塊中定義了一個變數名,那么在變數的作用域內都不能再定義同名的變數,例如,下面的變數名是正確的:

下面的變數名是不正確的:

 

說明:在C#語言中允許使用漢字或其他語言文字作為變數名,如“int年齡=21”,在程式運行時并不出現什么錯誤,但建議讀者盡量不要使用這些語言文字作為變數名,

3.3.2  簡單資料型別

前面提到,宣告變數時,首先需要確定變數的型別,那么,開發人員可以使用哪些型別呢?實際上,可以使用的變數型別是無限多的,因為開發人員可以通過自定義型別存盤各種資料,但這里要講解的簡單資料型別是C#中預定義的一些型別,

C#中的資料型別根據其定義可以分為兩種:一種是值型別,另一種是參考型別,從概念上看,值型別是直接存盤值,而參考型別存盤的是對值的參考,C#中的資料型別結構如圖3.2所示,

 

 

 從圖3.2可以看出,值型別主要包括簡單型別和復合型別兩種,其中簡單型別是程式中使用的最基本型別,主要包括整數型別、浮點型別、布爾型別和字符型別等4種,這4種簡單型別都是.NET中預定義的;而復合型別主要包括列舉型別和結構型別,這兩種復合型別既可以是.NET中預定義的,也可以是用戶自定義的,本節主要對簡單型別進行詳細講解,簡單型別在實際中的應用如圖3.3所示,

 

 

 

1.整數型別

整數型別用來存盤整數數值,即沒有小數部分的數值,可以是正數,也可以是負數,整型資料在C#程式中有3種表示形式,分別為十進制、八進制和十六進制,

◆十進制:十進制的表現形式就是我們在日常生活中使用的資料,如120、0、-127,

注意:不能以0作為十進制數的開頭(0除外),

◆八進制:以0開頭的數,如0123(轉換成十進制數為83)、-0123(轉換成十進制數為-83),

注意:八進制必須以0開頭,

◆十六進制:以0x或0X開頭的數,如0x25(轉換成十進制數為37)、0Xb01e(轉換成十進制數為45086),

注意:十六進制必須以0X或0x開頭,

C#中內置的整數型別如表3.1所示,

 

 

 說明:表3.1中出現了“有符號整數”和“無符號整數”,其中,“無符號整數”是在“有符號整數”型別的前面加了一個u,這里的u是unsigned的縮寫,它們的主要區別是:“有符號整數”既可以存盤正數,也可以存盤負數;“無符號整數”只能存放不帶符號的整數,因此,它只能存放正數,例如,下面的代碼:

 

 

 例如,定義一個int型別的變數i和一個byte型別的變數j,并分別賦值為2017和255,代碼如下:

 

 

 此時,如果將byte型別的變數j賦值為256,即將代碼修改如下:

 

 

 此時在Visual Studio開發環境中編譯程式,會出現如圖3.4所示的錯誤提示,

 

 

 

 

分析圖3.4中出現的錯誤提示,主要是由于byte型別的變數是8位無符號整數,它的范圍在0~255之間,而256這個值已經超出了byte型別的范圍,所以編譯程式會出現錯誤提示,

說明:整數型別變數的默認值為0,

2.浮點型別

浮點型別變數主要用于處理含有小數的資料,浮點型別主要包含float和double兩種型別,表3.2列出了這兩種浮點型別的描述資訊,

 

 

 

如果不做任何設定,包含小數點的數值默認為是double型別,例如9.27,沒有特別指定的情況下,這個數值是double型別,如果要將數值以float型別來處理,就需要通過使用f或F將其強制指定為float型別,

例如,下面的代碼就是將數值強制指定為float型別,

 

 

 

如果要將數值強制指定為double型別,則應該使用d或D進行設定,但加不加“d”或“D”沒有硬性規定,可以加也可以不加,

例如,下面的代碼就是將數值強制指定為double型別,

 

 

 

注意:

(1)需要使用float型別變數時,必須在數值的后面跟隨f或F,否則編譯器會直接將其作為double型別處理另外,也可以在double型別的值前面加上(float),對其進行強制轉換,

(2)浮點型別變數的默認值是0,而不是0.0,

3.decimal型別

decimal型別表示128位資料型別,它是一種精度更高的浮點型別,其精度可以達到28位,取范圍為土1.0X1028~士7.9X1028

多學兩招:由于decimal型別的高精度特性,它更合適于財務和貨幣計算,

如果希望一個小數被當成decimal型別,需要使用后綴m或M,例如:

 

 

 如果小數沒有后綴m或M,數值將被視為double型別,從而導致編譯器錯誤,例如,在開發環境中運行下面代碼:

 

 

 將會出現如圖3.5所示的錯誤提示,

 

 

 

從圖3.5可以看出,3.14這個數如果沒有后綴,直接被視為double型別,所以賦值給decimal型別的變數時,就會出現錯誤提示,應該將3.14改為3.14m或3.14M,

實體01:根據身高和體重計算BMI指數

創建一個控制臺應用程式,宣告double型變數height來記錄身高,單位為米,宣告int型變數weight記錄體重,單位為千克,根據“BMI=體重/(身高*身高)”的公式計算BMI指數(身體質量指數),代碼如下:

 

 

 

代碼注解:

第10、14、18和22行代碼使用了f...else if條件判斷陳述句,該陳述句主要用來判斷是否滿足某種條件,該陳述句將在后面章節進行詳細講解,這里只需要了解即可,

程式運行效果如圖3.6所示,

 

 

 

拓展訓練:

一、在用戶注冊模塊中,使用整型變數記錄用戶的年齡,

二、C#開發的財務系統中,需要創建一個存盤流動資金金額的臨時變數,則應使用下列( )陳述句?

A) decimal theMoney;

B) int theMoney;

C) string theMoney;

D) Dim theMoney as double;

4.bool 型別

bool型別(又稱布爾型別)主要用來表示true或者false 值,C#中定義布爾型別時,需要使用bool關鍵字,例如,下 面代碼定義一個布爾型別的變數:

 

 

 

說明:布爾型別通常被用在流程控制陳述句中作為判斷條件,

這里需要注意的是,布爾型別變數的值只能是true或者false,不能將其他的值指定給布爾型別變數,例如,將一個整數10賦值給布爾型別變數,代碼如下:

 

 

 在Visual Studio開發環境中運行這句代碼,會出現如圖3.7所示的錯誤提示,

 

 

 

說明:布爾型別變數的默認值為false,

5.字符型別

字符型別在C#中使用Char類來表示,該類主要用來存盤單個字符,它占用16位(兩個位元組)的記憶體空間,在定義字符型變數時,要以單引號('')表示,如'a'表示一個字符,而\"a\"則表示一個字串,因為雖然其只有一個字符,但由于使用了雙引號,所以它仍然表示字串,而不是字符,字符型別變數的宣告非常簡單,代碼如下:

 

 

 

注意:Char類只能定義一個Unicode字符,Unicode字符是目前計算機中通用的字符編碼,它為針對不同語言中的每個字符設定了統一的二進制編碼,用于滿足跨語言、跨平臺的文本轉換和處理的要求,這里了解Unicode即可,

◆Char類的使用

Char類為開發人員提供了許多的方法,可以通過這些方法靈活地對字符進行各種操作,Char類的常用方法及說明如表3.3所示,

 

 

 

從表3.3可以看到,C#中的Char類提供了很多操作字符的方法,其中以Is和To開始的方法比較常用,以Is開始的方法大多是判斷Unicode字符是否為某個類別,比如是否大小寫、是否是數字等;而以To開始的方法主要是對字符進行轉換大小寫及轉換字串的操作,

實體02:字符類Char的常用方法應用

創建一個控制臺應用程式,演示如何使用Char類提供的常見方法,代碼如下:

 

 

 

代碼注解:

(1)第3行到第8行代碼,宣告了5個不同型別的字符變數,下面的操作都是圍繞這5個字符變數進行的,

(2)第25行代碼主要是為了使控制臺界面能夠停留在桌面上,

程式的運行結果如圖3.8所示,

 

 

 

拓展訓練:

一、列印保險單詳細串列時,使用Char型別記錄用戶的性別是M(男)還是W(女),效果如圖3.9所示,

 

 

 

二、嘗試在Visual Studio 2017開發工具中比較'g'和103是否相等,

◆轉義字符

前面講到了字符只能存盤單個字符,但是,如果在Visual Studio開發環境中撰寫如下代碼:

 

 

 會出現如圖3.10所示的錯誤提示,

 

 

 

從代碼表面上看,反斜線“\”是一個字符,正常應該是可以定義為字符的,但為什么會出現錯誤呢?這里就引出了轉義字符的概念,

轉義字符是一種特殊的字符變數,以反斜線“\”開頭,后跟一個或多個字符,也就是說,在C#中,反斜線“\”是一個轉義字符,不能單獨作為字符使用,因此,如果要在C#中使用反斜線,可以使用下面代碼表示:

 

 

 

轉義字符就相當于一個電源變換器,電源變換器就是通過一定的手段獲得所需的電源形式,例如交流變成直流、高電壓變為低電壓、低頻變為高頻等,轉義字符也是,它是將字符轉換成另一種操作形式,或是將無法一起使用的字符進行組合,

注意:轉義符(單個反斜線)“\”只針對后面緊跟著的單個字符進行操作,

C#中的常用轉義字符如表3.4所示,

 

 

 

實體03:輸出Windows系統目錄

創建一個控制臺應用程式,通過使用轉義字符在控制臺視窗中輸出Windows的系統目錄,代碼如下:

 

 

 程式的運行結果如圖3.11所示,

 

 

 

拓展訓練:

一、在控制臺視窗中輸出Visual Studio2017開發環境的安裝目錄,

二、使用轉義字符輸出帶特殊效果的內容,效果如圖3.12所示,

 

 

 多學兩招:實體03中輸出系統目錄時,遇到反斜線時,使用“\\”表示,但是,如果遇到下面的情況:

 

 

 從上面的代碼看到,在有多級目錄時,如果都使用“\\”,會顯得非常麻煩,這時可以用一個@符號來進行多級轉義,代碼修改如下:

 

 

 

3.3.3  變數的初始化

變數的初始化實際上就是給變數賦值,以便在程式中使用,首先,在Visual Studio 2017開發環境中運行下面一段代碼:

 

 

 運行上面代碼時,會出現如圖3.13所示的錯誤提示,

 

 

 

從圖3.13可以看出,如果直接定義一個變數進行使用,會提示使用了未賦值的變數,這說明:在程式中使用變數時,一定要對其進行賦值,也就是初始化,然后才可以使用,那么如何對變數進行初始化呢?

初始化變數有3種方法,分別是單獨初始化變數、宣告時初始化變數、同時初始化多個變數等,下面分別進行講解,

1.單獨初始化變數

在C#中,使用賦值運算子“=”(等號)對變數進行初始化,即將等號右邊的值賦給左邊的變數,

例如,宣告一個變數sum,并初始化其默認值為2017,代碼如下:

 

 

 說明:在對變數進行初始化時,等號右邊也可以是一個已經被賦值的變數,例如,首先宣告兩個變數sum和num,然后將變數sum賦值為2017,最后將變數sum賦值給變數num,代碼如下:

 

 

 

2.宣告時初始化變數

宣告變數時可以對變數進行初始化,即在每個變數名后面加上給變數賦初始值的指令,

例如,宣告一個整型變數mr,并且賦值為927,然后再同時宣告3個字串型變數并初始化,代碼如下:

 

 

 

3.同時初始化多個變數

在對多個同型別的變數賦同一個值時,為了節省代碼的行數,可以同時對多個變數進行初始化,

例如,宣告5個int型別的變數a、b、c、d、e,然后將這5個變數都初始化為0,代碼如下:

 

 

 上面講解了初始化變數的3種方法,現在對本節開始出現錯誤的代碼段進行修改,使其能夠正常運行,修改后的代碼如下:

 

 

 再次運行程式,即可正常運行,

3.3.4  變數的作用域

由于變數被定義后,只是暫時存盤在記憶體中,等程式執行到某一個點后,該變數會被釋放掉,也就是說變數有它的生命周期,因此,變數的作用域是指程式代碼能夠訪問該變數的區域,如果超出該區域,則在編譯時會出現錯誤,在程式中,一般會根據變數的“有效范圍”將變數分為“成員變數”和“區域變數”,

1.成員變數

在類體中定義的變數被稱為成員變數,成員變數在整個類中都有效,類的成員變數又可以分為兩種,即靜態變數和實體變數,

例如,在Test類中宣告實體變數和靜態變數,代碼如下:

 

 

 

其中,x為實體變數,y為靜態變數(也稱類變數),如果在成員變數的型別前面加上關鍵字static,這樣的成員變數稱為靜態變數,靜態變數的有效范圍可以跨類,甚至可達到整個應用程式之內,對于靜態變數,除了能在定義它的類記憶體取,還能直接以“類名.靜態變數”的方式在其他類內使用,

2.區域變數

在類的方法體中定義的變數(定義方法的“{”與“}”之間的區域)稱為區域變數,區域變數只在當前代碼塊中有效,

在類的方法中宣告的變數,包括方法的引數,都屬于區域變數,區域變數只有在當前定義的方法內有效,不能用于類的其他方法中,區域變數的生命周期取決于方法,當方法被呼叫時,C#編譯器為方法中的區域變數分配記憶體空間,當該方法的呼叫結束后,則會釋放方法中區域變數占用的記憶體空間,區域變數也將會銷毀,

變數的有效范圍如圖3.14所示,

 

 

 

實體04:使用變數記錄用戶登錄名

創建一個控制臺應用程式,使用一個區域變數記錄用戶的登錄名,代碼如下:

 

 

 程式運行結果如圖3.15所示

 

 

 

拓展訓練:

一、制作用戶登錄模塊時,使用區域變數記錄登錄用戶和登錄時間(提示:記錄登錄時間時,需要用到DataTime結構,該結構用來獲取日期相關的資訊),

二、使用一個int型別的變數記錄每年京東的年中促銷活動節日名稱(提示:618),運行效果如圖3.16所示,

 

 

3.4  常量

通過對前面知識的學習,我們知道了變數是隨時可以改變值的量,那么,在遇到不允許改變值的情況時,該怎么辦呢?這就是本節將要講解的常量,

3.4.1  常量是什么

常量就是程式運行程序中,值不能改變的量,比如現實生活中的居民身份證號碼、數學運算中的π值等,這些都是不會發生改變的,它們都可以定義為常量,常量可以區分為不同的型別,比如98、368是整型常量,3.14、0.25是實數常量,即浮點型別的常量,m、r是字符常量,

3.4.2  常量的分類

常量主要有兩種,分別是const常量和readonly常量,下面分別對這兩種常量進行講解,

1.const常量

在C#中提到常量,通常指的是const常量,const常量也叫靜態常量,它在編譯時就已經確定了值,const常量的值必須在宣告時就進行初始化,而且之后不可以再進行更改,

例如,宣告一個正確的const常量,同時再宣告一個錯誤的const常量,以便讀者對比參考,代碼如下:

 

 

2. readonly常量

readonly常量是一種特殊的常量,也稱為動態常量,從字面理解上看,readonly常量可以進行動態賦值,但需要注意的是,這里的動態賦值是有條件的,它只能在建構式中進行賦值,例如,下面的代碼:

 

 

 如果要在建構式以外的位置修改readonly常量的值,比如,在Main方法中進行修改,代碼如下:

 

 這時再運行程式,將會出現如圖3.17所示的錯誤提示,

 

 

3. const常量與readonly常量的區別

const常量與readonly常量的主要區別如下:

◆const常量必須在宣告時初始化,而readonly常量則可以延遲到建構式中初始化,

◆ const常量在編譯時就被決議,即將常量的值替換成了初始化的值,而readonly常量的值需要在運行時確定,

◆ const常量可以在類中或者方法體中定義,而readonly常量只能在類中定義,

3.5  運算子

運算子是具有運算功能的符號,根據使用運算元的個數,可以將運算子分為單目運算子、雙目運算子和三目運算子,其中,單目運算子是作用在一個運算元上的運算子,如正號(+)等;雙目運算子是作用在兩個運算元上的運算子,如加法(+)、乘法(*)等;三目運算子是作用在3個運算元上的運算子,C#中唯一的三目運算子就是條件運算子(?:),本節將詳細講解C#中的運算子,

3.5.1  算術運算子

C#中的算術運算子是雙目運算子,主要包括+、-、*、/和%5種,它們分別用于進行加、減、乘、除和模(求余數)運算,C#中算術運算子的功能及使用方式如表3.5所示,

 

 

實體05計算學生成績的分差及平均分

某學員3門課程的成績如下所示:

 

 編程實作兩個功能:計算C#課和SQL課的分數之差;計算3門課的平均分數,代碼如下:

 

 程式運行結果如圖3.18所示,

 

 

拓展訓練:

一、制作一個簡易的加法計算器程式,具體實作時,提示用戶輸入3個整型或浮點型數值,并計算這3個數值的和,

二、使用克萊姆法則求解下面的二元一次方程組,

21.8x+2y=28

7x+ 8y= 62

提示:克萊姆法則求解二元一次方程組的公式如圖3.19所示,

 

 注意:使用除法(/)運算子和求余運算子時,除數不能為0,否則將會出現例外,如圖3.20所示,

 

 

3.5.2  自增自減運算子

使用算術運算子時,如果需要對數值型變數的值進行加1或者減1操作,可以使用下面的代碼:

 

 

針對以上功能,C#中還提供了另外的實作方式:自增和自減運算子,分別用++和--表示,下面分別對它們進行講解,

自增和自減運算子是單目運算子,在使用時有兩種形式,分別是++expr、expr++,或者--expr、expr--,其中,++expr、--expr是前置形式,它表示expr自身先加1或者減1,其運算結果是自身修改后的值,再參與其他運算;而expr++、expr--是后置形式,它也表示自身加1或者減1,但其運算結果是自身未修改的值,也就是說,expr++、expr--是先參加完其他運算,然后再進行自身加1或者減1操作,自增、自減運算子放在不同位置時的運算示意圖如圖3.21所示,

 

 例如,下面代碼演示自增運算子放在變數的不同位置時的運算結果:

 

 注意:自增、自減運算子只能作用于變數,因此,下面的形式是不合法的:

 

 多學兩招:如果程式中不需要使用運算元原來的值,只是需要其自身進行加(減)1,那么建議使用前置自加(減),因為后置自加(減)必須先保存原來的值,而前置自加(減)不需要保存原來的值,

3.5.3  賦值運算子

賦值運算子主要用來為變數等賦值,它是雙目運算子,C#中的賦值運算子分為簡單賦值運算子和復合賦值運算子,下面分別進行講解,

1.簡單賦值運算子

簡單賦值運算子以符號“=”表示,其功能是將右運算元所含的值賦給左運算元,例如:

 

 

2.復合賦值運算子

在程式中對某個物件進行某種操作后,如果要再將操作結果重新賦值給該物件,則可以通過下面的代碼實作:

 

 上面的代碼看起來很煩瑣,在C#中,上面的代碼等價于:

 

 

上面代碼中的+=就是一種復合賦值運算子,復合賦值運算子又稱為帶運算的賦值運算子,它其實是將賦值運算子與其他運算子合并成一個運算子來使用,從而同時實作兩種運算子的效果,

C#提供了很多復合賦值運算子,其說明及運算規則如表3.6所示,

 

 

3.復合賦值運算子的優勢及劣勢

使用復合賦值運算子時,雖然“a+= 1”與“a=a+ 1”兩者的計算結果是相同的,但是在不同的場景下,兩種使用方法都有各自的優勢和劣勢,下面分別介紹,

(1)低精度型別自增

在C#中,整數的默認型別是int型,所以下面的代碼會報錯:

 

 上面的代碼中,在沒有進行強制型別轉換的條件下,a+1的結果是一個int值,無法直接賦給一個byte變數,但是如果使用“+=”實作遞增計算,就不會出現這個問題,代碼如下:

 

 

(2)不規則的多值運算

復合賦值運算子雖然簡潔、強大,但是有些時候是不推薦使用的,例如,下面的代碼:

 

 如果將,上面這行代碼改成復合賦值運算子實作,就會顯得非常煩瑣,代碼如下:

 

 說明:在C#中可以把賦值運算子連在一起使用,如:

 

 

在這個陳述句中,變數x、y. z都得到同樣的值5,但在程式開發中不建議使用這種賦值語法,

3.5.4  關系運算子

關系運算子是雙目運算子,它用于在程式中的變數之間以及其他型別的物件之間的比較,它回傳一個代表運算結果的布林值,當運算子對應的關系成立時,運算結果為true,否則為false, 關系運算子通常用在條件陳述句中來作為判斷的依據,C#中的關系運算子共有6個,其使用及說明如表3.7所示,

 

 

說明:不等于運算子(!=)是與等于運算子相反的運算子,它與!(a==b) 是等效的,

實體06:使用關系運算子比較大小關系

創建一個控制臺應用程式,宣告3個int 型別的變數,并分別對它們進行初始化,然后分別使用C#中的各種關系運算子對它們的大小關系進行比較,代碼如下:

 

 

代碼注解:

(1)第6行代碼使用“Console.WriteLine);" 輸出了一個空行,起到換行的作用,

(2)第7行到第12行代碼主要演示6種關系運算子的使用方法,

程式運行結果如圖3.22所示,

 

 

拓展訓練:

一、有兩個鏈球,它們分別重5kg和8kg,請使用程式輸出其中更重的一個鏈球,

二、國家推出二胎政策,A家庭陸續生了2個孩子,B家庭陸續生了4個孩子,哪個家庭屬于超生家庭?

3.5.5  邏輯運算子

假定某面包店,在每周二的下午7點至8點和每周六的下午5點至6點,對生日蛋糕商品進行折扣讓利活動,那么想參加折扣活動的顧客,就要在時間上滿足這樣的條件(周二并且7:00 PM~8:00 PM) 或者(周六并且5:00 PM~6:00 PM),這里就用到了邏輯關系,在C#中也提供了這樣的邏輯運算子來進行邏輯運算,

邏輯運算子是對真和假這兩種布林值進行運算,運算后的結果仍是一個布林值,在C#中,邏輯運算子主要包括& (&&) (邏輯與)、| (||) (邏輯或)、! (邏輯非),在邏輯運算子中,除了“!”是單目運算子之外,其他都是雙目運算子,表3.8列出了邏輯運算子的用法和說明,

 

 使用邏輯運算子進行邏輯運算時,其運算結果如表3.9所示,

 

 

多學兩招:邏輯運算子“&&”與“&”都表示“邏輯與”,那么它們之間的區別在哪里呢?從表3.9可以看出,當兩個運算式都為true時,邏輯與的結果才會是true,使用“&”會判斷兩個運算式; 而“&&”則是針對bool型別的資料進行判斷,當第一個運算式為false時,則不去判斷第二個運算式,直接輸出結果從而節省計算機判斷的次數,通常將這種在邏輯運算式中從左端的運算式可推斷出整個運算式的值稱為“短路”,而那些始終執行邏輯運算子兩邊的運算式稱為“非短路”,“&&”屬于“短路”運算子,而“&”則屬于“非短路”運算子,“||”與“|”的區別跟“&&”與“&”的區別類似,

實體07參加面包店的打折活動

創建一個控制臺應用程式,使用代碼實作前面描述的面包店打折活動的場景,代碼如下:

 

 

代碼注解:

(1)第9行和第13行代碼使用了if...else條件判斷陳述句,主要用來判斷是否滿足某種條件,該陳述句將在第4章進行詳細講解,這里只需要了解即可,

(2)第9行代碼中對條件進行判斷時,使用了邏輯運算子&&、||和關系運算子==、>=、<=,

程式運行結果如圖3.23和圖3.24所示,

 

 

拓展訓練:

一、在某網站首頁中,可以使用賬戶名、手機號或者電子郵箱進行登錄,請判斷某用戶是否可以登錄,(已知服務器中有如下記錄,賬戶名:123,手機號: 123****8910, 電子郵箱: [email protected] )

二、有兩名男性應聘者:一位25歲,一位32歲,該公司招聘資訊中有一個要求,即男性應聘者的年齡在23~30歲之間,判斷這兩名應聘者是否滿足這個要求,

3.5.6  位運算子

位運算子的運算元型別是整型,可以是有符號的也可以是無符號的,C#中的位運算子有位與、位或、位異或和取反運算子,其中位與、位或、位異或運算子為雙目運算子,取反運算子為單目運算子,位運算是完全針對位方面的操作,因此,它在實際使用時,需要先將要執行運算的資料轉換為二進制,然后才能進行運算,

說明:整型資料在記憶體中以二進制的形式表示, 如整型變數7的32位二進制表示是00000000 00000000 00000000 00000111,其中,左邊最高位是符號位,最高位是0則表示正數,若為1則表示負數,負數采用補碼表示,如-8的32位二進制表示為11111111 11111111 11111111 11111000

1.“位與”運算

“位與”運算的運算子為“&”,“位與”運算的運演算法則是:如果兩個整型資料a和b對應位都是1,則結果位才是1,否則為0,如果兩個運算元的精度不同,則結果的精度與精度高的運算元相同,如圖3.25所示,

 

 

2.“位或”運算

“按位或”運算的運算子為“|”,“位或”運算的運演算法則是:如果兩個運算元對應位都是0,則結果位才是0,否則為1,如果兩個運算元的精度不同,則結果的精度與精度高的運算元相同,如圖3.26所示,

3. “位異或” 運算

“位異或”運算的運算子是“∧”,“位異或”運算的運演算法則是:當兩個運算元的二進制表示相同(同時為0或同時為1)時,結果為0,否則為1,若兩個運算元的精度不同,則結果數的精度與精度高的運算元相同,如圖3.27所示,

 

 

4.“取反”運算

“取反”運算也稱“按位非”運算,運算子為“~”,“取反”運算就是將運算元對應二進制中的1修改為0,0修改為1,如圖3.28所示,

說明:圖3.28 中,123取反后得到的結果中,由于前面符號位為1,因此最高位以負數計算,即-27+22,所以結果為-124,

在C#中使用Console.WriteLine輸出圖3.25~圖3.28的運算結果,主要代碼如下:

 

 運算結果如圖3.29所示,

 

 

3.5.7  移位運算子

C#中的移位運算子有兩個,分別是左移位<<和右移位>>,這兩個運算子都是雙目運算子,它們主要用來對整數型別資料進行移位操作,移位運算子的右運算元不可以是負數,并且要小于左運算元的位數,下面分別對左移位<<和右移位>>進行講解,

1.左移位運算子<<

左移位運算子<<是將-一個二進制運算元向左移動指定的位數,左邊(高位端)溢位的位被丟棄, 右邊(低位端)的空位用0補充,左移位運算相當于乘以2的n次冪,

例如,int型別資料48對應的二進制數為00110000,將其左移1位,根據左移位運算子的運算規則可以得出(00110000<<1)=01100000所以轉換為十進制數就是96 (48*2); 將其左移2位,根據左移位運算子的運算規則可以得出(01100000<<2)=11000000所以轉換為十進制數就是192 (48*22), 其執行程序如圖3.30所示,

 

 

2.右移位運算子>>

右移位運算子>>是將一個二進制運算元向右移動指定的位數,右邊( 低位端)溢位的位被丟棄,而在填充左邊(高位端)的空位時,如果最高位是0 (表示正數),左側空位填入0;如果最高位是1(表示負數),左側空位填入1,右移位運算相當于除以2的n次冪,

正數48右移1位的運算程序如圖3.31所示,

 

 負數-80右移2位的運算程序如圖3.32所示,

 

 多學兩招:由于移位運算的速度很快,在程式中遇到運算式乘以或除以2的n次冪的情況時,一般采用移位運算來代替,

3.5.8條件運算子

條件運算子用“?:” 表示,它是C#中唯一的三目運算子,該運算子需要3個運算元,形式如下:

 

 其中,運算式1是一個布林值,可以為真或假,如果運算式1為真,回傳運算式2的運算結果,如果運算式1為假,則回傳運算式3的運算結果,例如:

 

 多學兩招:條件運算子相當于一個if陳述句,因此,上面的第 2行代碼可以修改如下:

 

 

關于if陳述句的詳細講解,請參見后面章節

另外,條件運算子的結合性是從右向左的,即:從右向左運算,例如: 

 

 等價于:

 

 

實體08:判斷人的年齡所處階段

創建一個控制臺應用程式,使用條件運算子判斷輸入年齡所處的階段,并輸出相應的提示資訊,代碼如下;

 

 

代碼注解:

(1)第4行代碼中,Int32.Parse方法用來將用戶的輸入轉換為int型別,存盤到int型別變數中,

(2)第6行代碼是定義了一個string型別的變數,記錄條件運算式的回傳結果

程式運行結果如圖3.33所示,

 

 

拓展訓練:

一、通過使用條件運算子判斷輸入的年份是不是閏年,

二、使用邏輯運算子判斷用戶輸入的用戶名和密碼是否同時滿足條件,如果是,輸出“登錄成功”,否則,輸出“登錄失敗”,提示:默認的用戶名和密碼分別是mr和mrsoft,另外,該程式實作時需要用到關系運算子“==”和條件運算子“?:”,登錄成功和失敗的效果分別如圖3.34和圖3.35所示,

 

 

3.6  資料型別轉換

型別轉換是將一個值從一種資料型別更改為另一種資料型別的程序,例如,可以將string型別資料“457”轉換為一個int型別,也可以將任意型別的資料轉換為string型別,

資料型別轉換有兩種方式,即隱式轉換與顯式轉換,如果從低精度資料型別向高精度資料型別轉換,則永遠不會溢位,并且總是成功的;而把高精度資料型別向低精度資料型別轉換,則必然會有資訊丟失,甚至有可能失敗,這種轉換規則就像如圖3.36所示的兩個場景,高精度相當于一個大水杯,低精度相當于一個小水杯,大水杯可以輕松裝下小水杯中所有的水,但小水杯無法裝下大水杯中所有的水,裝不下的部分必然會溢位,

 

 

3.6.1  隱式型別轉換

隱式型別轉換就是不需要宣告就能進行的轉換,進行隱式型別轉換時,編譯器不需要進行檢查就能自動進行轉換,下列基本資料型別會涉及資料轉換(不包括邏輯型別),這些型別按精度從“低”到“高”排列的順序為byte < short < int < long < float < double,可對照圖3.37,其中char型別比較特殊,它可以與部分int型數字兼容,且不會發生精度變化,

 

 例如,將int型別的值隱式轉換成long型別,代碼如下:

 

 

3.6.2  顯式型別轉換

有很多場合不能隱式地進行型別轉換,否則編譯器會出現錯誤,例如,下面的型別在進行隱式轉換時會出現錯誤:

◆int型別轉換為short型別——會丟失資料

◆int型別轉換為uint型別——會丟失資料

◆float型別轉換為int型別——會丟失小數點后面的所有資料

◆double型別轉換為int型別——會丟失小數點后面的所有資料

◆數值型別轉換為char型別——會丟失資料"

◆decimal型別轉換為其他數值型別——decimal型別的內部結構不同于整數和浮點數

如果遇到上面型別之間的轉換,就需要用到C#中的顯式型別轉換,顯式型別轉換也稱為強制型別轉換,它需要在代碼中明確地宣告要轉換的型別,如果要把高精度的變數轉換為低精度的變數,就需要使用顯式型別轉換,

顯式型別轉換的一般形式為:

其功能是把運算式的運算結果強制轉換成型別說明符所表示的型別,

例如,下面的代碼用來把x轉換為float型別:

 

 

 通過顯式型別轉換,就可以解決高精度資料向低精度轉換的問題,例如,將double型別的值4.5賦值給int型別變數時,可以使用下面的代碼實作:

3.6.3  使用Convert類進行轉換

在3.6.2節中講解了可以使用“(型別說明符)運算式”進行顯式型別轉換,使用這種方式實作將long型資料轉換成int型資料:

 

 按照代碼的本意,i的值應該是3000000000,但在運行這兩行代碼時,卻發現i的值是-1294967296,這主要是由于int型別的最大值為2147483647,很明顯,3000000000要比2147483647大,所以在使用上面代碼進行顯式型別轉換時,出現了與預期不符的結果,但是程式并沒有報告錯誤,如果在實際開發中遇到這種情況,可能會引起大的BUG,那么,在遇到這種錯誤時,有沒有一種方式能夠向開發人員報告錯誤呢?答案是肯定的,C#中提供了Convert類,該類也可以進行顯式型別轉換,它的主要作用是將一個基本資料型別轉換為另一個基本資料型別,Convert類的常用方法及說明如表3.10所示,

 

 例如,定義一個double型別的變數x,并賦值為198.99,使用Convert類將其顯式轉換為int型別,代碼如下:

 

 下面使用Convert類的ToInt32對本節開始的兩行代碼進行修改,修改后的代碼如下:

 

 再次運行這兩行代碼,則會出現如圖3.38所示的錯誤提示,

 

 

這樣,開發人員即可根據圖3.38中的錯誤提示對程式代碼進行修改,避免程式出現邏輯錯誤,

3.7  運算子優先級與結合性

C#中的運算式是使用運算子連接起來的符合C#規范的式子,運算子的優先級決定了運算式中運算執行的先后順序,運算子優先級其實相當于進銷存的業務流程,如進貨、入庫、銷售、出庫,只能按這個步驟進行操作,運算子的優先級也是這樣的,它是按照一定的先后順序進行計算的,C#中的運算子優先級由高到低的順序依次是:

(1)自增、自減運算子,

(2)算術運算子,

(3)移位運算子,

(4)關系運算子,

(5)邏輯運算子,

(6)條件運算子,

(7)賦值運算子,

如果兩個運算子具有相同的優先級,則會根據其結合性確定是從左至右運算,還是從右至左運算,表3.11列出了運算子從高到低的優先級順序及結合性,

 

 說明:表3.11中的“←”表示從右至左,“→”表示從左至右,從表3.11中可以看出,C#中的運算子中,只有單目、條件和賦值運算子的結合性為從右至左,其他運算子的結合性都是從左至右,所以,下面的代碼是等效的:

 

 

3.8  難點解答

3.8.1  使用賦值運算子時的注意事項

使用賦值運算子時,其左運算元不能是常量,但所有運算式都可以作為賦值運算子的右運算元,例如,下面的3種賦值形式是錯誤的:

 

 另外,在使用賦值運算子時,右運算元的型別必須可以隱式轉換為左運算元的型別,否則,將會出現錯誤提示,例如,下面的代碼:

 

 運行上面的代碼,將會出現如圖3.39所示的錯誤提示,

 

 

3.8.2  條件運算子不能單獨作為陳述句

在C#中使用條件運算子對兩個整型變數a和b進行運算,如果a>b,則得到a的值,否則,得到b的值,代碼如下:

 

 運行程式,出現如圖3.40所示的錯誤提示,

 

 分析錯誤原因,“?:”是C#中的三目運算子,而三目運算子是不能單獨構成陳述句的,所以上面的代碼才會出現錯誤,要修改該程式,只需要使用一個變數記錄三目運算子運算之后的結果即可,改正后的代碼如下:

 

 

3.9  小結

本章介紹的是C#的基礎語法,其中需要重點掌握的是C#中的基本資料型別、變數與常量以及運算子三大知識點,另外,要對資料型別之間的轉換有一定的了解,在使用變數時,需要注意的是變數的有效范圍,否則在使用時會出現編譯錯誤或浪費記憶體資源,此外,各種運算子也是本章的重點,正確使用這些運算子,才能得到預期的結果,

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/279764.html

標籤:C#

上一篇:c# ef ,DAO分層到底應該怎么寫? 涉及到導航屬性

下一篇:.NET Core 呼叫百度 PaddleOCR 識別圖文

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more