检查任何值是否为 NULL 或空的最佳方法是什么?

What's the best way for checking if any value is NULL or empty?

我想知道检查空值的最佳方式(我指的是性能和适当性)是什么?

我知道这两种方式:

第一个(我认为最好的):

对于任何指针检查:

if (value == NULL) ...

int

if (value == 0) ...

第二个:

if (value) ...

您应该使用 "First",因为它更易于理解、维护、...

性能方面没有明显差异。

两者将执行相同的操作,并且很可能会生成完全相同的汇编代码。使用您认为合适的任何东西。

最好考虑一下您的代码将如何被其他编码人员解释。从可读性的角度来看,if (value == NULL) 似乎比 if (!value) 更清晰。但这是风格问题。

For an Int : if (value == 0)

对于 int 如果值为 0。这并不意味着参数为空,它意味着参数保存值 0.

在性能方面,没有区别。您可以通过检查编译的汇编代码来检查这一点。

汇编代码如下。

#include<stdio.h>
int main()
{
    int a=0;

    if(a==0)
            printf("hello");

}

main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    , %rsp
    movl    [=11=], -4(%rbp)
    cmpl    [=11=], -4(%rbp)
    jne     .L3
    movl    $.LC0, %edi
    movl    [=11=], %eax
    call    printf

对于这个,

#include<stdio.h>
int main()
{
    int a=0;

    if(a)
            printf("hello");
}

main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    , %rsp
    movl    [=12=], -4(%rbp)
    cmpl    [=12=], -4(%rbp)
    je      .L3
    movl    $.LC0, %edi
    movl    [=12=], %eax
    call    printf

你可以看到两个代码是一样的,因此在性能方面没有区别。

但是,正如其他人提到的,FIRST 更容易理解,也更清晰。那个应该用

您应该始终使用 if(value == NULL),因为它是最清晰明确的形式。

if(value == 0)if(!value) 是常见的变体,但它们不太清楚,因为您无法判断其意图是检查指针还是变量的值。

以上 3 种形式之间没有性能差异,它们将产生完全相同的机器代码。


文体细节:

从风格上讲,最好始终将 if 语句视为布尔类型(就像在 C++ 中一样)。不幸的是,C 仍然使用 int,而不是真正的布尔类型,因此整数和布尔表达式之间不存在类型安全。

但是你可以像真正的布尔类型一样编写代码,因为这样你就可以使用外部静态分析器来获得更强的布尔表达式类型。例如,MISRA-C 使用术语 "essentially boolean" 来强制执行此操作。

这是一种相当不错且有效的方法,可以清除晦涩的表达式和与类型相关的错误。

在这样的代码中 if(value)if(!value) 是不允许的,因为这个例子中的值是一个指针,而不是布尔值。

资料来源:MISRA-C:2012 规则 10.1、11.9、14.4