* ++ * p是否可以接受语法?

时间:2011-12-25 09:15:39

标签: c

在K& R第5.10节中,在类似grep的函数的示例实现中,有以下几行:

while (--argc > 0 && (*++argv)[0] == '-')
    while (c = *++argv[0])

理解语法对我来说是最具挑战性的事情之一,即使是在第一次查看它之后的几个星期,我仍然需要通过语法慢慢思考才能理解它。我使用这种替代语法编译了程序,但我不确定第二行是否允许。我从来没有见过这样的*++交错,但它对我有意义,它编译,然后运行。它也不需要括号或括号,这可能是我看起来更清楚的部分原因。我只是在一个方向上读取操作符(从右到左),而不是在变量名的任何一侧来回弹跳。

while (--argc > 0 && **++argv == '-')
    while (c = *++*argv)

4 个答案:

答案 0 :(得分:9)

对于一个人来说,这是让任何人阅读你的代码的一种方法 呵呵?!?!?!

因此,从可读性的角度来看,不,你可能不应该编写这样的代码。

尽管如此,这是有效的代码,并按此分解:

*(++(*p))

首先,p被取消引用。然后它会递增。然后它再次被解除引用。


更糟糕的是,这一行:

while (c = *++*argv)

在循环条件中有一个赋值。所以现在你有 两个 副作用让你的读者头脑旋转。 YAY !!!

答案 1 :(得分:3)

似乎对我有用。当然,你不应该从左到右阅读,这不是C编译器解析源的方式,而不是C语言语法的工作方式。根据经验,您应该首先找到要操作的对象(在本例中为argv),然后分析操作符,通常,就像在这种情况下,从内部(对象)到外部。实际的解析(和阅读)规则当然更复杂。

P上。 S.而且就个人而言,我认为这行代码实际上并不难理解(而且我不是C编程专家),所以我认为你不应该像Mysticial所暗示的那样用括号括起来。如果你知道我的意思,那只会让代码看起来很大......

答案 2 :(得分:1)

即使不了解优先规则,也没有歧义。

++*都是前缀一元运算符;它们只能应用于跟随它们的操作数。第二个*只适用于argv++*argv以及第一个*++*argv。所以它相当于*(++(*argv))++*的优先顺序之间没有可能的关系,这可能会使其成为其他任何内容。

这与*argv++不同,可以想象为(*argv)++*(argv++),你必须应用优先级规则来确定哪个(它是*(argv ++)`因为后缀运算符绑定比前缀一元运算符更紧密。)

有一个约束,++只能应用于左值;由于*argv是一个左值,这不是问题。

答案 3 :(得分:1)

这段代码有效吗?是的,但那不是你问的。

这段代码可以接受吗?这取决于(谁可以接受?)。

我不认为这是可以接受的 - 我认为由于一些不同的原因,它“比必要的阅读更难”。

首先;许多程序员必须使用多种不同的语言,可能使用不同的运算符优先级规则。如果您的代码看起来依赖于特定语言的运算符优先级规则(即使它没有),那么人们必须停下来并尝试记住哪些规则适用于哪种语言。

二;不同的程序员有不同的技能水平。如果你曾经在一个庞大的开发团队中工作,你会发现最好的程序员编写的代码是每个人都能理解的,最糟糕的程序员编写的代码包含一半团队无法发现的细微错误。大多数C程序员应该理解“*++*argv”,但是一个优秀的程序员知道少数“不那么好”的程序员要么不理解它,要么需要一段时间来弄清楚它。

第三;在所有不同的写作方式中,你应该选择最能表达你意图的变体。对于此代码,您正在使用数组,因此它应该看起来像您打算使用数组(而不是指针)。 注意:出于同样的原因,“uint32_t foo = 0x00000002;”优于“uint32_t foo = 0x02;”。