C 两个int指针之间的指针差

C 两个int指针之间的指针差,c,pointers,pointer-arithmetic,C,Pointers,Pointer Arithmetic,我希望输出为1,为什么是-1 假设在上面的问题中,我有+++a而不是a++ 它仍然是未定义的行为吗?当您增加指针时,它不会将值添加到1。它只是告诉指针指向下一个位置。此外,指针从未初始化,它们只是指向随机垃圾数 正如我在这里看到的,第一个问题主要是 int main(void) { int *a; int *b = a++; printf("%d\n",b-a); return 0; } a是自动本地的,并且初始值是不确定的(没有显式初始化),因此执行a++(或

我希望输出为1,为什么是-1

假设在上面的问题中,我有
+++a
而不是
a++


它仍然是未定义的行为吗?

当您增加指针时,它不会将值添加到1。它只是告诉指针指向下一个位置。此外,指针从未初始化,它们只是指向随机垃圾数

正如我在这里看到的,第一个问题主要是

int main(void) {
    int *a;
    int *b = a++;
    printf("%d\n",b-a);
    return 0;
}
a
是自动本地的,并且初始值是不确定的(没有显式初始化),因此执行
a++
(或者,
++a
)调用

关于指针减法,请参见上的回答

最后,两个指针的减法生成类型
ptrdiff\u t
,您应该使用
%td
打印结果。否则,您将再次调用UB


[如以下评论中所述]

假设指针已正确初始化,例如

 int *a;
在这种情况下,结果将是
-1
,因为这是两个元素索引中的差异(请记住
a++
is)

第§6.5.6/9章,
C11
标准

减去两个指针时,两个指针都应指向同一数组对象的元素, 或超过数组对象最后一个元素一次结果是 两个数组元素的下标。


除非两个指针指向同一数组的地址,否则在C中不定义两个指针(本例中为b-a)的差异

此外,由于代码中的指针“a”未被分配任何地址(包含垃圾值),因此执行任何类型的操作都是一种罪恶


如果您想了解两个指针的减法是如何工作的,那么请尝试定义一个数组并使这两个指针指向它。

int*a
是一个具有自动存储持续时间的变量,并且从未获取其地址(
&a
)。因此,代码会调用未定义的行为(根据6.3.2.1),您的程序不会有任何可预测的结果

ptrdiff\u t
上使用
%d
格式说明符也会调用未定义的行为(7.21.6.1/9)。您应该使用
%td
表示
ptrdiff\u t
%p
表示指针


因此,你不能期望从你的程序中得到任何东西。它可以输出任何内容,也可以不输出任何内容,或者崩溃。

首先,您的代码会导致未定义的行为,因为它读取和修改未初始化的变量

还应使用说明符%td打印指针差异

假设指针a实际指向有效对象:

int k[5] = {0};
int * a = &(k[0]);
int *b = a++;
printf("%td\n",b-a);
后缀
++
运算符给出操作数的当前值,然后将操作数递增1。上述代码与以下代码相同:

int i;
int *a = &i;
int *b = a++;
printf("%td\n",b-a);
指针a指向超过对象i的一个,指针b指向对象i。由于指针运算,减法将产生-1。如果操作为:
a-b
,则结果为1


这是已定义的行为。

未定义的行为

声明*a时,a指向内存位置,
*b=a++
;b指向与a相同的位置,增加a指向比b指向的上一个位置大1倍的位置

b-a=-1
//正确

我举个例子

int i;
int *a = &i+1;
int *b = &i;
printf("%td\n",b-a);
我引入
w
以更好地说明

变量的运行时内存地址看起来与上面的类似

b-a
(0x404-0x408)==-1(-4)

int的大小(在本例中)是4个字节。而持有int地址的指针的地址会改变(+/-)4倍, 就int而言,在这种情况下,4个字节包含一个整数(1个单位)

w-a==(0x400-0x408)=-2(-8)

如果你有


a-w==(0x408-0x400)=2(8)

,因为
b=a++
a
分配给
b
,然后增加
a
(这不会影响
b
)。这里唯一未定义的行为是使用未初始化的
a
@haccks是正确的。指针算法只有在两个指针都指向同一数组的成员时才有意义。在这种情况下,这可能是很清楚的,但我们不能忽视一个事实,即这是标准中未定义的行为。当所述未定义的行为被纠正时,告诉某人他们的代码有未定义的行为是微不足道的,并且无论如何都不会影响OP所询问的实际问题,这是非常没有建设性的。感谢@Cairnarvon对OP.的帮助@Haris--No.如果
a
被初始化,语句
b=a++
a
的值赋给
b
,然后递增
a
的值。在这种情况下,
b-a
不是
0
…指向同一数组的地址
+
或数组最后一个元素的地址
,如果指针正确初始化,结果会是什么?OP期望1…@Bob_uuu通常,我们需要(b-a)来获取这两个指针之间数组的元素数。但是因为int*b=a++;结果将是-1,这是没有用的。我不是落选的选民。我只是想问,为什么
a++
UB在这里?好的,这里的
a
是一个指针(已经放在堆栈上了),并且
a++
会将
a
中存储的地址增加4或8或其他任何值。我认为
(*a)+
将是UB。请告诉我我遗漏了什么。@babon你把
a
&a
搞混了吗
a++
基于相同的逻辑,如果
a
也会是
int
。如果指针
int main(void)
     {
        int *a; // 0x408
        int *w = a++; // 0x400
        int *b = a++; // 0x404

        int c = (b-a);
        printf("%d\n",b-a);// -1
        printf("%d\n",w-a); // -2

        return 0;
    }