不考虑宗教论据:
选项一:
if (pointer[i] == NULL) ...
if (!pointer[i]) ...
在C语言中,选项1和选项2在功能上是等价的吗?
由于没有比较操作,后者是否更快地解析?
不考虑宗教论据:
选项一:
if (pointer[i] == NULL) ...
if (!pointer[i]) ...
在C语言中,选项1和选项2在功能上是等价的吗?
由于没有比较操作,后者是否更快地解析?
我更喜欢显式的样式(第一种版本)。这样可以明确指针参与而不是整数或其他类型,但这只是风格问题。
就性能而言,两种方式应该没有区别。
等价的。语言标准上就是这么说的。而且人们对于宗教信仰有着非常执着的偏好!
我喜欢第二种,其他人喜欢第一种。
实际上,我更喜欢第三种而不是第一种:
if (NULL == ptr) {
...
}
因为这样我:
=
== NULL
并将其误认为相反。从功能上讲,它们是等效的。
即使NULL
指针不是“0”(全部为零位),if (!ptr)
也与NULL
指针进行比较。
以下是错误的。 它仍然存在,因为有许多评论引用它: 不要将指针与字面值零进行比较。 它几乎可以在任何地方使用,但我IRC中未定义行为。
(void*)0
也是一个例外。当转换为指针类型时,它变成了一个空指针值。这时它就成为了指向某个地址而不是0x0的指针。但这与将指针与0进行比较无关。这并不是将地址与0进行比较。整数不是地址。 - Johannes Schaub - litbif(pointer[i] == NULL)
比if(!pointer[i])
慢,那么编译器不会将其更改为第二种更高效的形式吗?NULL
应该在标准头文件中声明如下:
#define NULL ((void*)0)
因此,无论如何,您都在与零进行比较,并且编译器应该以相同的方式进行优化。每个处理器都有针对与零进行比较的一些“优化”或操作码。
#define NULL (void *)0
。 - avakarNULL
定义为0
。 - Johannes Schaub - litb过早的优化是不好的。微小的优化也是不好的,除非你试图从CPU中挤出每一个Hz,否则没有必要这样做。正如人们已经展示的那样,编译器会自动优化大部分代码。
最好让你的代码尽可能简洁易读。如果这样更易读
if (!ptr)
比这个更好
if (NULL==ptr)
打开编译器优化,它们基本上是相同的
在gcc 4.3.3上测试过
int main (int argc, char** argv) {
char c = getchar();
int x = (c == 'x');
if(x == NULL)
putchar('y');
return 0;
}
对比
int main (int argc, char** argv) {
char c = getchar();
int x = (c == 'x');
if(!x)
putchar('y');
return 0;
}
gcc -O -o test1 test1.c
gcc -O -o test2 test2.c
diff test1 test2
没有产生任何输出 :)
-O0
参数以禁用优化确实会产生不同的二进制文件。 - Mark Rushakoff这真的取决于编译器。如果大多数现代C编译器对您所描述的具体场景没有生成几乎相同的代码,我会感到惊讶。
让您的编译器为每个场景生成一个汇编清单,您就可以回答自己的问题(针对您特定的编译器 :))。
即使它们是不同的,性能差异在实际应用中也可能是无关紧要的。
我进行了一次汇编转储,并发现了两个版本之间的差异:
@@ -11,8 +11,7 -
pushl %ecx
subl $20, %esp
movzbl -9(%ebp), %eax
- movsbl %al,%eax
- testl %eax, %eax
+ testb %al, %al
看起来后者实际上生成了一条指令,而第一个生成了两条指令,但这是相当不科学的。
这是gcc,没有优化:
test1.c:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *pointer[5];
if(pointer[0] == NULL) {
exit(1);
}
exit(0);
}
test2.c: 将 pointer[0] == NULL
改为 !pointer[0]
gcc -s test1.c,gcc -s test2.c,diff -u test1.s test2.s
char
和 NULL
进行比较?问题是关于指针的。(如果我看错了反汇编,请随意指出。) - avakarexit(1)
的简单调用,比较完全被优化掉。还要注意,您的片段存在未定义行为(访问未初始化的对象)。 - avakar