首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有数组成员的结构

具有数组成员的结构
EN

Stack Overflow用户
提问于 2018-12-14 04:49:47
回答 3查看 83关注 0票数 1

我在研究结构体,发现了一些误解。我写了几个例子:

代码语言:javascript
运行
复制
#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
}

输出:

代码语言:javascript
运行
复制
t1::field = s
t2::field = 4
t3::field = some string
t4::field = some string

意为

另一个例子是

代码语言:javascript
运行
复制
#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 *,并且将指针指向的对象作为某个数组的第一个元素来处理就足够了。

但从我的行为判断,我的理解是完全错误的。你能简单解释一下吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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'}};

(t4t3相同,除非使用大括号括起来的初始化器,并且省略指定的初始化器.field,它指示从第一个开始填充成员,参见C11标准§6.7.9初始化(p19))。

您的“另一个示例”失败的原因与t2失败的原因相同。

票数 2
EN

Stack Overflow用户

发布于 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。

票数 2
EN

Stack Overflow用户

发布于 2018-12-14 05:51:10

为了扩展大卫C.的回答

不管出于什么原因,C被设计成(在很大程度上)对于变量的声明、定义和使用具有相同的语法。这是一个永远的困惑源,尤其是数组。

可以使用数组表示法和指针表示法实现对分配内存的访问;实际上,数组表示法由编译器“分解”为指针表示法。

这导致人们认为数组实际上是指针--但是,从源代码的角度来看,它们不是。

两个主要的区别是:

1)这两种类型的初始化是根本不同的。

2)

  • 指针本身就是一个变量,在它“生命”的地方有一个独特的内存位置,因此可以重新分配或以其他方式操作。
  • 数组更像是编译器指令。当内存在其定义期间被分配时,没有存储到该内存的地址的单独位置。相反,编译器将根据机器代码中的堆栈(基)指针创建内存偏移量,以便对数组进行任何访问。当使用像arr_name或&arr_name这样的东西时,会创建一个临时指针(在某些CPU寄存器中),这些指针可以用于访问数组,也可以复制到指针变量中,但它本身并不是一个单独的实体。这就是人们所说的“数组衰变”为指针时的意思。

您可能需要查看指针和数组的使用的反汇编;这个名为在线工具的是一个非常好的工具。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53773665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档