什么是测试零长度字符串的有效方法:`strlen(str) > 0` 或 `*str`

What is efficient way to test zero length string: `strlen(str) > 0` or `*str`

假设 char *str;,以下方法有效测试空字符串

/* Approrach 1 */
if (str && strlen(str) > 0) {
    ... 
}

/* Approach 2 */
if (str && *str) {
    ...
}

最好用什么?我假设 second 会更快,因为它不必遍历缓冲区来获取长度。还有使用第二个的任何失败吗?

What is the most preferable to use?

显然是第一,因为它最易读。

方法 2,因为第一次尝试将遍历字符串(如果它不为空)。不,方法 2 没有缺点。

我会忽略性能问题。 CLANG 和 GCC 都会为“-O3”选项生成相同的代码。

godbolt

第一种方法更明确地表达了程序员的意图。

如果您启用了优化,编译器不太可能生成不同的代码。但是,如果性能真的是一个问题,那么使用第二种方法可能会更好。我说可能,因为它不是 100% 确定的。谁知道优化器会做什么?但是,如果第一种方法不为空,则存在第一种方法将遍历整个字符串的风险。

说到可读性,我认为第一个可读性稍好一些。但是,使用 *str 来测试空字符串在 C 语言中是非常惯用的。任何经验丰富的 C 编码人员都会立即理解它的含义。所以TBH,可读性问题主要是为了防止不是 C 程序员的人阅读代码。如果有人不理解 if (str && *str) 的作用,那么您也不希望他们修改代码。 ;)

如果您正在使用的代码库有编码标准,请坚持使用。如果没有,请选择您最喜欢的一个。没关系。

我会给出我认为更好的第三个选项:

if (str && str[0]) {
    // ... 
}

strlen 方法并不理想,因为它可以遍历非零长度的字符串。编译器可能会完全优化该调用(正如已经指出的那样),但它不会在每个编译器上运行(并且我假设 -ffreestanding 选项会禁用此优化),并且它至少使它看起来更像工作需要进行。

但是,我认为 [0] 的意图比 * 更清晰。我通常建议在取消引用指向单个对象的指针时使用 *,并在该指针指向数组的第一个元素时使用 [0]


为了更清楚,你可以这样做:

if (str && str[0] != '[=11=]') {
    // ... 
}

但这开始使特殊字符与字母数字字符的比例变得难以阅读。