Ada 程式設計/字串
Ada 支援三種不同的字串型別。每種字串型別旨在解決不同的問題。
此外,每種字串型別都針對每種可用的字元型別 (Character, Wide_Character, Wide_Wide_Character) 實現,共計九種組合。
固定長度字串(預定義型別 String)是 字元陣列,因此長度固定。由於 String 是一個 不確定的子型別,因此長度不需要在編譯時知道 - 長度可以在執行時計算出來。在以下示例中,長度是從命令列引數 1 計算出來的
X : String := Ada.Command_Line.Argument (1);
但是,一旦長度被計算出來並且字串被建立,長度將保持不變。嘗試以下程式,它展示了一個典型的錯誤
withAda.Text_IO;withAda.Command_Line;procedureShow_Commandline_1ispackageT_IOrenamesAda.Text_IO;packageCLrenamesAda.Command_Line; X : String := CL.Argument (1);beginT_IO.Put ("Argument 1 = "); T_IO.Put_Line (X); X := CL.Argument (2); T_IO.Put ("Argument 2 = "); T_IO.Put_Line (X);endShow_Commandline_1;
該程式僅當第 1 個和第 2 個引數具有相同的長度時才有效。即使第 2 個引數更短,情況也是如此。沒有對較短字串的自動填充,也沒有對較長字串的自動截斷。
話雖如此,包 Ada.Strings.Fixed 包含一組用於固定長度字串處理的程式和函式,允許填充較短字串和截斷較長字串。
嘗試以下示例以檢視其工作原理
withAda.Text_IO;withAda.Command_Line;withAda.Strings.Fixed;procedureShow_Commandline_2ispackageT_IOrenamesAda.Text_IO;packageCLrenamesAda.Command_Line;packageSrenamesAda.Strings;packageSFrenamesAda.Strings.Fixed; X : String := CL.Argument (1);beginT_IO.Put ("Argument 1 = "); T_IO.Put_Line (X); SF.Move ( Source => CL.Argument (2), Target => X, Drop => S.Right, Justify => S.Left, Pad => S.Space); T_IO.Put ("Argument 2 = "); T_IO.Put_Line (X);endShow_Commandline_2;
當已知和/或限制字串的最大長度時,可以使用有界長度字串。這在資料庫應用程式中很常見,在資料庫應用程式中,只能儲存有限數量的字元。
與固定長度字串一樣,最大長度不需要在編譯時知道 - 它也可以在執行時計算出來 - 如下面的示例所示
withAda.Text_IO;withAda.Command_Line;withAda.Strings.Bounded;procedureShow_Commandline_3ispackageT_IOrenamesAda.Text_IO;packageCLrenamesAda.Command_Line;functionMax_Length ( Value_1 : Integer; Value_2 : Integer)returnIntegerisRetval : Integer;beginifValue_1 > Value_2thenRetval := Value_1;elseRetval := Value_2;endif;returnRetval;endMax_Length;pragmaInline (Max_Length);packageSBisnewAda.Strings.Bounded.Generic_Bounded_Length ( Max => Max_Length ( Value_1 => CL.Argument (1)'Length, Value_2 => CL.Argument (2)'Length)); X : SB.Bounded_String := SB.To_Bounded_String (CL.Argument (1));beginT_IO.Put ("Argument 1 = "); T_IO.Put_Line (SB.To_String (X)); X := SB.To_Bounded_String (CL.Argument (2)); T_IO.Put ("Argument 2 = "); T_IO.Put_Line (SB.To_String (X));endShow_Commandline_3;
您應該知道,有界長度字串有一些明顯的缺點。最明顯的是,每個有界長度字串都是一個不同的型別,這使得轉換它們相當麻煩。此外,有界長度字串型別始終為型別允許的最大字串長度分配記憶體。有界長度字串的記憶體分配等於最大字串“字元”數加上一個實現相關的數字,其中包含字串長度(每個字元可能需要分配超過一個位元組的字元,具體取決於字串的底層字元型別,而長度數字對於 Windows GNAT Ada 編譯器 v3.15p 來說是 4 個位元組,例如)。
最後但並非最不重要的是無界長度字串。事實上:如果您沒有進行嵌入式或資料庫程式設計,這將是您最常使用的字串型別,因為它為您提供了最大的靈活性。
顧名思義,無界長度字串可以儲存幾乎任何長度的字串 - 僅限於 Integer'Last 的值或您的可用堆記憶體。這是因為 Unbounded_String 型別在幕後使用動態記憶體分配,提供較低的效率但最大的靈活性。
withAda.Text_IO;withAda.Command_Line;withAda.Strings.Unbounded;procedureShow_Commandline_4ispackageT_IOrenamesAda.Text_IO;packageCLrenamesAda.Command_Line;packageSUrenamesAda.Strings.Unbounded; X : SU.Unbounded_String := SU.To_Unbounded_String (CL.Argument (1));beginT_IO.Put ("Argument 1 = "); T_IO.Put_Line (SU.To_String (X)); X := SU.To_Unbounded_String (CL.Argument (2)); T_IO.Put ("Argument 2 = "); T_IO.Put_Line (SU.To_String (X));endShow_Commandline_4;
如您所見,無界長度字串示例也是最短的 (不考慮有錯誤的第一個示例) - 這使得使用無界長度字串非常吸引人。
- 2.6: 字串字面量 [註釋]
- 3.6.3: 字串型別 [註釋]
- A.4.3: 固定長度字串處理 [註釋]
- A.4.4: 有界長度字串處理 [註釋]
- A.4.5: 無界長度字串處理 [註釋]
- 2.6: 字串字面量 [註釋]
- 3.6.3: 字串型別 [註釋]
- A.4.3: 固定長度字串處理 [註釋]
- A.4.4: 有界長度字串處理 [註釋]
- A.4.5: 無界長度字串處理 [註釋]
