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

1.3 基本數據類型

C++/CLI與標準C++相同,它們都是一種強類型語言,在程序中用到的變量、表達式和數值等都必須有特定的類型,在編譯程序時編譯器會檢查所有數據類型操作的合法性。

1.3.1 基本數據類型

C++/CLI中的基本數據類型大多與標準C++的基本數據類型相同,并且算術運算也相同。然而,C++/CLI中新定義了兩種整數類型long long和unsigned long long,這兩種數據類型分別占用64位(8字節)空間,可以表示-263~263-1范圍的有符號整數和0~264-1范圍的無符號整數。

當為long long數據類型的變量賦值時,需要在整數數值的后面加上LL或者ll后綴;而當為unsigned long long數據類型的變量賦值時,則需要在整數數值的后面加上ULL或者ull后綴。例如:

        longlong value1 = 123456789LL;
        unsigned long long value2 = 123456789ULL;

在C++/CLI中,每種基本類型都在System命名空間中定義了相應的值類類型??梢詫⒒緮祿愋椭翟趯闹殿愋椭g相互轉換。C++/CLI的基本數據類型及對應的值類類型如表1.3所示。

表1.3 C++/CLI的基本數據類型及對應的值類類型

在默認情況下,char類型被視為singed char,因此其關聯的值類類型為System::SByte。如果編譯選項/J,則char默認為unsigned char,此時關聯的值類類型為System::Byte。

此外System空間中還定義了許多其他類型,如表示字符串的String類型、精確存儲的十進制小數類型Decimal等。Decimal類型適用于要求使用大量有效的整數及小數位數的情況,并且其精度達到28位。Decimal類型并不會消除對舍入的需要,而是盡可能地提高數值精度以將因舍入而導致的錯誤程度降到最低。例如:

        System::Decimal dividend = 1;
        System::Decimal divisor = 3;
        System::Decimal result=dividend/divisor;//result=0.3333333333333333333333333333

1.3.2 裝箱與拆箱

在C++/CLI中,關聯的值類類型為基本類型添加了重要的附加功能。當編譯器需要時,將安排原值與關聯類型之間的自動轉換,其中從原值轉換為關聯類型稱為裝箱(boxing),反之稱為拆箱(unboxing)。根據上下文環境,這些變量將表現為簡單的值或者對象。

由于標準C++基本類型的名稱是C++/CLI程序中值類類型名稱的別名,所以原則上C++/CLI代碼中可用任何一種名稱。例如:

        int count = 10;
        double value = 2.5;

等價于:

        System::Int32 count = 10;
        System::Double value = 2.5;

將基本類型轉換為值類類型是C++/CLI的一個重要特征。在標準C++中基本類型與類類型完全不同,而在C++/CLI中,所有數據都以類類型的形式存儲,包括值類型(存儲在堆棧上)和引用類型(存儲在堆上)。

【例1.5】 裝箱、拆箱的示例。在main函數中分別定義一個值類型和一個引用類型的雙精度浮點數,然后將這兩個數裝箱到Object對象中。代碼如下:

        // Ex1_5.cpp: 主項目文件
        #include "stdafx.h"
        using namespace System;
        int main(array<System::String ^> ^args)
        {
            double result = 3.14159;
            Console::WriteLine(L"result的值為: {0}", result.ToString());
            double^ br = result;
            Console::WriteLine(L"br的值為: {0}", br->ToString());
            result = 2.7;
            *br = 2.17;
            Console::WriteLine(L"result與br的值分別為: {0}, {1}", result, br);
            Object^ obj = br;
            Console::WriteLine(L"obj的值為: {0}", obj);
            Console::WriteLine(L"隱式裝箱:(3).ToString()輸出為:{0}", (3).ToString());
            return 0;
        }

當Ex1_5項目運行后,其執行結果如圖1.9所示。

圖1.9 Ex1_5項目的運行結果

1.3.3 強制類型轉換

在實際編程應用中,經常會遇到類型的相互轉換問題。在CLR環境中,通常使用safe_cast顯式地對類型進行強制轉換。safe_cast的用法與static_cast的用法相同,它們都在關鍵字后通過尖括號對(“< >”)來指定轉換后的新類型,并在括號(“( )”)中指定需要轉換的變量和表達式。其用法如下:

      [cli]::static_cast<type-id>(expression)

當使用static_cast進行類型的轉換時是強制性的,并沒有在任何運行過程進行類型檢查來保證轉換的正確性,所以編程人員需要明白自己所進行的轉換是否合理。但是,若使用safe_cast進行類型轉換時,編譯器將不產生轉換錯誤,而是在運行時進行檢查并判斷轉換是否可行。如果safe_cast在將一種類型轉換為另一種類型時不成功,那么產生錯誤。例如:

        double value1 = 10.5, value2 = 15.5;
        int^ sum = safe_cast<int>(value1 + value2);
        String^ str = safe_cast<String^>(sum);//error C2682:不能從int^轉換到String^類型

另外,在System命名空間中還提供了Convert類用于將一個基本數據類型轉換為另一個基本數據類型。Convert類還支持將任何自定義類型轉換為任何基類型,但是自定義類型必須實現IConvertible接口,以定義將實現類型轉換為每個基類型的方法。Convert類中常用的轉換方法如表1.4所示。

然而,使用Convert類對基本數據類型進行類型轉換時,可能會產生InvalidCastException異常、FormatException異?;騉verflowException異常。其中,如果在不支持特定類型的轉換時將產生InvalidCastException異常;而若由于字符串格式不正確而導致將字符串值轉換為任何其他基類型時,則將產生FormatException異常;如果將大范圍數據類型轉換為小范圍的數據類型,并導致超出小范圍數據類型的表示范圍時,將產生OverflowException異常。

表1.4 Convert類中常用的轉換方法

【例1.6】 類型強制轉換的示例。在main函數中分別調用Convert類中的類型轉換函數將double類型的數轉換為整型、bool類型、字符串類型等。代碼如下:

          // Ex1_6.cpp: 主項目文件
          #include "stdafx.h"
          using namespace System;
          int main(array<System::String ^> ^args)
          {
              Double dNumber = 23.15;
              try {
                Int32  iNumber = Convert::ToInt32(dNumber);
                Console::WriteLine(L"Double類型{0} 轉換為整型:{1}",dNumber,iNumber);
              }
              catch (OverflowException^ e) {
                Console::WriteLine(L"范圍溢出: {0}", e->ToString());
              }
              Boolean bNumber = Convert::ToBoolean(dNumber);
              Console::WriteLine(L"Double類型{0} 轉換為bool類型:{1}",dNumber,bNumber);
              String^ strNumber = Convert::ToString(dNumber);
            Console::WriteLine(L"Double類型{0}轉換為String類型:{1}", dNumber,strNumber);
              try {
                Char chrNumber = Convert::ToChar(strNumber->Substring(0, 1));
                Console::WriteLine(L"將字符串{0} 轉換為Char類型: {1}",
                    strNumber->Substring(0, 1), chrNumber);
              }
              catch (FormatException^ e) {
                Console::WriteLine(L"字符串格式錯誤: {0}", e->ToString());
              }
              return 0;
          }

當Ex1_6項目運行后,其執行結果如圖1.10所示。

圖1.10 Ex1_6項目的運行結果

主站蜘蛛池模板: 葫芦岛市| 临澧县| 松江区| 海南省| 富阳市| 安阳市| 天峻县| 马公市| 孟州市| 闵行区| 合阳县| 阿拉尔市| 巍山| 舒城县| 甘肃省| 河源市| 崇左市| 泰顺县| 凤阳县| 英德市| 碌曲县| 铜山县| 深水埗区| 牙克石市| 凉山| 景泰县| 化隆| 丰宁| 南江县| 寻乌县| 安达市| 长兴县| 和田县| 磐石市| 百色市| 定陶县| 保定市| 台山市| 泰州市| 延川县| 五寨县|