2011-08-15 87 views
1
#include <stdio.h> 

int main() 
{ 
char *arr = "This is to test"; 
printf("\n%c %c ",*(arr++), *(arr++)); 
return 0; 
} 

该程序输出h T而不是输出h h。为什么这样?从字符指针打印字符

+4

两个字:未定义的行为(u)r –

+0

有没有办法输出'hh' ...它可能输出'h T'或'T h'(取决于没有定义参数的评估顺序),但'hh'只是没有意义。 –

+2

我期望他认为arr ++和arr + 1是一样的。他没有意识到++实际上修改了arr。 –

回答

5

ARR ++相当于给Arr + = 1.您实际上递增ARR。这就是你的情况正在发生的事情。

printf("\n%c %c ",*(arr++), *(arr++)); 
//    ^  ^Evaluates to 0 therefore prints T then increments by 1 
//     ^Evaluates to 1 therefore prints h and then increments by 1 
//Now if where to prinf %s arr it should print "is is to test" 

你想要做什么是

printf("\n%c %c ",*(arr+1), *(arr+1)); 

注:正如其他人所指出的多个前/后缀++/- 产生不确定的行为(评估顺序),应避免虽然我在你的情况了解你不是要修改原来的阵列。

+0

这并不回答为什么'h'在他的情况下'T'之前打印的问题。然而,它确实回答了他为什么不是'h''h'的问题的第二部分。 –

+0

我认为它确实回答了为什么'h T'是输出的问题。查看评论。 –

7

使用两个增量运营商在一个声明中是相互独立的引线不确定的行为,因为编译器可以自由选择其递增第一(或者说你没有给编译器任何暗示其中一个第一事要做)。

无论如何,如果你期待h h,这也是错误的写*(arr++)两次,因为他们将两个执行递增arr两次 - 所以会有印刷(arr[0]arr[1])两个不同的角色。

另一个错误是使用后增量,这将导致arr后递增字符已抓取,因此它会输出T,不h

因此,一个可能的解决方案是这样的代码,用一个额外的变量:

#include <stdio.h> 

int main() 
{ 
char *arr = "This is to test"; 
char c = *(++arr); 
printf("\n%c %c ", c, c); 
return 0; 
} 

在此代码,arr将只一次递增,并且在该位置取出的字符以后可以使用。

1

基本上,因为++在打印后将指针向前移动了一步,而且今天大多数编译器生成的代码最先完成。然后它会向左移动。

这是因为一元运算符arr ++将导致arr = arr + 1;,因为它使用的是后缀运算符,所以在将结果分配给arr之前将会打印它。

这样执行的步骤是:

  1. 印花T
  2. 移动指针到h
  3. 打印^ h
  4. 移动指针到我

如果你有三个在同一行,你会得到IH T作为这将导致其移动第三次。

我相信你正在尝试做的是值得的效果:

printf("\n%c %c ",*(arr+1), *(arr+1)); 
+0

“以及今天大多数编译器生成的代码”我认为这不是真正依赖于编译器本身,而是来自架构上使用的调用约定(特别是从堆栈上的参数顺序)。 –

1

如果u [R应该得到输出h小时。 然后u必须写

printf("\n%c %c",*(arr+1),*(arr+1)); 

但在这里,在你的代码更新改编,这是增量后增量所以首先它将该值赋给函数参数,然后变量递增。从左至右堆栈分配的功能

printf("\n%c %c ",*(arr++), *(arr++)); 

值,这样你们可以想像这样下面的语句:

printf("\n%c %c ",'h', 'T'); 

和论证“\ N%C%C”将打印输出从左正确的,你得到了输出h T.