我在研究结构体,发现了一些误解。我写了几个例子:
#include <stdio.h>
struct test{
char field[16];
};
int main(int argc, char * argv[]){
const char *string = "some string";
struct test t1 = {.field = *string};
struct test t2 = {.field = string};
struct test t3 = {.field = "some string"};
struct test t4 = {{'s', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0'}};
printf("t1::field = %s\n", t1.field); //prints s
printf("t2::field = %s\n", t2.field); //prints garbage character
printf("t3::field = %s\n", t3.field); //prints some string
printf("t4::field = %s\n", t4.field); //prints some string
}
输出:
t1::field = s
t2::field = 4
t3::field = some string
t4::field = some string
另一个例子是
#include <stdio.h>
struct test{
char field[16];
};
int main(void) {
const char *string = {'s', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0'};
struct test t = {.field = *string};
printf("t::field = %s\n", t.field); //segfault
}
输出为空。
这种行为对我来说并不是很清楚。在分配数组内存时,我们可以把它的第n个元素作为arr[n]
,扩展为*(arr + n)
.因此,我希望我们使用一些char field[16]
初始化char *
,并且将指针指向的对象作为某个数组的第一个元素来处理就足够了。
但从我的行为判断,我的理解是完全错误的。你能简单解释一下吗?
发布于 2018-12-14 05:13:03
结构测试{ char field16;};
包含一个带有16字符的字符数组field
。可以初始化数组,也可以将数组复制到数组,但不能分配数组。
有效
struct test t1 = {.field = \*string};
(将t1.field
初始化为string[0]
(例如*(string + 0)
或仅为*string
))
无效
struct test t2 = {.field = string};
(尝试将指针分配给字符串文本到数组,请参见C11标准- 6.3.2.1其他操作数-值、数组和函数指示符(P3))
有效
struct test t3 = {.field = "some string"};
(使用字符串文字初始化数组)
有效
struct test t4 = {{'s', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0'}};
(t4
与t3
相同,除非使用大括号括起来的初始化器,并且省略指定的初始化器.field
,它指示从第一个开始填充成员,参见C11标准§6.7.9初始化(p19))。
您的“另一个示例”失败的原因与t2
失败的原因相同。
发布于 2018-12-14 06:30:40
在第一个程序中,struct test t2 = {.field = string};
是一个错误,因为指针不是char数组的有效初始化器。
在第二个程序中,const char *string = {'s', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0'};
是一个错误,因为指针的初始化程序不能超过一个。
您应该使用一个编译器来显示这些错误的错误消息,否则您将使您自己难以学习C。
发布于 2018-12-14 05:51:10
为了扩展大卫C.的回答:
不管出于什么原因,C被设计成(在很大程度上)对于变量的声明、定义和使用具有相同的语法。这是一个永远的困惑源,尤其是数组。
可以使用数组表示法和指针表示法实现对分配内存的访问;实际上,数组表示法由编译器“分解”为指针表示法。
这导致人们认为数组实际上是指针--但是,从源代码的角度来看,它们不是。
两个主要的区别是:
1)这两种类型的初始化是根本不同的。
2)
您可能需要查看指针和数组的使用的反汇编;这个名为在线工具的是一个非常好的工具。
https://stackoverflow.com/questions/53773665
复制相似问题