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
是的,你可以去做。请注意 *pointer
是 pointer
指向(或保存地址)的内存位置的值。
我最近发现很多代码片段使用了:
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
是的,你可以去做。请注意 *pointer
是 pointer
指向(或保存地址)的内存位置的值。