Adam Rosenfield 选择的答案是错误的。coobird的答案也是如此。出于这个原因,我对这两个答案都投了反对票。
Adam Markowitz 的解释*lineptr++
是正确的,但他没有回答主要问题这是否是合法的 C99 代码。只有 Tom Future 能做到;不幸的是,他没有解释*lineptr++
。我给他们每人一分。
所以简而言之,lineptr
是一个变量,可以作为指针进行操作。因此,增加指针是合法的。
lineptr
是指向字符序列的指针序列的指针。换句话说,它是指向字符串数组的第一个字符串的指针。根据代码,我们可以假设字符串是空('\0')终止的字符序列。 nlines
是数组中的字符串数。
while 测试表达式是nlines-- > 0
. nlines--
是后减量(因为--
在变量的右侧)。因此,它在执行测试之后执行,无论测试结果如何,在任何情况下都是如此。
因此,如果nlines
作为参数给出的值是0
,则首先执行测试并返回false
; 循环中的指令不被执行。请注意,因为nlines
无论如何都会递减,所以nlines
afterwhile
循环的值将是-1
.
如果nlines == 1
,则测试将返回true
并nlines
递减;循环中的指令将执行一次。请注意,在执行这些指令时, 的nlines
值为0
。再次执行测试时,我们又回到了nlines == 0
.
该printf
指令使用*lineptr++
表达式。它是指针的后增量(++
位于变量的右侧)。这意味着首先计算表达式,并在使用后执行增量。所以在第一次执行时printf
会收到字符串数组第一个元素的副本,它是指向字符串第一个字符的指针。lineptr
只有在那之后才增加。下次printf
执行时,lineptr
点在第二个元素上,并在打印第二个字符串时移动到第三个。这是有道理的,因为我们显然想要打印第一个字符串。如果 Adam Rosenfield 是对的,第一个字符串会被跳过,最后我们会尝试打印超出最后一个字符串的字符串,这显然是一件坏事。
因此,该printf
指令是以下两个指令的简明形式
printf("%s\n", *lineptr);
++lineptr; // or lineptr++, which is equivalent but not as good. lineptr += 1; is ok too.
请注意,根据经验,当前置增量和后置增量的作用相同时,出于性能原因,前置增量更可取。编译器会小心为您切换它。嗯,大多数时候。只要有可能,对预操作员自己最好,所以总是使用它。一旦您在 C++ 中实现了后自增和预自增,原因就会变得更加明确。