2015-09-19 110 views
-4

我正在学习指针基础知识。请看看我的示例代码,并告诉我发生了什么。C指针:解释程序概念

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 

请解释我..

+2

你可能更适合自己阅读这个主题。这个问题在过去几乎被数千次**问过。 –

+1

“_tell我怎么回事” - 除了未定义的行为。 –

+1

如果你增加一个指向一个整数的指针,它将以一个整数的大小递增,所以它指向数组中的下一个整数。 – wimh

回答

5

您所看到的输出是因为你指定的地址0x02指针j当你写j + 1你是通过递增1与递增其地址sizeof(int)sizeof(*j)相同。

但行为实际上是不确定的是commented here最初由@Filipe Gonçalves,并回答my question - 由@Kninnug

C11 § 6.5.6/8 here

[.. ]如果指针操作数和结果指向相同数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出;否则,行为是不确定的。 [..]

你可以查看官方文档阅读更多关于它。

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

如果您的系统是64位,那么将i复制到(int *)也可能不够。如果你曾经提领j

线

j = i; 

可能会导致不确定的行为。

你应该的整数分配给这样,也许你的意思

j = &i; 
与编译警告

否则启用,编译器应该警告你不正确的任务,虽然它是有效的它不正确指针。


注意main()回报int,并已申报/它定义为没有返回值。

+0

'j + 1'和'j + 2'是UB。只有当结果指针指向同一个数组中的一个元素或者结束时的一个位置时,指针运算才能很好地定义。使用'%d'修饰符打印'j'也是UB。 –

+0

@FilipeGonçalves你确定吗?你能告诉我标准的哪一部分是提到的,所以我可以修复答案吗?我以为它是无效的,但是在我看来,它并不一定,除非你解除指针的引用。 –

+2

@iharobC11§6.5.6/ 8:[*] *如果指针操作数和结果指向同一个数组对象的元素,或者一个超过数组对象的最后一个元素,那么评估将不会产生溢出;否则,行为是不确定的。* [..] – Kninnug