procedure TForm1.Button1Click(Sender: TObject);
var
  FileRec:TSearchrec;
  s:String;
begin
  s:='E:\FWGL\data.mdb';
  findfirst(S,faAnyfile,FileRec);
  ShowMessage(S+'的属性值为:'+inttostr(FileRec.Attr));   //显示32
  ShowMessage('常量 aDirectory 的值为:'+inttostr(faDirectory));   //16
  if ((FileRec.Attr and faDirectory) = 0) then
    ShowMessage('按位与值:'+inttostr(FileRec.Attr and faDirectory)+' '+S+' 是一个文件.')
  else
    showMessage('按位与值:'+inttostr(FileRec.Attr and faDirectory)+' '+s+' 是一个文件夹');
end;这里的 FileRec.Attr 的值为何是 32? 如果加了个只读,那就是33  
为何 32 and 16 = 0 就能判断其是否是一个文件而不是文件夹?
它们之前有什么关系? 怎么运算的?

解决方案 »

  1.   

    faDirectory 不就是文件夹吗32 xor 1 = 33
      

  2.   


    这个说的对,换成二进制就看明白了。
    我实话,我记不太清了,好像是这样的:文件的属性是一串不连续的整数(每一个属性都不为是任意n个属性之和)。如果有两个属性,就表示为这两个属性的和,有3个属性,就表示为3个属性之和,也是一个整数。看一下定义:
    TSearchRec = record
      private
        function GetTimeStamp: TDateTime;
      public
    {$IFDEF MSWINDOWS}
        Time: Integer platform deprecated;
    {$ENDIF MSWINDOWS}
    {$IFDEF POSIX}
        Time: time_t platform;
    {$ENDIF POSIX}
        Size: Int64;
        Attr: Integer;//看这里,看到了吗,就是一个整数。
        Name: TFileName;
        ExcludeAttr: Integer;再看一段{ File attribute constants }  faInvalid     = -1;
      faReadOnly    = $00000001;//这不就是1吗,32+1不就是33吗?
      faHidden      = $00000002 platform; // 如果加上这个属性,就是32+2啊,就是34.
      faSysFile     = $00000004 platform; // on POSIX system files are not regular files and not directories
      faVolumeID    = $00000008 platform deprecated;  // not used in Win32
      faDirectory   = $00000010;//这不就是16吗?
      faArchive     = $00000020 platform;//这不就是32吗?
      faNormal      = $00000080;
      faTemporary   = $00000100 platform;
      faSymLink     = $00000400 platform; // Available on POSIX and Vista and above
      faCompressed  = $00000800 platform;
      faEncrypted   = $00004000 platform;
      faVirtual     = $00010000 platform;
      faAnyFile     = $000001FF;其实这个方法很常用啊,可能你没有用过低级语言吧。
    给你举个例子你就知道这样定义的好处了。
    假如电梯程序(3层)中有3个指示灯a、b、c,分别表示:电梯中1楼呼叫、2楼呼叫、3楼呼叫。
    那么,a、b同时亮起,就是说明1、2楼都有呼叫。我要来处理类似的所有事件,我只需要3个字节就可以来区分了。000、001、010、011、100、101、110、111。按照位置,1楼呼叫、2楼呼叫、3楼呼叫的3个处理,只需要按照位置and一下,就可以了。把传递过来的数字,假设为i,那么:
    1楼呼叫:i and 001;//就是i and 1,由此进入处理程序。
    2楼呼叫:i and 010;//i and 2……
    3楼呼叫:i and 100;//i and 4……
    这样就可以判断了。
    跟文件的属性一样,都是1、2、4、7……一串不连续的整数可以表示任意的多选。
    这种方法很常用——在很久以前
      

  3.   

    LZ先要解决,与运算(即and)是什么?是怎么样进行运算的?
    可以看帮助或者看源码知道各个属性值是多少,注意他们每个值都是不同的
    然后把它转换成2进制,2个数进行与运算,结果就出来了比如faDirectory用2进制表示是0001 0000
    任何一个数和它进行and运算,只有第4位为1时,结果才会不等于0
    而所有这些属性值当中只有他自己是所以...
      

  4.   

    kaikai_kk说的真明白,呵呵。
    刚跑到大富翁上回来,顺便说一下:这种运算方法有时候被称为“取位”,就是取得某一位的开关。8个选项以内的复选,经常采用这种方式。(其实现在就是16位也无所谓)plc中的程序、汇编中的经常用到这种方式,选项少的话,这种方式非常灵活,占用资源少。可以参见一些霓虹灯啊、喷泉控制等等经典的入门程序,移位、取位等等都是基本的方法。
    不过参考其他语言的时候要注意高位优先还是低位优先,plc和汇编中很多是高位优先的,delphi等语言表述的时候往往是低位优先。