【问题标题】:Can I dereference the address of an integer pointer?我可以取消引用整数指针的地址吗?
【发布时间】:2019-08-11 15:48:44
【问题描述】:

考虑到以下给定,我正在尝试找出可以填充 int 指针 k 的所有可能方法:

int i = 40;    
int *p = &i;    
int *k = ___; 

到目前为止,我想出了“&i”和“p”。但是,可以用“*&p”或“&*p”填空吗?

我对“*&p”的理解是,它取消了对整数指针地址的引用。这对我来说意味着如果打印出来将输出 p 的内容,即 &i。或者在初始化 int 指针时这是不可能的吗?或者任何时候都有可能?

我将“&*p”理解为整数*p指向的内存地址。这个我也不确定。

如果有人有任何建议或建议,我将不胜感激!真的想更好地理解指针。

【问题讨论】:

  • "是否可以用...填空" - 编译器怎么说?
  • int *k = p; printf ("*k is: %d\n", *k);
  • k = &*&*&*&*&*&*&*&*&*&*&*&i;

标签: c pointers


【解决方案1】:

指针基础知识

指针只是一个普通变量,它保存着其他东西的地址作为它的值。换句话说,一个指针指向可以找到其他东西的地址。通常你会想到一个保存立即值的变量,例如int i = 40;,而指针(例如int *p = &i;)只会保存40 存储在内存中的地址。

如果您需要存储在p 指向的内存地址的值,您取消引用 p 使用一元'*' 运算符,例如int j = *p; 将初始化 j = 40)。

由于p 指向存储40 的地址,如果您更改该地址的值(例如*p = 41;),41 现在存储在40 之前的地址。由于p 指向i 的地址并且您更改了该地址的值,所以i 现在等于41。但是j 驻留在另一个内存位置,并且它的值是在您更改i 地址的值之前设置的,j 的值仍然是40

如果您想创建第二个指针(例如int *k;),您只是在创建另一个变量,该变量将地址作为其值。如果您希望k 引用p 持有的相同地址作为其值,您只需初始化k,就像在声明它时通过分配其值来初始化任何其他变量一样,例如int *k = p;(这与在初始化后的某个时刻分配 k = p; 相同)。

指针算法

无论指向的对象类型如何,指针运算都以相同的方式工作,因为指针的type 控制指针运算,例如使用char * 指针,pointer+1 指向下一个字节(下一个char),对于int * 指针(正常的4 字节整数),pointer+1 将指向下一个int 在偏移处pointer 之后的 4 个字节。 (所以一个指针,只是一个指针....算术由type自动处理)

将 & 和 * 链接在一起

可用于获取对象地址和解引用指针的运算符是一元 '&' (address of) 运算符和一元 '*' (dereference)操作员。 '&' 在获取对象地址时增加了一层间接性'*' 在取消引用指针以获取指针所指向的值(或事物)移除了一级间接。所以正如@KamilCuk 在他的评论中举例解释的那样,你一个接一个地应用多少次并不重要,一个只是 adds 和另一个 删除了一层间接性,使得除了最终操作符之外的所有操作都是多余的。

(注意:在处理指针数组时,用于获取数组索引处的指针的后缀[..]运算符也起到取消引用删除一级间接的指针数组)

您的选择

鉴于您的声明:

int i = 40;    
int *p = &i;    
int *k = ___;

和上面的指针总结,你有两个选择,都是等价的。你可以直接用i的地址初始化指针k,例如

int *k = &i;

或者您可以通过分配p 持有的地址来初始化k,例如

int *k = p;

无论哪种方式,k 现在都将 i 的内存位置作为其值,40 当前存储在该内存位置。

【讨论】:

    【解决方案2】:

    我有点不确定你想做什么,但是,

    int* p = &i;
    

    现在,说&*p 真的就像说p,因为这会给你地址。

    只是p 更清晰。

    【讨论】:

      【解决方案3】:

      规则是(引用C11 standard footnote 102)对于任何指针E

      &*E is equivalent to E
      

      &*&*&*... 右侧的任何指针类型变量前面都可以有多个 &*&*&*...

      对于下面的&*&*&* 序列,我表示:零个或多个&* 序列。我在它后面放了一个空格,所以它就像,以某种方式可见。所以:我们可以将指针k分配给i的地址:

      int *k = &*&*&* &i;
      

      并将k 分配给与p 相同的值:

      int *k = &*&*&* p;
      

      我们也可以取指针 p 的地址,&p 也是如此,它将有int** - 即。它将是指向int 的指针。然后我们可以取消引用该地址。所以*&p。它将始终等于p

      int *k = &*&*&* *&p;
      

      可以用“*&p”或“&*p”填空吗?

      是的,两者都是正确的。 *&p 首先获取p 变量的地址,然后将其引用,正如我上面所说的。 *&variable 应始终等于variable 的值。第二个&*p 等于p

      我对“*&p”的理解是,它取消了对整数指针地址的引用。这对我来说意味着如果打印出来将输出 p 的内容,即 &i。或者在初始化 int 指针时这是不可能的吗?或者任何时候都有可能?

      是的,是的。它是可能的,任何时候,任何类型。 &* 仅适用于完整类型。

      旁注:函数真的很有趣。取消引用运算符* 在函数或函数指针前面被忽略。这只是 C 中的一条规则。参见 ex。 this question。只要其中没有&& 序列,就可以在函数或函数指针前面有无限的*& 序列。它变得荒谬:

      void func(void);
      void (*funcptr)(void) = ***&***********&*&*&*&****func;
      void (*funcptr2)(void) = ***&***&***&***&***&*******&******&**funcptr;
      

      funcptrfuncptr2 都分配了相同的值,并且都指向函数 func

      【讨论】:

      • 你也可以像&0[&i]&(&i)[0]
      • 现在任何理智的人都不会滥用这些规则,即使是The International Obfuscated C Code Contest
      • "对于任何变量 E &*E is equivalent to E" 并非如此。这仅适用于指针。此处相同:“任何时候都可以使用任何类型。& 仅可以使用完整类型。*”。相反,它确实适用于任何变量:*&E == E
      • 天哪。我有“任何指针E”。然后无缘无故地编辑为“对于任何变量E”。
      猜你喜欢
      • 2021-07-25
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 2014-01-12
      • 1970-01-01
      • 1970-01-01
      • 2014-08-06
      • 2015-09-10
      相关资源
      最近更新 更多