从像(char *)&(struct)这样的结构传递参数来读取函数

时间:2015-02-19 18:09:39

标签: c pointers struct

阅读K& R书籍ANSI,并进入无法理解的源代码,它是关于readdir函数。那段代码很大。所以它就像:

typedef struct {
  long ino;       
  char name[NAME_MAX+1];
} Dirent;

并且在readdir函数中我们有:

Dirent *dirbuf;

现在,有:

            ignore    what is this     what is dis      what is dis
while (read(dp->fd, (char *) &dirbuf , sizeof(dirbuf) ) == sizeof( dirbuf) )

“什么是dis,这是什么”是问题的一部分,请解释一下它的作用。我一直在玩它以检查(char *)是否在结构中搜索char *并在查找时将IT带到read函数,但它不是?还可以在检查时解释该语句是否与sizeof( dirbuf)相等,以及为什么第三个参数不是sizeof(dirbuf->name)?在这里我尝试了:

struct lele{
    int dig;
    char name[20];

};

int main(void)
{
    struct lele p;

    scanf("%d%s", (int *) &p, (char *) &p);
    printf("name: %s ,,, dig : %d\n", p.name, p.dig);
    return 0;
}
INPUT: 5 , green

OUTPUT: name: n ,,, dig : 1701147239

还可以解释和输出吗? 编辑主流问题是为什么第二个参数不是dirbuf->namereaddir的代码:

#include <sys/dir.h> /* local directory structure */
/* readdir: read directory entries in sequence */
Dirent *readdir(DIR *dp)
{
     struct direct dirbuf; /* local directory structure */
     static Dirent d; /* return: portable structure */
     while (read(dp->fd, (char *) &dirbuf, sizeof(dirbuf))
        == sizeof(dirbuf)) {
      if (dirbuf.d_ino == 0) /* slot not in use */
         continue;
      d.ino = dirbuf.d_ino;
      strncpy(d.name, dirbuf.d_name, DIRSIZ);
      d.name[DIRSIZ] = '\0'; /* ensure termination */
      return &d;
}
return NULL;
}

1 个答案:

答案 0 :(得分:1)

在昔日(或K&amp; R)时代,可以使用open()read()close()来阅读UFS(Unix文件系统)上的目录。此外,文件名限制为14个字符,inode编号限制为2个字节(unsigned short)。一个由16字节条目组成的目录:

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| inode | . | \0| \0| \0| \0| \0| \0| \0| \0| \0| \0| \0| \0| \0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| inode | . | . | \0| \0| \0| \0| \0| \0| \0| \0| \0| \0| \0| \0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| inode | f | i | l | e | n | a | m | e | \0| \0| \0| \0| \0| \0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| inode | l | o | n | g | e | r | f | i | l | e | n | a | m | e |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 00000 | d | e | l | e | t | e | d | - | f | i | l | e | \0| \0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| inode | o | t | h | e | r | n | a | m | e | \0| \0| \0| \0| \0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

请注意,14个字符的名称是最大值,但这些名称不是以null结尾的。删除的条目的inode编号为零,但名称未被删除。空填充符合strncpy()的作用(虽然不清楚strncpy()实际上是用它来做的。)

更现代的文件系统允许可变长度的名称,并且通过仅为名称分配必要的空间来避免浪费空间,并且它们使用大的inode编号。

问题中显示的代码是:

while (read(dp->fd, (char *)&dirbuf, sizeof(dirbuf)) == sizeof(dirbuf))

这看起来像第一版;在那些日子里,没有void *char *是通用指针。这将执行read()函数调用,将dirbuf变量视为缓冲区。 sizeof(dirbuf)以字节为单位给出变量的大小。因此,这会将固定数量的字节读入变量。 read()系统调用返回它读取的字节数;如果那不是请求的数量,则存在一个问题 - 可能是EOF(用零表示),或者可能是-1(文件描述符的问题),或者可能是一个小于请求大小的数字(可能表示腐败)文件系统)。因此,总的来说,循环将目录条目读入结构变量dirbuf

我不相信结构中显示的大小(long是4个字节,并且没有空填充)。我必须看看他们要做的事情。