C 我想知道一些关于这个代码的事情

C 我想知道一些关于这个代码的事情,c,C,谁能帮我解释一下这个代码为什么这个代码的结果是“13” #包括 #包括 int main() { 静态int a[]={1,3,2,3,4}; int*p[]={a,a+1,a+2,a+3,a+4}; int**ptr=p; ptr++; printf(“\n%d%d%d\n”,ptr-p,*ptr-a,**ptr); 返回0; } 如果您想了解更多信息,可以查阅“指针算法”,或者我的答案没有帮助 说明: int*p[]={a,a+1,a+2,a+3,a+4}用指向数组a中每个元素的指针填充数组

谁能帮我解释一下这个代码为什么这个代码的结果是“13”

#包括
#包括
int main()
{
静态int a[]={1,3,2,3,4};
int*p[]={a,a+1,a+2,a+3,a+4};
int**ptr=p;
ptr++;
printf(“\n%d%d%d\n”,ptr-p,*ptr-a,**ptr);
返回0;
}
如果您想了解更多信息,可以查阅“指针算法”,或者我的答案没有帮助

说明:

int*p[]={a,a+1,a+2,a+3,a+4}
用指向数组
a
中每个元素的指针填充数组
p
。它相当于
int*p[]={&a[0]、&a[1]、&a[2]、&a[3]、&a[4]}
p[0]
指向
a[0]
p[1]
指向
a[1]
,依此类推

int**ptr=p
然后创建指向数组开头的指针
p
。也就是说,它相当于
int**ptr=&p[0]

ptr++
递增
ptr
,以便它指向下一个元素。在这种情况下,结果与
ptr=&p[1]相同

然后,在打印数字时:

减去指针(指针算术)意味着结果等于两个操作数之间可以容纳的元素数。因为您之前增加了ptr行,所以它们正好相隔1个元素(即,
sizeof(int*)
ptr
指向
p[1]
p
指向
p[0]

同样,对于
*ptr-a
,它们相隔1个元素(仅在本例中,它是
sizeof(int)
*ptr
(即,
p[1]
)指向
a[1]
a
指向
a[0]

ptr
指向
p[1]
,它指向
a[1]
,它是
3
,因此
**ptr
3

代码警告:

正如David Bowling所指出的,
printf
语句对提供的参数使用了错误的格式说明符。由于指针减法的结果,例如
ptr-p
,是类型
ptrdiff\u t
,正确的格式说明符是
%td
printf(“\n%td%td%d\n”,ptr-p,*ptr-a,**ptr”)

使用
%d
说明符与
int
类型一起使用,当与不正确的类型一起使用时,会导致未定义的行为


您可以查看要与哪些类型一起使用的说明符,例如:

除了其他类型之外,“%d”是指针的错误格式说明符。@MartinJames
ptr-p
*ptr-a
是一个差(作为整数),而不是指针。另外,
**ptr
int
。此代码的作者应远离任何计算机。很抱歉,结果是“1 1 3”,我只需要解释一下此代码。@EugeneSh。我们不能以这种方式批准PROF/TA。这是指针算法的一个很好的解释,但是由于格式说明符和参数之间的不匹配,发布的代码会生成警告并具有未定义的行为:
ptr-p
*ptr-a
具有type
ptrdiff\u t
。正确的
printf()
格式说明符是
%td
printf(“\n%td%td%d\n”,ptr-p,*ptr-a,**ptr)@DavidBowling感谢您指出。我真的不确定那个表达式的结果类型,也没有费心去确定它是否真的是
int
(正如我第一次预料的那样)。然而,我假设
ptrdiff\u t
在今天的常用平台上与
int
基本相同。实际上,
ptrdiff\u t
很可能是
long int
typedef
t
是一种长度修饰符,可与
d
i
o
u
x
n
一起使用。我的系统上的警告是:警告:格式“%d”要求参数类型为“int”,但参数2的类型为“long int”[-Wformat=]。@DavidBowling:在64位windows系统上,更可能不支持
long long int
%td
。给定此lame示例中的值,
printf(“\n%d%d%d\n”,(int)(ptr-p),(int)(*ptr-a),**ptr)
是一个更简单可行的版本。@chqrlie--我没有意识到
long
在这里的64位Windows系统中很常见。至于
%td
,我当然指的是兼容编译器;)对于此类值,我曾经看到过一个很好的建议,例如,
%td
不可用:转换为尽可能宽的有符号类型,并为该类型使用适当的转换说明符;然而,发布的代码并不是一个真正的问题。。。。
#include <stdio.h>
#include <stdlib.h>


int main()
{
    static int a[]={1,3,2,3,4};
    int *p[]={a,a+1,a+2,a+3,a+4};
    int **ptr=p;
    ptr++;
    printf("\n%d %d %d\n",ptr-p,*ptr-a,**ptr);
    return 0;
}