C Is*++*p可接受的语法?
在K&R第5.10节中,在其类C Is*++*p可接受的语法?,c,C,在K&R第5.10节中,在其类grep函数的示例实现中,有以下几行: while (--argc > 0 && (*++argv)[0] == '-') while (c = *++argv[0]) 理解那里的语法对我来说是最具挑战性的事情之一,即使是在第一次看了几周之后,我仍然必须非常缓慢地思考语法才能理解它。我用这种替代语法编译了这个程序,但我不确定第二行是否允许。我从来没有见过像这样交错的*和++,但对我来说,这很有意义,它可以编译并运行。它也不需要括号或括
grep
函数的示例实现中,有以下几行:
while (--argc > 0 && (*++argv)[0] == '-')
while (c = *++argv[0])
理解那里的语法对我来说是最具挑战性的事情之一,即使是在第一次看了几周之后,我仍然必须非常缓慢地思考语法才能理解它。我用这种替代语法编译了这个程序,但我不确定第二行是否允许。我从来没有见过像这样交错的*
和++
,但对我来说,这很有意义,它可以编译并运行。它也不需要括号或括号,这也许是为什么我觉得它更清楚的一部分。我只是从一个方向(从右到左)读取操作符,而不是在变量名的任一侧来回跳转
while (--argc > 0 && **++argv == '-')
while (c = *++*argv)
首先,这是一种让所有阅读你代码的人都去的方法,哈强> 因此,从可读性的角度来看,不,您可能不应该编写这样的代码 尽管如此,它仍然是有效的代码,分解如下:
*(++(*p))
首先,p
被取消引用。然后它是递增的。然后再次取消引用
更糟糕的是,这一行:
while (c = *++*argv)
在循环条件中具有赋值。所以现在你有两个副作用让你的读者头晕目眩。耶 对我来说似乎有效。当然,您不应该从左到右阅读它,这不是C编译器解析源代码的方式,也不是C语言语法的工作方式。根据经验,您应该首先找到要对其进行操作的对象(在本例中为-
argv
),然后分析操作符,通常像本例中那样,从内部(对象)到外部。当然,实际的解析(和读取)规则更加复杂
另外,就我个人而言,我认为这一行代码真的不难理解(而且我不是C编程大师),所以我不认为你应该像神秘主义者建议的那样用括号括起来。如果你知道我的意思的话,那只会让代码看起来更大…没有歧义,即使不知道优先级规则
++
和*
都是前缀一元运算符;它们只能应用于它们后面的操作数。第二个*
只能应用于argv
,++
到*argv
,第一个*
到++*argv
。所以它相当于*(++(*argv))
。在++
和*
的先例之间没有可能的关系,这可能意味着其他任何东西
这与*argv++
不同,后者可能是(*argv++
或*(argv++)
,您必须应用优先级规则来确定哪个(它是*(argv++)`因为后缀运算符比前缀一元运算符绑定得更紧密)
有一个约束,
++
只能应用于左值;因为*argv
是左值,所以这不是问题。此代码有效吗?是的,但那不是你要的
这个代码可以接受吗?这取决于(谁能接受?)
我不认为这是可以接受的。我认为这是“比必要的阅读更难”的原因。
第一,;许多程序员必须使用几种不同的语言,可能使用不同的运算符优先级规则。如果您的代码看起来依赖于特定语言的运算符优先级规则(即使它不依赖),那么人们必须停止并尝试记住哪些规则适用于哪种语言
第二;不同的程序员有不同的技能水平。如果你曾经在一个庞大的开发团队中工作,你会发现最好的程序员编写的代码大家都能理解,而最差的程序员编写的代码包含团队中一半人无法发现的细微错误。大多数C程序员应该理解“*++*argv
”,但是一个好的程序员知道少数“不太好”的程序员要么不理解它,要么需要一段时间才能理解它
第三;在所有不同的写作方式中,你应该选择最能表达你意图的变体。对于这段代码,您使用的是一个数组,因此它看起来应该是一个数组(而不是指针)。注意:出于同样的原因,“
uint32\u t foo=0x00000002;
”比“uint32\u t foo=0x02;
”更好。在我看来像是未定义的行为。稍微更正一下<代码>argv[0]应为常量IMHO。也就是说,argv
是一个非常量的函数参数,但它指向字符串指针的只读数组。除此之外,对于熟练的C/C++来说,语法还可以programmer@PrasoonSaurav:它有什么未定义的?@valdo:标准明确规定,argc
和argv
以及argv
数组指向的字符串是可修改的。奇怪的是,它并没有说argv
数组的元素是可修改的(或者它们不是)。我不知道这个省略是否是故意的,但它在C11中没有改变。酷,我就是这么想的。我没有很多阅读代码的经验,所以我不知道它有多普遍,也不知道它是否会让人困惑。但我不认为这会让人困惑,因为这些操作符的关联性是从右到左的。像你那样使用括号可能很好,但这有点像说((4+5)+7)=16,不是吗?不管怎样,对我来说都不是特别重要,我也不想争辩。。。只是大声思考。:-)如果你停下来仔细阅读,就不会那么困惑了。但这是非常罕见的(我以前从未见过),更不用说奇怪的符号组合看起来会很尴尬。(让我想起x-->0
)@1111:你必须问这个问题。也就是说