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 }
};
非常感谢任何建议,
答案 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
?你的意图是什么?
如果你不想在初始化后写入name
和position
数组,也许你应该使用指针代替数组,如
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”这样的名字不起作用(你可能认为它无效......)