仅使用一个字段创建结构的目的是什么

时间:2015-01-12 08:45:05

标签: c struct

在我公司的项目中,我看到有几次人们创建一个只包含一个元素的结构。 添加了最新的一个,在这个例子中,ipAddr是另一个结构(对于ipAddr是一个数组的情况的一个很好的解释是由Frerich Raabe给出的,但不幸的是,这不是这里的情况)

typedef struct
{
  ipAddr ip;
} Record;

我想如果代码正在改变并且在它开始时这是有意义的,因为可以轻松添加更多字段并且可以轻松地操作代码以支持新字段,但这是一个很久以前根据一个设计,所以我不认为这里的问题。

为什么要创建一个字段的结构呢?

2 个答案:

答案 0 :(得分:3)

我可以想到几个原因:

  1. 如果以后可能需要更多字段。这有点普遍。
  2. 故意使外部类型与内部类型不兼容。
  3. 对于第二个例子,想象一下:

    typedef struct
    {
        char postal_code[12];
    } Destination;
    

    在这种情况下,目的地由邮政编码完全指定,但这将让我们定义这样的函数:

    int deliver(const char* message, const Destination* to);
    

    这样,没有用户可以无意中调用该函数,反转两个参数,如果它们都是纯字符串,他们可以很容易地做到。

答案 1 :(得分:2)

只有一个字段的结构的一个常见原因是单个字段是一个数组,并且您希望能够定义返回此类数组值的函数。考虑例如。

typedef unsigned char ipAddr[4];

void f(ipAddr ip);         /* OK */
ipAddr g(void);            /* Compiler barfs: cannot return array. */

这可以通过引入structipAddr类型的单个成员来解决:

typedef unsigned char ipAddr[4];

typedef struct {
    ipAddr ip;
} Record;

void f(Record ip);         /* OK */
Record g(void);            /* Also OK: structs can be returned by value. */

但是,即使将数组传递给函数也是有问题的:您实际上并没有传递数组,而是传递指针(“衰减”类型为指针)。想象一下,上面声明的f需要创建给定IP地址的副本:

typedef unsignd char ipAddr[4];

void f(ipAddr ip) {
    ipAddr *a = malloc(sizeof(ip));
    /* ... */
}

这只适用于32位构建,因为指针的大小与四个unsigned char值的数组大小相同(4个字节)。 64位构建(或不同大小的阵列)会出现错误,要么分配太多或太少的内存。发生这种情况是因为在f内,ip的类型为unsigned char *,即指针。 struct有助于此,因为它不会衰减。