在采访中询问指针算术输出

时间:2015-07-28 14:07:45

标签: c string

char s[] = "arista2015";
char *p = s;
printf("%s",p+p[4]-p[1]);

此程序将输出显示为

  

ista2015

有人可以解释输出吗?

3 个答案:

答案 0 :(得分:7)

p[4]等于't'。它的ASCII码是116。

p[1]等于'r'。它的ASCII码是114。

因此 p+p[4]-p[1]p+2,即p指向的2个字节: 编辑:马特' s答案提出了一个非常好的观点 - 字符串外部的指针算法也是未定义的行为,因此p+116-114p+2实际上并不保证是相同的。

'a' 'r' 'i' 's' 't' 'a' '2' '0' '1' '5' '\0'
 ^       ^
 p      p+2

有趣的是,这是undefined behavior,但是!在EBCDIC系统上,它会打印一个空字符串,就像't' - 'r' == 10一样(是的,真的)。 C99标准仅保证与小数位'0''1''2' ... '9'对应的代码是连续的。

答案 1 :(得分:5)

由于加法运算符是左右关联的,因此关键表达式为:

(p + p[4]) - p[1]

而不是其他答案/评论所建议的p + (p[4] - p[1])。由于p + p[4]远远超出s的范围,因此会导致undefined behaviour,这意味着任何事情都可能发生(包括但不限于任何特定输出)。

答案 2 :(得分:1)

尝试运行这些代码并研究输出

#include<stdio.h>
int main(){
char s[] = "arista2015";
char *p = s;
printf("Address of p: %d\n",p);
printf("Address of 'a' in arista2015 : %d\n",&s[0]);
printf("Address of'r' in arista2015 : %d\n",&s[1]);

p=p+p[4]-p[1]; // Now address of P becomes p + 2 so its points to address of 'i'
printf("Address of 'i....'%d\n",&s[2]);// and it print from address of i before null
printf("%d\n",p);//prints the address
printf("%s\n",p);//prints the value

 }

运行这些代码并检查其工作原理如上所述。

我的输出:
地址:p:2686737
地址&#39; a&#39;在arista2015:2686737
地址&#39; r&#39;在arista2015:2686738
地址&#39; i ....&#39; 2686739
2686739个
ista2015