2012-06-20 53 views
1

以下行应该测试当前文件是否是一个目录或不是:混淆为位操作&

if ((stbuf.st_mode & S_IFMT) == S_IFDIR) 
     //file is a directory. 

其中stbuf是被定义为类型

struct stat   /* inode information returned by stat */ 
{ 
     dev_t st_dev;  /* device of inode */ 
     ino_t st_ino;  /* inode number */ 
     short st_mode; /* mode bits */ 
     short st_nlink; /* number of links to file */ 
     short st_uid;  /* owners user id */ 
     short st_gid;  /* owners group id */ 
     dev_t st_rdev; /* for special files */ 
     off_t st_size; /* file size in characters */ 
     time_t st_atime; /* time last accessed */ 
     time_t st_mtime; /* time last modified */ 
     time_t st_ctime; /* time originally created */ 
}; 

S_IFMTS_IFDIR

#define S_IFMT 0160000 /* type of file: */ 
#define S_IFDIR 0040000 /* directory */ 

我不明白ho上面给出的陈述会起作用吗?请任何人都可以解释它背后的逻辑。
谢谢。

回答

2

对于来自源和掩码的每对对应位,当且仅当两个位都设置为1时,逻辑AND操作才会给出位(1)。这表示掩码中未打开的所有位都是归零。假设你有一个单字节的位abcdefgh,其中每个字母都是一位,所以要么是0要么是1。 00111000,将两者结合得到00cde000。因此,使用这个掩码,你“切出”了这些位的一个子字符串。通常,掩码只设置一个位,在这种情况下,您将测试一个位。在你的例子中,掩码是S_IFMT。现在,您可以在3位空间中扫描一些值,掩码保持不变,如00101000,00011000或任何在由掩码分隔的空间内都有1位的任何值(这就是您示例中的S_IFDIR) ),并且你可以与之比较。因此,如果明白的话,整个操作意味着“取一个变量位的子串并检查它是否是预定义的值之一”。这一切都是为了空间效率而完成的,如果它不重要,设计人员可能会为模场定义一个单独的变量。

+0

感谢您的回答......我明白了..... – mohit

3

它基本上说,如果你把stbuf.st_mode的所有位,并排列在 位S_IFMT。您将生成第三行,即AND操作的结果。对于AND操作,请参见以下truth table,输出仅为1如果均为输入为1

input1| input2| output 
------+-------+------- 
    0 | 0 | 0 
    0 | 1 | 0 
    1 | 0 | 0 
    1 | 1 | 1 

对于每一个相应的位位置,把0号码下方,除非在给定位置的对应位的两个1,在这种情况下,您记录1

也许这视觉形象会有所帮助:

st_mode | 0100 0000 0000 0000 0000 0000 0000 0000 
S_IFMT | 1110 0000 0000 0000 0000 0000 0000 0000 
bitwise & |=========================================== 
result | 0100 0000 0000 0000 0000 0000 0000 0000 

与一个S_IFDIR比较由此产生的位模式。如果他们平等,你有一个目录。

也许这个SO问题Using Struct Stat()也会有所帮助。最后,stat(3) man page除了这个结构的所有细节外,还有一些示例代码。

+0

@sixlettervariables哇..感谢编辑,这是真棒。我第一次甚至没有认出我的答案:-) ..你打败了我(我正在做一个小例子)。真的改善了答案。 – Levon

+0

我打算用一段ASCII艺术作答,但你已经解释得很清楚了。 – user7116

+0

@sletterlettervariables再次感谢您,我希望您的照片和我的文字结合起来对OP(以及其他任何碰到此问题的人)有所帮助 – Levon

2

按位AND正在获取与特定设置S_IFDIR有关的位。

如果结果是S_IFDIR那么设置该标志。 0160000是八进制数,代表整数的前三位。 0040000是第二位,所以它们重叠。