这是C.我正在学习C,这是一个幻灯片中的例子。为什么这个指针减法输出这个?
int main(int argc, char *argv[]) {
int a = 5, b = 10, c;
int *p = &a, *q = &b;
c = p - q;
printf("%d", c);
return 0;
}
当我运行它的输出是3,我不明白为什么。这似乎是因为它使用&它会减去内存地址,输出将是内存地址为-5。
这是C.我正在学习C,这是一个幻灯片中的例子。为什么这个指针减法输出这个?
int main(int argc, char *argv[]) {
int a = 5, b = 10, c;
int *p = &a, *q = &b;
c = p - q;
printf("%d", c);
return 0;
}
当我运行它的输出是3,我不明白为什么。这似乎是因为它使用&它会减去内存地址,输出将是内存地址为-5。
你正在减去指针的地址,而不是它们指向的地址,你会得到两个存储器地址之间的差异,不能保证是任何特定的。如果你在不同的机器或编译器上运行它,它将很可能是完全不同的值,因为a
和b
可以分配到各种地址。例如,在我的机器上,它是1.类似的现象称为未定义的行为出于某种原因,因为您无法保证所有编译器和机器都有相同的结果。
如果您改为p
和q
像这样c = *p - *q;
您将得到-5作为c
作为两组值之间的差异。此外,如果您将p
和q
分配为int *p = a, *q = b;
,那么您也会将c
设置为-5,因为那样您就可以将指针设置为不同的地址,并在尝试访问之后尝试访问,在任何情况下都会是一个糟糕的主意。
谢谢,但我没有试图减去他们指向的东西,这是一个来自老师的例子,我不理解它,我只是在脑海中想到它会是-5。你能解释为什么它是3吗? –
@BenjaminDagg这正是我在回答中解释的内存地址的差异。它现在可能是3,但是可以在不同的计算机或编译器上重新编译它,它很可能会非常不同,因为地址会有所不同。 – Dom
@BenjaminDagg没有什么特别的原因,它只是3.它碰巧是3.如果你抛硬币,它可能会出现,但没有理由出现在头上。它只是。你为什么期望-5?这就是错误 - 你没有理由期待这一点。 –
减去2个不是同一个数组的指针是未定义的行为。
当两个指针相减时,它们都应指向同一个数组对象的元素,或者指向数组对象的最后一个元素之后的元素;结果是两个数组元素的下标差异。 C11§6.5.69
相反,得到一些数字差异,值转换为intptr_t
。
int main(int argc, char *argv[]) {
int a = 5, b = 10, c;
int *p = &a, *q = &b;
intptr_t ip = (intptr_t) p;
intptr_t iq = (intptr_t) q;
intptr_t diff = ip -iq;
printf("%lld", (long long) diff);
return 0;
}
当然您打印的值可能不是5. int
的位置从编译变化进行编译。
你能解释为什么你期望-5? –
你问为什么从另一个减去一个指针而不是从另一个减去一个指针? –