【问题标题】:How can a C pointer of type int hold a memory address, given that a byte memory address is not of type int?假设字节内存地址不是 int 类型,那么 int 类型的 C 指针如何保存内存地址?
【发布时间】:2016-07-24 23:35:36
【问题描述】:

我正在查看"Pointers in C: when to use the ampersand and the asterisk" 的答案,对int *p2 = &i; 的示例感到困惑(来自 Dan Olson 的回答)

i 的地址不是一个 int,它是 0x02304 之类的东西,对吧?那么我们怎样才能把它放到p2 中呢?如果字节内存地址不是 int 类型,那么 int 类型的 C 指针如何保存内存地址?

谢谢!

附:对于对此感到困惑的任何人,我发现有帮助的另一个线程(尽管它没有为我回答这个问题)是"What exactly is a C pointer if not a memory address"Good lucky。

【问题讨论】:

  • p2 不是int。它是一个指向int的指针。所有指针都存储地址。无论地址指向什么,地址的大小都不会改变。
  • 如果 lhs 写成 int* p2 而不是 int *p2 会有帮助吗?
  • @kaylum:实际上,不同的指针类型可能有不同的大小,但这远远超出了这个问题的水平。
  • p2 不是 int 类型,而是 int* 类型
  • 这样想,& 符号给出了任何东西的地址,例如 0x02304。但是编译器需要知道要使用多少字节,从 0x02304 开始;这是需要“int”部分的地方。因此,32 位编译器在读取该地址的值时会自动读取 4 个字节。地址只是一个数字,指针是一个地址,但编译器有额外的数据类型信息。

标签: c pointers


【解决方案1】:

i的地址不是int,应该是0x02304吧?

指针是保存内存地址的变量。地址,就像你家的地址一样,是一个分配给内存字节位置的整数。

int 类型的 C 指针如何保存内存地址

在您的示例中,p2pointer-to-int 类型的变量。它是一个指针 - 一个内存地址 - 您要声明指向将存储 int 变量的内存。

【讨论】:

  • 谢谢,这个措辞好多了。
  • 地址可能不是整数(就像你家的地址 - 里面有字母)
  • 指针的另一个类比是酒店房卡,其中可以存储房间号,可用于访问房间及其包含的对象,查看它们甚至修改它们.房间号可以改,也可以失效。
【解决方案2】:

p2 不是int,它是指向int 的指针。因此,它可以保存int 变量的地址。

语法int *p2;定义了一个指向int的指针。

&i初始化p2将变量i的地址存储到p2中。修改p2指向的值会修改i的值。

以下替代语法都是等效的:

int *p2 = &i;
int * p2 = & i;
int * p2 =& i;
int*p2=&i;
int* p2 = &i;

首选语法是int *p2 = &i;,因为它避免了在同一行定义多个变量时常见的误解:

int *p1, *p2;  // defines 2 pointers to int
int *p1, p2;   // p1 is a pointer-to-int, whereas p2 is an int

在类型上加上* 会使后一个定义非常混乱:

int* p1, p2;  // p1 is a pointer-to-int, whereas p2 is an int

因此,强烈建议不要在同一行上定义具有不同间接级别的变量。

【讨论】:

    【解决方案3】:

    我认为int *p2 = &i; 令人困惑的原因是同时声明和实例化以及间距的综合效果。我会解释的。

    通常,对于指向整数 p2 和整数 i 的指针,写入“*p2”会取消引用 p2 并给出位于地址 &iint

    所以代码“int *p2 = &i;”使它看起来像 int 被设置为等于内存地址。

    确实是代码

    int i = 1;
    int *p2;
    *p2 = &i
    

    错了,因为在最后一行,*p2 是一个 int,因为它是取消引用的 p2,而 &i 是一个指针。

    为什么 int *p2 = &i; 与上面有缺陷的代码的最后一行不同:

    代码int *p2 = &i;与上面的3行代码不同,因为它是一个声明。声明指针变量时,输入类型(例如intlongchar 等)和变量名称(与正常一样) - 并且还输入星号 *在这两部分之间(请参阅上面的@chqrlie 答案,了解关于此的许多间距选项 - 最佳实践是将* 附加到变量名)。在声明中,* 没有取消引用指针。相反,它告诉编译器变量myPointer 将是一个指向内存的指针,它保存声明类型的数据(之前的intlongchar 等)。因此,在代码“int *p2 = &i;”中,指针同时被声明和实例化,* 不会在左侧呈现int。对于声明,虽然将* 放在变量名旁边更安全(正如@chqrlie 指出的那样),但即使在声明中实例化了指针,这也不会解开指针。对于声明,将* 视为附加到类型(而不是附加到变量名,有充分的理由很可能是)。我喜欢在指针名称旁边用* 声明指针,但要明白,在声明中实例化指针时,对于新学习者来说,想象该行的一种更清晰的方法可能是int* p2 = &1

    int* (type pionter-to-int) p2 (name of pointer) = &i (等于给出整数地址的指针i) ;

    感谢所有回答和评论的人,并祝所有可能来到这里试图弄清楚指针的人好运。

    【讨论】:

      【解决方案4】:

      指针是内存地址的抽象,具有一些相关的类型语义。

      p2 的类型为int *,或“指向int 的指针”。它存储一个整数对象的位置(在本例中为对象i 的位置)。 表达式*p2的类型是int

       p2 == &i;  // both expressions have type int * and evaluate to an address value
      *p2 ==  i;  // both expressions have type int and evaluate to an integer value
      

      指针与存储地址值所需的一样大,但是该地址值是针对给定平台表示的(无论是单个整数值,还是表示页码和偏移量的一对值,或者一些其他格式)。请注意,不同的指针类型可能具有不同的大小,尽管在现代桌面体系结构上它们都是相同的大小(32 位或 64 位)。

      指针的类型对指针运算很重要。给定一个指针p,表达式p + 1 产生指向类型的下一个对象的地址。如果指向的类型是 1 字节宽(例如 char)并且它的当前地址是 0x8000,那么 p + 1 会产生下一个字节的地址,即 0x8001。如果类型为 4 字节宽(例如 long)且其当前地址为 0x8000,则 p + 1 产生下一个第四字节的地址,即 0x8004。

      【讨论】:

        【解决方案5】:

        指针是它自己的类型。 如果它与不同的语法一起使用,它可以这样写:

        Pointer x = new Pointer(int, address);
        

        【讨论】:

          猜你喜欢
          • 2013-12-22
          • 2015-05-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-03
          • 2019-04-07
          • 1970-01-01
          相关资源
          最近更新 更多