tft每日頭條

 > 科技

 > delphi字符型數組

delphi字符型數組

科技 更新时间:2024-09-03 05:20:40

delphi字符型數組(Delphi基礎教程圖文版之字符串詳解)1

上午在整理多線程的文章,沒注意時間今天發晚了,最近争取日更!!

Delphi中的字符一直處于懵懵懂懂的狀态,不同于我接觸到的其它編程語言在Delphi中居然有好幾種字符串,今天好好研究一番!!

Delphi中字符串的操作很簡單,但幕後情況卻相當複雜。Pascal傳統的字符串操作方法與Windows不同,Windows吸取了C語言的字符串操作方法。

32位Delphi中增加了長字符串類型,該類型功能強大,是Delphi缺省的字符串類型。

傳統的字符串類型是一個字符序列,序列的頭部是一個長度字節,指示當前字符串的長度。由于隻用一個字節來表示字符串的長度,所以字符串不能超過255個字符。

這一長度限制為字符串操作帶來不便,因為每個字符串必須定長(确省最大值為255),當然你也可以聲明更短的字符串以節約存儲空間。 為克服傳統Pascal字符串的局限性,32位Delphi增加了對長字符串的支持。這樣共有三種字符串類型:

ShortString

短字符串類型也就是前面所述的傳統Pascal字符串類型。短字符串中的每個字符都屬于 AnsiChar類型(标準字符類型)

var S: ShortString; { 255個字符長度,256個字節} S1: String[255]; { S1和S的字符類型一樣} Len: Integer; begin S := 'Hello'; Len := Ord(S[0]); { Len現在包含S的長度為5,Ord函數可以把一個字符類型轉換為整數類型} Len := SizeOf(S); { Len現在包含的是ShortString類型的大小,為256字節} end;

以上例子通過S[0]可以獲得S的字符串長度,當然也可以用Length函數來确定一個短字符串的長度。

可以通過數組的下标來訪問ShortString中的一個特定位置的字符,具體使用參看下面例子和注釋說明:

var S: string[8]; i: Integer; begin S := 'a_pretty_darn_long_string'; { 因為S隻有8個字符大小,因此s的實際存儲的内容為"a_pretty"} i := 10; S[i] := 's'; { 因為S隻有8個字符大小,試圖改寫第10個元素,将會使内存混亂} end;

AnsiString

這種類型也有人稱為長字符串類型(LongString)同時也是Delphi默認的字符串類型,它是一種動态分配的字符串,其大小隻受可用内存的限制。聲明一個長字符串,隻需要用關鍵字String不加大小參數即可。據說使用了更新前拷貝(copy--on-write)技術。恕我才疏學淺沒研究過這個東西。這類字符串長度沒有限制(可以存儲多達20億個字符),其字符類型也是AnsiChar類型。

由于是動态分配的,一次可以随意修改字符串,而不用擔心對其他的影響,也不用擔心越界的問題。String類型沒有0元素,試圖存取String類型的0元素會産生一個編譯錯誤。

之前在萬一老師的博客中看到了以下的代碼不太理解,現在可以完全解釋為什麼我們試圖将一個string類型的變量直接賦值給字符數組時報錯了

//字符串 < > 字符數組,注意這裡說的字符串僅僅是長字符串 var arr: array[0..5] of Char; str: string; begin {可以把字符串常量直接賦給字符數組; 但超界不行} arr := 'Delphi'; ShowMessage(arr); {Delphi} {可以把字符數組直接賦給字符串變量} str := arr; ShowMessage(str); {Delphi} {其實字符串内部也是包含了一個字符數組, 所以能索引訪問, 不過它的索引起始于 1} ShowMessage(str[1]); {D} ShowMessage(arr[0]); {D} {但不能把一個字符串變量賦給字符數組} //arr := str; {錯誤; 這需要用其他手段實現, 譬如複制或移動内存} end;

WideString

長字符串類型與AnsiString 類型相似,隻是它基于WideChar字符類型,WideChar字符為雙字節Unicode字符。

var S: string; { 在Delphi 7中默認string等同于AnsiString} WS: WideString; begin S := '世界你好'; WS := S; ShowMessage(S[1]); { 此時無任何顯示,因為S[1]取出的是‘世’的一半} ShowMessage(WS[1]); { 顯示‘世’} end;

不過WideString和AnsiString的不同主要在三個方面:

  • WideString由WideChar字符組成,而不是由AnsiChar字符組成的,它們跟Unicode字符串兼容。
  • WideString用SysAllocStrLen()API函數進行分配,它們跟OLE的BSTR字符串相兼容。
  • WideString沒有引用計數,所以将一個WideString字符串賦值給另一個WideString字符串時,就需要從内存中的一個位置複制到另一個位置。這使得WideString在速度和内存的利用上不如AnsiString有 效。
Ansi和Unicode

字符編碼:為了區分一個字符到底使用了幾個字節,就不能将字符的編号直接存儲到計算機中,字符編号在存儲之前必須要經過轉換,在讀取時還要再逆向轉換一次,這套轉換方案就叫做字符編碼。它規定了如何将字符的編号存儲到計算機中

字符集:為每個字符分配了唯一的編号。可以将字符集理解成一個很大的表格,它列出了所有字符和二進制的對應關系,計算機顯示文字或者存儲文字,就是一個查表的過程。它定義了字符和二進制的對應關系

ASCII(American Standard Code for Information Interchange,美國信息交換标準碼),它使用7 bits來表示一個字符,總共表示128個字符,後來IBM公司在此基礎上進行了擴展,用8bit來表示一個字符,總共可以表示256個字符

ANSI(American National Standard Institite)美國國家标準學會(美國的一個非營利組織),首先ANSI編碼是一種對ASCII碼的拓展,它不是指的一種特定的編碼,而是不同地區擴展編碼方式的統稱,各個國家和地區所獨立制定的兼容ASCII但互相不兼容的字符編碼,微軟統稱為ANSI編碼

Unicode 是一套字符集,而不是一套字符編碼。它固定使用16 bits(兩個字節)來表示一個字符,共可以表示65536個字符。标準的Unicode稱為UTF-16。後來為了雙字節的Unicode能夠在現存的處理單字節的系統上正确傳輸,出現了UTF-8

個人理解:ANSI是每個國家根據自己的語言在ASCII基礎擴展的一些編碼。為了實現大一統出現了Unicode,而Unicode為了兼容以前的字符出現了雙字節(UTF-16)和單字節(UTF-8)之分

PChar和字符數組

在第二季的視頻中我曾經對端口号做過一次轉換sin_addr.S_addr := inet_addr(PAnsiChar(AnsiString(EditAddr.Text))); 這段代碼,一個将字符串轉成PAnsiChar的一個場景,這是個什麼玩意兒?其實這樣做純粹是為了兼容winAPI中的數據類型

在C和C 中沒有真正的字符串數據類型,都是通過以Null結尾(0)的字符數組來實現的,字符數組沒有長度字節,因此隻能通過結尾的Null标志來作為字符串的字符結束标志。又因為Windows是用C編寫的,很多Windows函數要用到以字符數組作為參數,但Pascal字符串類型不是字符數組,因為為了讓Pascal字符串也能與Windows兼容,就需要一個字符串數組,PChar類型正是符合這種需求,在任何需要字符數組的地方都可用PChar。相應的也有PAnsiChar和PWideChar,分别對應于AnsiChar字符和WideChar字符。

其實最初我也被字符串折騰的不行不行的,所以整理這篇文章

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved