简体   繁体   English

以下代码如何将输出显示为-99?

[英]How is the following code giving the output as -99?

Given below is a C code snippet with str initialized to "face": 下面给出的是一个初始化为“ face”的str的C代码片段:

char *str = "face";
printf("%d\n", -2[str]);

First, we need to parse the expression in question: We have two operators in -2[str] - a subscript operator [] and a unary minus operator - . 首先,我们需要解析所讨论的表达式: -2[str]有两个运算符-下标运算符[]和一元负运算符- Subscript operator has higher precedence than unary minus, so printf prints a negation of 2[str] *. 下标运算符的优先级高于一元减号,因此printf打印否定2[str] *。

There are many Q&As explaining that 2[str] is the same as str[2] , so I am not going to repeat the explanation; 有很多问题和答案解释2[str]str[2]相同,因此我不再重复解释。 you can read about it in this Q&A . 您可以在本问答中阅读有关内容。

Finally, the value of str[2] is 'c' , which represents code of 99 on your system. 最后, str[2]值为'c' ,它表示系统上的代码99 Negation is applied to that value, so that is how -99 gets printed. 将负值应用于该值,这样便可以打印-99

* Note that - is not part of an integer constant, because in C integer constants do not include sign . *注意-不是整数常量的一部分,因为在C中,整数常量不包括sign

The code in the question is: 问题中的代码是:

char *str = "face";
printf("%d\n", -2[str]);

Let's be clear: this is horrid, and anyone writing that code should be made to rewrite it. 让我们清楚一点:这很可怕,任何编写该代码的人都应该重写它。

There are two parts to the confusion when approaching this: 解决此问题时,有两部分混淆:

  1. Why is a[i] == i[a] ? 为什么a[i] == i[a]
  2. How is -2[str] evaluated? 如何评估-2[str]

The linked question covers (1) extensively. 链接的问题广泛涵盖(1)。 Read it. 阅读。

To address the second part, consider an alternative program: 要解决第二部分,请考虑一个替代程序:

#include <stdio.h>

int main(void)
{
    char data[] = "XYZface";
    char *str = &data[3];
    printf("[%s] %d %d %d (%c)\n", str, -2[str], -(2[str]), (-2)[str], (-2)[str]);

    return 0;
}

This outputs: 输出:

[face] -99 -99 89 (Y)

Why? 为什么? The -2[str] notation is equivalent to -str[2] (you have read the linked Q&A, haven't you?) and not str[-2] , because there are no negative literal numbers. -2[str]表示法与-str[2]等效(您已经阅读了链接的问答,对吗?)而不是str[-2] ,因为没有负的文字数字。

Read C11 §6.4.4.1 Integer constants : there are no minus signs in there. 阅读C11§6.4.4.1整数常量 :其中没有减号。 When you write -2 , you have a unary minus operator and a literal 2 . 当您编写-2 ,您有一元减号运算符和文字2 Mostly, that's the same as negative two, but not when mixed with a higher priority operator such as subscripting. 通常,这与负二相同,但与高优先级运算符(例如,下标)混合使用时则不同。 The §6.5.2 Postfix operators such as subscripting have higher priority than the §6.5.3 Unary operators such as negation. §6.5.2后缀运算符 (如下标)比§6.5.3一元运算符(反)具有更高的优先级。

Let's also be clear: there is no undefined behaviour in the question's code (or mine, I trust). 让我们也清楚一点:问题代码中没有未定义的行为(或者我相信我的)。 Technically, the value for letter 'c' ( +99 ) is implementation-defined, but there are few extant systems where the integer value of 'c' is not 99 (but see EBCDIC for a code set where the answer would be different). 从技术上讲,字母'c'+99 99)的值是实现定义的,但是现存的系统中'c'的整数值不是99的系统很少(有关答案可能有所不同的代码集,请参见EBCDIC ) 。

Lets dissect: 让我们剖析:

-2[str]

is

-(2[str])

because of operator precedence. 由于运算符的优先级。 Note that the -2 is not directly an integer literal; 注意-2不是直接的整数文字; 2 is and it can receive the unary operator - , but before that happens, the [] operator is applied. 2是并且它可以接收一元运算符- ,但是在此之前,将应用[]运算符。
Next step is 下一步是

-(str[2])

Because (a well known if curious fact) a[i]==i[a] . 因为(众所周知的奇怪事实) a[i]==i[a]

-('c')

Because of the format string %d , this is seen as a negative int , with the absolute value of the ASCII value of 'c' . 由于格式字符串%d ,它被视为一个负int ,其ASCII值的绝对值为'c'

-(99)
-99

(This is of course a compilation of know-how by several commenters: Jonathan Leffler, StoryTeller and a little by myself.) (这当然是一些评论者的专有技术汇编:Jonathan Leffler,StoryTeller和我自己编写的一小部分。)

As explained in the comments the code is working like this: 如注释中所述,代码的工作方式如下:

-(2[str]) => -(*(2 + str)) => -str[2] -(2[str]) => -(*(2 + str)) => -str[2]

As str[2] is 'c' , whose ASCII value is 99 . 由于str[2]'c' ,其ASCII值为99 So the output is -99 . 因此输出为-99

Thanks, storyteller for clearing this out. 谢谢讲故事的人将其清除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM