【问题标题】:C Pointers: Explain the program concept [closed]C指针:解释程序概念[关闭]
【发布时间】:2015-09-19 12:27:23
【问题描述】:

我正在学习指针基础知识。请看一下我的示例代码并告诉我发生了什么。

void main()
{
     int i, *j;
     i = 2;
     j = i;
     printf("%d", j);
     printf("\n%d", j + 1);
     printf("\n%d", j + 2);
}

我的输出是

2 6 10

请解释一下..

【问题讨论】:

  • 您最好自己阅读该主题。这个问题在过去已经被问过 数千次 次了。
  • "告诉我发生了什么事" -- 只有未定义的行为。
  • 如果你增加一个指向整数的指针,它会随着整数的大小而增加,所以它指向数组中的下一个整数。
  • 也许this 会有所帮助

标签: c pointers


【解决方案1】:

您看到的输出是因为您在编写 j + 1 时将地址 0x02 分配给了指针 j,您将其递增 1 与将其地址递增 sizeof(int) 或 @987654331 相同@ 是一样的。

但这种行为实际上是未定义的,就像 commented here 最初由 @Filipe Gonçalves 所定义,并由 @Kninnug 回复 my question - here

C11 §6.5.6/8:

[..] 如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为未定义。 [..]

您可以查看官方文档以了解更多信息。

此外,您的printf() 调用是未定义行为的原因。您应该使用%p 说明符打印指针并将指针转换为void *,如果您希望分配正确,您还应该将地址转换为int * 以使其工作。

如果您的系统是 64 位,则将 i 转换为 (int *) 也可能不够。

线

j = i;

如果您取消引用 j,可能会导致未定义的行为。

你不应该这样为指针分配整数,也许你的意思是

j = &i;

否则在启用编译警告的情况下,编译器应该警告您不正确的分配,尽管它是有效的,但它不正确


注意main() 返回int,并且您已将其声明/定义为不返回值。

【讨论】:

  • j+1j+2 是 UB。仅当结果指针指向同一数组中的元素或超出末尾的一个位置时,指针算法才被明确定义。并且使用%d 修饰符打印j 也是UB。
  • @FilipeGonçalves 你确定吗?你能告诉我在标准的哪个部分提到了这个,以便我可以解决答案吗?我以为它是无效的,但后来我想到不一定,除非你取消引用指针。
  • @iharob C11§6.5.6/8: [..] 如果指针操作数和结果都指向同一个数组对象的元素,或者在最后一个元素之后数组对象,评估不应产生溢出;否则,行为未定义。 [..]
  • @Kninnug 谢谢你,我只是引用了你的评论,所以请不要删除它。
  • @iharob 没问题,但您也可以在答案本身中包含评论(逐字或更改:引用的片段不能解释整个故事)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-16
  • 2014-04-01
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多