所以我在C中有一个程序正在运行,但我不明白输出是如何生成的?
以下是该计划:
#include <stdio.h>
int c;
void main() {
int a=10,b=20,j;
c=30;
int *p[3];
p[0]=&a;
p[1]=&b;
p[2]=&c;
j=p[0]-p[2];
printf("\nValue of p[0] = %u\nValue of p[2] = %u\nValue of j = %d\n\n",p[0],p[2],j);
}
以下是输出:
Value of p[0] = 3213675396
Value of p[2] = 134520860
Value of j = -303953190
谁能告诉我j是如何得到这个值的,即-303953190 ?它应该是 3079154536
答案 0 :(得分:1)
p
是指向int的指针数组 - 因此它存储指向int而不是int的指针。因此,p[0]
和p[2]
是指针 - 减去它们将为您提供一个整数,该整数可能会溢出您试图存储在问题所在的int
中。地址也是使用%p
而不是%d
打印的。
取消引用该值,您将获得所需内容,例如:
j=p[0][0]-p[2][0];
或者像这样:
j=*(p[0])-*(p[2]);
答案 1 :(得分:1)
您应该计算指向对象而不是指针的差异:
j=(*(p[0]))-(*(p[2]));
答案 2 :(得分:1)
提取两个指针会产生有符号整数。
来自 C标准第6.56章:
6.5.6加法运算符
[...]
9当减去两个指针时,两个指针都指向同一个数组对象的元素, 或者超过数组对象的最后一个元素;结果是差异 两个数组元素的下标。结果的大小是实现定义的, 它的类型(有符号整数类型)是&lt; 中定义的 ptrdiff_t stddef.h&gt; 标题。
将指针差异分配给int
会溢出int
。
绕过这个溢出而不是
int j;
使用
ptrdiff_t j;
然后使用%td
打印该值。
来自 C标准章节7.17 :
7.17常用定义&lt; STDDEF.H&GT;
[...]
2类型为
的 ptrdiff_t的强>
这是减去两个指针的结果的有符号整数类型;
另外(无关)
void main()
错了。它应该是
int main(void)
所以正确的代码看起来像这样:
#include <stdio.h>
#include <stddef.h> /* for ptrdiff_t */
int c;
int main(void)
{
int a=10, b=20;
ptrdiff_t j;
int * p[3];
c=30;
p[0]=&a;
p[1]=&b;
p[2]=&c;
j=p[0]-p[2];
printf("\nValue of p[0] = %p\nValue of p[2] = %p\nValue of j = %td\n\n",
(void *) p[0],
(void *) p[2],
j);
return 0;
}
答案 3 :(得分:1)
您正在做3213675396 - 134520860.如果您想获取值,请使用* p [0]。如果你的目的是减去地址(这没有意义但仍然),预期的答案应该是3079154536.但是因为数字太大而无法容纳因此你得到答案-303953190。在数字行上考虑简化char
-128 -127 -126 -125 ... 0 1 2 ... 125 126 127
现在,如果您尝试将128存储在范围之外,那么它将给出-128的值。如果尝试分配值130,您将得到-126。因此,当超出右侧限制时,您可以看到计数从左侧开始。这仅仅是为了解释目的,因为它被存储为两个恭维的事实,这种行为的真正原因是欠的。更多信息可以在here
找到答案 4 :(得分:0)
您将其打印为整数而不是无符号。使用%u
代替%d
。
试试这个:
#include <stdio.h>
int c;
void main() {
int a=10,b=20;
unsigned j;
c=30;
int *p[3];
p[0]=&a;
p[1]=&b;
p[2]=&c;
j=(unsigned)p[0]-(unsigned)p[2];
printf("\nValue of p[0] = %u\nValue of p[2] = %u\nValue of j = %u\n\n",(unsigned)p[0],(unsigned)p[2],j);
}