初始化结构

时间:2010-06-05 04:26:22

标签: c

gcc 4.4.4 c89

我将添加到此列表中。所以我期待NULL终止它。但是,我收到了警告:"Initialization makes integer from pointer without a cast"

为什么我没有在那个结构中使用它时会提到整数?

我在想这个例子中的数组和指针是一样的吗?

 struct company_prof
    {
        char name[32];
        size_t age;
        char position[32];
    } employee[] = {
        { "Job Bloggs",  23, "software engineer"    },
        { "Lisa Low" ,   34, "Telecomms Technician" },
        { "simon smith", 38, "personal assistist"   },
        { NULL         , -1, NULL                   }
    };

非常感谢任何建议,

3 个答案:

答案 0 :(得分:5)

在这种情况下,您将静态地为结构中的字符串分配空间。字符串的空间实际上并不是与结构分开的实体,它只是一块空间。因此,您无法为这些字段分配指针,因为它们无法引用其他任何内容 - 它们只是用于引用结构中这些块的开头的方便名称。

你了解转换的原因是字符(例如name[0])是小整数,并且它试图将NULL指针填充到每个字符串的第一个字符中。第一个字符太小而无法容纳指针,所以它会给你一个警告。

您可能希望在此使用"\0"代替NULL。这是一个空字符串或空字符串,它与空指针有点不同。

编辑:您可以考虑获取列表大小的替代方法是使用sentinel值,而是定义一个从大小(以字节为单位)计算它的常量。典型的结构如下:

static const int num_employees = sizeof(employee) / sizeof(employee[0]);

答案 1 :(得分:5)

您正尝试使用NULL初始化字符数组。这没有任何意义。例如,您将从

获得相同的警告
char a[100] = { NULL };

并且以完全相同的方式没有任何意义。

诊断消息中提到的“整数”是字符数组的第一个元素。 char是C中的整数类型,当你写

char a[100] = { NULL };

尝试使用a初始化数组NULL的第0个元素。在您的平台上,NULL被声明为具有指针类型的东西,这就是诊断消息说您试图从指针(a[0])创建整数(NULL)的原因没有演员。

更简单的例子可能如下所示

char c = NULL;

并且出于同样的原因,它将为您获得相同的诊断信息。

请问您为何尝试使用char初始化NULL?你的意图是什么?

如果你不想在初始化后写入nameposition数组,也许你应该使用指针代替数组,如

struct company_prof
    {
        const char *name;
        size_t age;
        const char *position;
    } employee[] = {
        { "Job Bloggs",  23, "software engineer"    },
        { "Lisa Low" ,   34, "Telecomms Technician" },
        { "simon smith", 38, "personal assistist"   },
        { NULL         , -1, NULL                   }
    };

正式来说,在这种情况下NULL非常有意义。但不是在数组的情况下。

但不太正式地说,数组末尾的{ NULL, -1, NULL }记录的目的并不清楚。是某种终止元素?为什么不直接使用数组的确切大小而不是创建终止元素?

答案 2 :(得分:1)

您使用char [32]作为结构成员。 您无法从NULL转换为char [N]。所以最新发生的是NULL被视为零。警告来自编译器决定将NULL转换为0。 由于char [N]的初始化在数组内部发生,将其初始化为0是有效的,它只是将所有值设置为零。 e.g。

struct wrapper {char i [2]} w = {0}

将内部i设置为{0,0}

这意味着您的内存布局如下所示。

|==============name============||--||==========position===========|
0123456789012345678901234567890101230123456789012345678901245678901
Job.Bloggs0000000000000000000000(23)software.engineer00000000000000 // first
...                                                                 // rest
00000000000000000000000000000000(-1)0000000000000000000000000000000 // sentinel

这可能是也可能不是你想要的......但它确实意味着循环使用这些值并不是你所期望的:特别是这不起作用:

p = employee;
while( p.name != NULL )
{
  printf("%s", p.name);
  ++p;
};

它只会从内存中打印垃圾并最终导致段错误。

您可以尝试这样的事情

p = employee;
while( p.name[0] != 0 )
{
  printf("%s", p.name);
  ++p;
};

但是对于像“\ 0foo”这样的名字不起作用(你可能认为它无效......)