类似指针的区别

Anu*_*uri 2 c pointers

相同类型的两个指针的差异总是一个.

#include<stdio.h>
#include<string.h>
int main(){
int a = 5,b = 10,c;
int *p = &a,*q = &b;
c = p - q;
printf("%d" , c);
return 0;
}

Output is 1.
Run Code Online (Sandbox Code Playgroud)

我不明白其背后的原因

Kei*_*son 9

行为未定义.

C99 6.5.6第9段说:

当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素; 结果是两个数组元素的下标的差异.

同一节中的第7段说:

出于这些运算符的目的,指向不是数组元素的对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型.

第4节第2段说:

如果违反了出现在约束之外的"应该"或"不应该"的要求,则行为是不确定的.未定义的行为在本国际标准中以"未定义的行为"或省略任何明确的行为定义来表示.这三者之间的重点没有区别; 他们都描述了"未定义的行为".

3.4.3将术语"未定义行为"定义为:

行为,在使用不可移植或错误的程序结构或错误数据时,本国际协会没有要求

注意可能的未定义行为范围包括完全忽略不可预测的结果,在转换或程序执行期间以环境特征(有或没有发出诊断消息)的文档方式执行,终止翻译或执行(使用发布诊断消息).

鉴于声明:

int a = 5, b = 10, c;
Run Code Online (Sandbox Code Playgroud)

评估可能&b - &a会产生看似合理的结果,例如1-1.(合理的结果始终是未定义行为的可能症状;它是未定义的,不需要崩溃.)但是编译器没有义务放置a并且b在内存中的任何特定位置相对于彼此,即使它这样做,减法不保证有意义.优化编译器可以自由地转换程序,假设其行为定义良好,导致代码在违反该假设时可以以任意方式行事.

通过编写&b - &a,您实际上向编译器承诺这是一个有意义的操作.正如亨利·斯宾塞(Henry Spencer)所说的那样,"如果你对编译器撒谎,就会报复."

请注意,不仅仅是减法的结果是未定义的,它是评估它的程序的行为.


哦,我提到行为未定义吗?


NPE*_*NPE 5

实际上,程序的行为是不确定的.输出恰好1在你的平台/编译器,但它可以很容易被别的东西.