'标准'太奇怪了 [英] the 'standard' is so strange

查看:82
本文介绍了'标准'太奇怪了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这种行为对我来说似乎很奇怪,但我想有人会根据着名的C标准解释它。


-------------------- code ------------------------- ----------

#include< stdio.h>


int main(无效)

{

char xx [] =" abcd";

char * p1 = xx;

char * p2 = xx;

int i;

for(i = 0; i< 4; i ++)

printf("%d%c%c \ n",i,* p1 ++,* p1);

putchar(''\ n'');

for(i = 0; i< 4; i ++)

printf("%d%c%c\ n",i,* p2,* p2 ++);

}

--------------------输出------------------------ -----------

0 aa

1 bb

2 cc

3 dd

0 ba

1 cb

2 dc

3 d


--------------------------------------- ----------------------

-

我知道你来自英格兰,

但我保证不会反对

你。

This behavior seems very strange to me, but I imagine that someone will
be able to ''explain'' it in terms of the famous C standard.

-------------------- code -----------------------------------
#include <stdio.h>

int main (void)
{
char xx[]="abcd";
char * p1 = xx;
char * p2 = xx;
int i;
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p1++, *p1 );
putchar(''\n'');
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p2, *p2++);
}

-------------------- output -----------------------------------

0 a a
1 b b
2 c c
3 d d

0 b a
1 c b
2 d c
3 d

-------------------------------------------------------------

--
I understand you come from England,
but I promise not to hold it against
you.

推荐答案

Pilcrow写道:
Pilcrow wrote:

printf("%d %c%c \ n",i,* p1 ++,* p1);
printf("%d %c %c\n", i, *p1++, *p1 );



这行代码使您的程序不确定。


您修改p1并读取它两次

没有插入序列点,

获取对象的地址

将打印其值。

That line of code makes your program be undefined.

You modify p1 and read it twice
without an intervening sequence point,
to get an address of an object
that will have its value printed.


printf("%d%c%c\ n",i,* p2,* p2 ++);
printf("%d %c %c\n", i, *p2, *p2++);



那个也是。


N869

6.5表达式

[#2]在上一个和下一个序列点之间,一个对象

的存储值最多只能通过表达式的

评估一次修改。此外,只能访问先前值

以确定存储的值为




-

pete

That one too.

N869
6.5 Expressions

[#2] Between the previous and next sequence point an object
shall have its stored value modified at most once by the
evaluation of an expression. Furthermore, the prior value
shall be accessed only to determine the value to be
stored.

--
pete


Pilcrow< Pi ****** @ gmail.comwrites:
Pilcrow <Pi******@gmail.comwrites:

这种行为对我来说似乎很奇怪,但我想有人会根据着名的C标准''b $ b'来解释它。


-------------------- code -------------------------- ---------

#include< stdio.h>


int main(无效)

{

char xx [] =" abcd";

char * p1 = xx;

char * p2 = xx;

int i;

for(i = 0; i< 4; i ++)

printf("%d%c%c\ n" ;,i,* p1 ++,* p1);
This behavior seems very strange to me, but I imagine that someone will
be able to ''explain'' it in terms of the famous C standard.

-------------------- code -----------------------------------
#include <stdio.h>

int main (void)
{
char xx[]="abcd";
char * p1 = xx;
char * p2 = xx;
int i;
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p1++, *p1 );



效果p1 ++时未指定会发生的。因此

" * p1"在这种情况下毫无意义。编译器可以做它b $ b喜欢的东西。

It is not specified when the effect "p1++" will happen. Therefore
"*p1" is meaningless in this context. The compiler can do what it
likes.


putchar(''\ n'');

for(i = 0; i< 4; i ++)

printf("%d%c%c\ n,i,* p2,* p2 ++);
putchar(''\n'');
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p2, *p2++);



同样,当效果p2 ++时,没有指定它。会发生的。同样,

" * p2"在这种情况下毫无意义。再一次,编译器可以做它b $ b喜欢的东西。

Again, it is not specified when the effect "p2++" will happen. Likewise,
"*p2" is meaningless in this context. Again, the compiler can do what it
likes.


}


--- -----------------输出-------------------------------- ---


0 aa

1 bb

2 cc

3 dd
}

-------------------- output -----------------------------------

0 a a
1 b b
2 c c
3 d d



似乎编译器选择从右到左计算printf

的参数,或者不执行p1
直到评估完所有参数之后。你很幸运,更糟糕

可能发生的事情。

It appears that the compiler chose to evaluate the arguments to printf
from the right to the left, or to not perform the incrementation of p1
until after all arguments were evaluated. You were lucky, much worse
things could have happened.


0 ba

1 cb
2 dc

3 d
0 b a
1 c b
2 d c
3 d



似乎编译器选择评估printf的参数

从右到左,并在继续评估

左边的参数之前,在最右边的参数中执行p2的增量。再一次,你很幸运,更糟糕的事情可能发生。


结合这两个数据点,我想我们可以得出结论,

编译器选择评估它的参数从右到左和

执行与每个参数相关的副作用,因为它处理

该参数。允许这样做。它并没有被遗忘。


编译器的行为在任何方面看起来都不是非常奇怪,它

只是看起来未定义。唯一奇怪的行为是代码的作者认为他可以通过编写具有

未定义行为的代码来逃避。


Phil

-

我通过运行教程尝试了Vista语音识别。我很惊讶,这真是太棒了,我说的每一个字都很清楚。然后我说了

错误的单词......然后键入了正确的单词。实际上只是

检测声音并打印预期的单词! - pbhj on /。

It appears that the compiler chose to evaluate the arguments to printf
from the right to the left, and to perform the incrementation of p2 in
the rightmost argument before proceeding to evaluate the argument to the
left of it. Again, you were lucky, much worse things could have happened.

Combining those two data points, I think we can concluded that the
compiler choses to evaluate its arguments from right to left and to
perform the side-effects associated with each argument as it processes
that argument. It is permitted to so do. It it not oblided to so do.

The compiler''s behaviour does not in any way seem "very strange", it
simply appears undefined. The only strange behaviour is that of the
author of the code thinking he could get away with writing code with
undefined behaviour.

Phil
--
I tried the Vista speech recognition by running the tutorial. I was
amazed, it was awesome, recognised every word I said. Then I said the
wrong word ... and it typed the right one. It was actually just
detecting a sound and printing the expected word! -- pbhj on /.


Pilcrow< Pi ****** @ gmail.comwrites:
Pilcrow <Pi******@gmail.comwrites:

这种行为对我来说似乎很奇怪,但我想有人会根据着名的C标准''b $ b'来解释它。


-------------------- code -------------------------- ---------

#include< stdio.h>


int main(无效)

{

char xx [] =" abcd";

char * p1 = xx;

char * p2 = xx;

int i;

for(i = 0; i< 4; i ++)

printf("%d%c%c\ n" ;,我,* p1 ++,* p1);

putchar(''\ n'');

for(i = 0; i< 4; i ++ )

printf("%d%c%c\ n,i,* p2,* p2 ++);

}


--------------------输出------------------------- ----------


0 aa

1 bb

2 cc

3 dd

0 ba

1 cb

2 dc

3 d


----------------------------------- --------------------------
This behavior seems very strange to me, but I imagine that someone will
be able to ''explain'' it in terms of the famous C standard.

-------------------- code -----------------------------------
#include <stdio.h>

int main (void)
{
char xx[]="abcd";
char * p1 = xx;
char * p2 = xx;
int i;
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p1++, *p1 );
putchar(''\n'');
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p2, *p2++);
}

-------------------- output -----------------------------------

0 a a
1 b b
2 c c
3 d d

0 b a
1 c b
2 d c
3 d

-------------------------------------------------------------



其他人做得很好回答你的问题。但是我很好奇:为什么你对C

标准有这样一种不屑一顾的态度(在报价单中加上标准和解释字样)

标记等等)?


-

Keith Thompson(The_Other_Keith) ks *** @ mib.org < http://www.ghoti.net/~kst>

诺基亚

我们必须做点什么。这是事情。因此,我们必须这样做。

- Antony Jay和Jonathan Lynn,是部长

Others have done a very good job of answering your question. But I''m
curious: why do you have such a dismissive attitude regarding the C
standard (putting the words "standard" and "explain" in quotation
marks and so forth)?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


这篇关于'标准'太奇怪了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆