2013-10-24 56 views
1

我是一個在克里斯的書中徘徊的新手有一個問題。需要澄清Chris Rolliston XE2基礎中的按位運算符Page 65

在第65頁最後一段提到使用適當的設置類型,因爲它們提供了強大的輸入。

有人可以解釋這是什麼意思,因爲下面的例子看起來像我通常會做的事情,我試圖使用更好的做法。

+1

你能提供更多細節嗎?我猜測Chris正在將Delphi風格的整數類型(比如窗口風格,或者Win32的進程創建標誌)與C風格按位AND和OR運算符進行比較。但如果我們不需要猜測,那會更好。你知道打字有多強嗎?你有沒有用網絡搜索來查看它? –

+2

我們沒有克里斯的書第65頁在我們面前。克里斯在這裏並且可以解釋這很棒,但總的來說,這是一個可怕的問題。如何詢問實際的語法而不是頁面引用? –

回答

1

您引用的代碼是使用常量與枚舉類型的比較,並且演示了這兩種方法都可以正常工作。

const 
    mcFirst = 1; 
    ... 

VS

type 
    TMyEnum = (meFirst, ... 

克里斯建議使用枚舉類型,而不是常量,採取強有力的打字優勢。

+0

也許你可以解釋強烈的打字問題 –

+0

啊,在閱讀它幾個小時後我得到了這個。我的理解是枚舉類型可以通過對枚舉類型進行單個編輯來實現徹底的更改。謝謝,Tim C. –

9

正如我不能侵犯我自己的版權,完整的部分:

有在Delphi的RTL幾個地方 - 在Windows API和很多很多的地方 - 其中「位掩碼」上一個整數而不是正確的設置類型。例如,System.SysUtils單元聲明函數FileGetAttr,該函數以單個整數的形式返回文件的屬性(只讀,隱藏,系統等)。爲了測試單個屬性,則必須使用所謂的「按位」運營商,尤其是and

uses 
    System.SysUtils; 

var 
    Attr: Integer; 
begin 
    Attr := FileGetAttr('C:\Stuff\Some file.txt'); 
    if Attr and faReadOnly <> 0 then 
    WriteLn('Read only'); 
    if Attr and faHidden <> 0 then 
    WriteLn('Hidden'); 
    if Attr and faSysFile <> 0 then 
    WriteLn('System'); 
end. 

對於這項工作,在faXXX常量的定義,使得第一具有的值爲1,第二個值爲2,第三個值爲4,第四個爲8,依此類推。要將值添加到「設置」現有手動,使用or,並刪除值,使用and not

procedure AddHiddenAttr(const AFileName: string); 
begin 
    FileSetAttr(AFileName, FileGetAttr(AFileName) or faHidden); 
end; 

procedure RemoveHiddenAttr(const AFileName: string); 
begin 
    FileSetAttr(AFileName, FileGetAttr(AFileName) and not faHidden); 
end; 

一般情況下,你應該使用正確的集類型,你可以,因爲他們提供了強有力的打字和更好的可讀性。但是,下面的代碼演示了一個事實,即在發動機罩下,「真正的」組和他們的手工,C風格的等價歸結爲同一件事:

const 
    mcFirst = 1; 
    mcSecond = 2; 
    mcThird = 4; 
    mcFourth = 8; 

type 
    TMyEnum = (meFirst, meSecond, meThird, meFourth); 
    TMySet = set of TMyEnum; 

var 
    UsingSet: TMySet; 
    UsingConsts: LongWord; 
begin 
    //direct assignment 
    UsingSet := [meSecond, meThird]; 
    UsingConsts := mcSecond or mcThird; 
    WriteLn('Equal? ', Byte(UsingSet) = UsingConsts); 
    //subtraction 
    Exclude(UsingSet, meSecond); 
    UsingConsts := UsingConsts and not mcSecond; 
    WriteLn('Equal? ', Byte(UsingSet) = UsingConsts); 
    //addition 
    Include(UsingSet, meFourth); 
    UsingConsts := UsingConsts or mcFourth; 
    WriteLn('Equal? ', Byte(UsingSet) = UsingConsts); 
    //membership test 
    if meThird in UsingSet then WriteLn('meThird is in'); 
    if UsingConsts and mcThird <> 0 then WriteLn('mcThird is in'); 
end. 

運行程序,你會發現每種情況下輸出TRUE

因此...剛剛通過枚舉和設置類型,我現在覆蓋弱類型的等價物。這個位最後的含義是,如果你習慣以C方式定義簡單的位掩碼,那麼沒有理由避免在Delphi中使用正確的集合類型,因爲它們歸結爲同一事物。因此,當你獲得強有力的打字時,你不會失去任何效率 - 在這種情況下,「強打字」本身就意味着你不會意外地分配或測試用於不同類型集合的元素。

+0

看,我知道你會回來的!您可能想使用報價格式而不是斜體。 –

+0

@DavidHeffernan - 我最初使用了引號格式,但當第一段中的最後'和'剛剛碰到前面的文本(引號格式使用灰色背景,如代碼格式)時,它就變爲斜體。 –

+0

我認爲看起來好多了。發現代碼並不難。在我看來,它更好地描述了你最後的解釋性段落中的引用。 –