【问题标题】:how does pointer to structure works?指向结构的指针是如何工作的?
【发布时间】:2016-10-19 14:36:11
【问题描述】:

我知道变量指针。

int  x = 10;
int *ptr = &x;

在这些表达中涉及三件事:

  1. x 占用 2 字节内存,因为它是一个整数。

  2. ptr 也占用 2 个字节。

  3. 如果x的内存地址是1004,那么ptr会存储1004。

在这些示例中,每当我们在程序中使用*ptr 时,它都会给我们一个存储在内存地址 - 1004 的值

但是在结构中会发生什么? 举个例子:

struct book {
int a;
int b;
}
struct book str1, str2;
struct book *ptr = &str1;

我对这个例子有三个问题:

  1. ptr如何保存str1的完整地址?

  2. 指向变量的指针和指向内存中完整结构的指针有什么区别?

  3. ptr 需要多少字节?

  4. ptr 有会员吗?如果它有成员,那么它将有什么类型的成员? (指针或变量)

还有一件事——用类的对象代替它做什么

【问题讨论】:

  • Int 实际上是什么?我从 c++ 标准中不知道这一点。
  • 请注意,在 64 位机器中 int* 的大小需要 8 个字节而不是 4 个。
  • @HarshitPanchal “我现在不编译此代码......”如果您想要简洁和有用的答案,请发布minimal reproducible example。提供狂热的类型并不实用。
  • @HarshitPanchal 另请注意:每个问题一个问题!像您这样的东西不适合此处的预期常见问题解答格式。
  • @πάντα 但是耶稣,如果我写 Int 而不是 int 有什么关系,人们已经明白我在说什么

标签: c++ pointers memory structure


【解决方案1】:

1) ptr 是如何保存 str1 的完整地址的?

它保存起始地址。它不需要保存范围或任何东西。

2) ptr 在内存中的架构如何?

在内部,它是一个 32 位或 64 位无符号整数,具体取决于操作系统位宽(解释为指针)。

3) ptr 需要多少字节?

4 或 8 字节(适用于 32 或 64 位操作系统)。

4) ptr 有成员吗?如果它有成员那么它是什么类型的成员 会有吗? (指针或变量)

您可以使用-> 运算符取消引用指针,如

int x = ptr->a;

【讨论】:

  • Harshit 似乎使用的是 16 位架构,因此 ptr 应该只需要 16 位/2 字节。
【解决方案2】:
  1. 它拥有一个指向结构的指针。它也恰好是指向第一个元素的指针,如果您将其转换为 int。
  2. 指针在物理上是相同的,无论它们的类型如何,超出了语言赋予它们的语义(您可以通过强制转换来违反)。指针本质上只是一个数字,表示数据在长线性内存集中的存储位置。
  3. 与任何其他指针相同 - 但 因您的系统而异。 32 或 64 位,4/8 字节,通常。它将是void* 的大小。
  4. 指针没有成员。指针只是一个指针。但是,您可以遍历指向具有成员的结构的指针。

以下所有结果都相同:

str1.a = 10;
ptr->a = 10;
(*ptr).a = 10;

【讨论】:

  • 我对架构的简单意思是:简单变量指针和结构指针之间有什么区别。
  • 具体来说,不要求指向两种不同类型的指针大小相同。 (然而,要求任何指针都可以转换为指向 void 的指针。)不要求指针 数字;要求指针是你可以做数学运算的东西;那是微妙的不同。大多数通用架构的现代编译器确实将指针表示为固定位大小的数字是因为这很方便,而不是因为这是语言的要求。
  • @EricLippert 标准保证与否,我从未听说过,更不用说使用过任何不支持的系统。我很难想象#2 不成立的地方。 #3,uintptr_t 保证适合任何指针,如果任何指针可以与void* 相互互换,那么任何指针的大小都必须相同,并且应该与uintptr_t 共享该大小。不同大小的指针违反了 void* 可转换性。但是,从技术上讲,uintptr_t 可能更大,这是对的。我将进行编辑以反映这一点。
  • 是的,好吧,如今拥有虚拟内存和 32 位平面内存模型以及进程内存硬件隔离的年轻人应该离开我的草坪。很高兴您不必使用指针大小不同的地方!这真的很痛苦,让我告诉你。我很高兴得知这已经成为过去,以至于任何人都必须处理它实际上是不可想象的。
  • 如果您想花一些时间想象指针大小取决于它们所指向的内容的情况:考虑一个分段架构,其中有整个 兆字节 可用于代码但只有 64K 可用于数据。如果代码总是在代码空间中,而数据总是在数据空间中,那么指向函数的指针总是比指向数据的指针多字节。对数据使用代码大小的指针既浪费又慢。或者,当然,反之亦然;可能有很多数据内存,但很少有代码内存。
【解决方案3】:
  1. 您在这里真正想要的是什么? Ptr 将指向 str1 所在的内存地址。因此ptr 的值将与&str1 的值相同,但是如果您想获取指针的地址(通常为 4 个字节) -这里是&ptr,当然与ptr不同。

  2. 如前所述,指针通常占用 4 个字节的内存。

  3. 取决于您计算机的架构,如前所述,通常为 4 个字节。

  4. 指针不能有成员 指针可以指向有成员的结构或类。

【讨论】:

    【解决方案4】:

    指向struct 的指针没有什么特别之处。基本上所有的指针都只是一个内存地址。主要是在指针的类型很重要时取消引用指针,因为如果您有

    int a;
    int*  a_ptr = &a;
    

    然后

    *a_prt;
    

    会给你一个int,但如果你有

    struct foo { void bar(){} };
    foo a;
    foo* a_ptr;
    

    然后

    *a_ptr;
    

    会给你一个foo。与此相关,请注意

    a_ptr->bar();
    

    一样
    (*a_prt).bar();
    

    编译器可以检查foo 是否真的有bar(),如果指针类型未知,这是不可能的。

    【讨论】:

    • 我认为我们只能在类或对象中定义函数或方法。不在结构内部。
    • @HarshitPanchal 类和结构之间没有区别(除了它们的默认访问说明符)
    • @HarshitPanchal 不需要结构和类。我只能猜测,但我认为 Bjarne 认为为如此激烈的新概念引入一个新名称而不是仅仅扩展结构可以做的事情是有意义的。
    猜你喜欢
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多