当前位置: 首页 > 知识库问答 >
问题:

指向结构的指针是指向其第一个成员的指针吗?

蒙华翰
2023-03-14

我正在学习如何在C中使用结构,并写了以下示例:

#include <stdio.h>
#include <stdlib.h>

struct s1{
    unsigned short member;
};

int main()
{
    struct s1 *s1_ptr = malloc(sizeof(*s1_ptr));
    s1_ptr -> member = 10;
    printf("Member = %d\n", *s1_ptr); // Member = 10
}

问:是否保证在所有情况下指向一个结构的指针都是指向它的第一个元素的完全相同的指针?

在这种特殊的情况下,它能像我预期的那样工作,但我不确定它是否能得到保证。编译器可以在开始时插入一些填充吗?

我唯一能找到的关于结构类型布局的是第6.2.5节N1570的类型:

结构类型描述了一组按顺序分配的非空成员对象(在某些情况下,还包括一个不完整的数组),每个对象都有一个可选的指定名称和可能不同的类型。

但是这里没有填充。

共有2个答案

南门鸿雪
2023-03-14

嗯,不完全可能,但至少是可浇铸的。

指向结构的指针可以转换为指向其第一个成员的指针(或者,如果该成员是位字段,则转换为指向其分配单元的指针)。同样,指向结构的第一个成员的指针可以转换为指向封闭结构的指针。结构的任何两个成员之间或最后一个成员之后可能有未命名的填充,但在第一个成员之前不会。

所以你应该能够做到。

越雨泽
2023-03-14

开始的填充物被6.7.2.1p15覆盖(强调我的)

在结构对象中,非位字段成员和位字段所在的单位具有按声明顺序增加的地址。指向经过适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向其所在的单位),反之亦然。结构对象中可能存在未命名的填充,但在其开头没有。

因此,结构的地址是其第一个成员的地址。在指针转换之后,您可以从另一个中获取一个。

 类似资料:
  • 我正在学习链表,以及如何在C中使用结构和指针创建链表。下面我举一个例子。据我所知,被调用的将头节点所在的结构的开始内存位置作为参数传递。push()函数的参数将结构节点作为指向指针的指针,因此它作为引用传递,而不是实际副本。因此,我们的的第一个指针只是指向头部节点的内存位置的指针,第二个指针指向该值,该值是头部节点指向的下一个内存位置。我们通过为结构节点分配一些内存,在结构节点内创建一个名为new

  • 假设有一个结构 我得到一个指向该结构的成员的指针,比如作为某个函数的参数: 如何获取指向包含对象的指针?最重要的是:在不违反标准中的某些规则的情况下,也就是说,我想要标准定义的行为,而不是未定义或实现定义的行为。 附带说明:我知道这规避了类型安全。

  • 本文向大家介绍什么是指向指针的指针? 相关面试题,主要包含被问及什么是指向指针的指针? 时的应答技巧和注意事项,需要的朋友参考一下 指针指向的变量是一个指针,即具体内容为一个指针的值,是一个地址. 此时指针指向的变量长度也是4位.

  • 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针,或者 指向指针的指针。 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: 指针变

  • Go 语言中指向结构体的指针和 C 语言一样 结构体和指针 创建结构体指针变量有两种方式 package main import "fmt" type Student struct { name string age int } func main() { // 创建时利用取地址符号获取结构体变量地址 var p1 = &Student{"lnj", 33}

  • 在下面给出的代码中,我声明了一个指向int的指针,我们都知道memcpy返回一个指向目标字符串的空指针,所以如果ptr是指向int的指针,那么为什么printf(“%s”,ptr);是完全有效的,ptr毕竟不是指向char的指针。