while(*pointer) 在 C 中合法吗?

Is while(*pointer) legal in C?

我最近发现很多代码片段使用了:

while (*pointer) { 
    ... ++pointer; 
}

我和我的讲师一起检查了它是否好,"legal" 执行这样的操作,因为我认为在指针指向整数数组的情况下条件不会停止。

我无法得到明确的答案,如果使用这种情况是正确的以及为什么条件有效,我将不胜感激,因为不确定数组末尾是否为 0 / NULL停止条件。

提前致谢。

良好且合法,是的。这个用的很多。

一个例子,你想使用指针而不是索引(有时会有一些优势)。

计算字符串中*的个数

int counstar(char *s) {
    int n = 0;
    while(*s) if(*s++ == '*') n++;
    return n;
}

通常,(约定)C 字符串以 '[=14=]' 结尾,因此您知道它在哪里结束,而我仅 if (*s) 就足够了。

对于整数(以及除字符串以外的任何值),除非已指定(例如,最后一个数字是 0),否则您不知道数组的大小,需要一个变量来告知大小。但是,如果您知道最后一个为零,例如,算法将类似于上面的字符串 1。

将 x 与 n 个整数相加

void addx(int *a, int x, int n) {
   while (n--) *a++ += x;
}

如果您知道最后一项总是 0(并且不递增)

void addx(int *a, int x) {
   while (*a) *a++ += x;
}

我不知道你的指针指向什么具体类型,买除了0或NULL,'\0'也是零。所以对于C类型的字符串,也是可以的。

一个常见的用例是当存在可变长度的指针数组(例如动态分配的字符串数组)时,其大小由等于 NULL 的标记值确定。

这是一个非常简单的例子

#include <stdio.h>

int main( int argc, char * argv[] )
{
    while ( *argv ) puts( *argv++ );

    return 0;
}

这是有效的,因为根据 C 标准(5.1.2.2.1 程序启动)

2 If they are declared, the parameters to the main function shall obey the following constraints: ...

argv[argc] shall be a null pointer ,,,

"Is while(*pointer) legal in C?"

如果确保 pointer 指向一个字符串文字,一个包含字符串的 char 数组,或者指向一个基本或指针类型的数组,其中至少一个元素包含 [=13] =] 值,那么它是正确且合法的。

但是否则(如果指向的数组不包含至少一个具有 0 值的元素),这是不合法的,因为您将在该条件下访问超出数组边界的元素,因为pointer 的增量。要取消引用指向数组末尾的指针,调用 undefined behavior:

"If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated."

Source: ISO/IEC 9899:2011 (C11), 6.5.6/8

是的,你可以去做。请注意 *pointerpointer 指向(或保存地址)的内存位置的值。