C++ 在C和C++;编程?
以下两段代码之间有什么区别吗?哪一个更好用?其中一个更快吗 案例1:C++ 在C和C++;编程?,c++,c,performance,if-statement,optimization,C++,C,Performance,If Statement,Optimization,以下两段代码之间有什么区别吗?哪一个更好用?其中一个更快吗 案例1: int f(int x) { int a; if(x) a = 42; else a = 0; return a; } int f(int x) { int a; if(x) a = 42; return a; } 案例2: int f(int x) { int a; if(x)
int f(int x)
{
int a;
if(x)
a = 42;
else
a = 0;
return a;
}
int f(int x)
{
int a;
if(x)
a = 42;
return a;
}
案例2:
int f(int x)
{
int a;
if(x)
a = 42;
else
a = 0;
return a;
}
int f(int x)
{
int a;
if(x)
a = 42;
return a;
}
实际上,这两个代码段可以返回完全不同的结果,所以没有更好的 在情况2中,您可以返回一个未初始化的变量a,这可能导致垃圾值不是零 如果你是这个意思:
int f(int x)
{
int a = 0;
if(x)
a = 42;
return a;
}
那么我想说的是更好,因为它更紧凑(但您只节省了一个else,没有多少计算浪费)实际上,两个代码段都可以返回完全不同的结果,所以没有更好的 在情况2中,您可以返回一个未初始化的变量a,这可能导致垃圾值不是零 如果你是这个意思:
int f(int x)
{
int a = 0;
if(x)
a = 42;
return a;
}
那么我想说的是更好,因为它更紧凑(但您只节省了一个else,没有多少计算浪费)以防您的第二个代码
int f(int x)
{
int a=0;
if(x)
a = 42;
return a;
}
而不是
int f(int x)
{
int a;
if(x)
a = 42;
return a;
}
没关系。如果你的第二个代码是
int f(int x)
{
int a=0;
if(x)
a = 42;
return a;
}
而不是
int f(int x)
{
int a;
if(x)
a = 42;
return a;
}
没关系。编译器会将它们转换为相同的优化代码。我更喜欢这个(您的第二个代码片段):
- 任何东西都应该有支架。即使现在if块中只有一行,我也会在以后添加更多
- 我不把大括号放在它们自己的行上,因为这是毫无意义的浪费空间
- 为了可读性,我很少将块与条件放在同一行
- 任何东西都应该有支架。即使现在if块中只有一行,我也会在以后添加更多
- 我不把大括号放在它们自己的行上,因为这是毫无意义的浪费空间
- 为了可读性,我很少将块与条件放在同一行
- 我更喜欢这个(你的第二个片段):
- 问题不是“哪一个更好”。问题是“两者都有效吗?”
答案是:不,它们不会同时起作用。一个是正确的,另一个是不可能的。因此,性能甚至不是问题
以下结果导致
a
具有c99标准第3.17.2节和第3.17.3节中提到的“不确定值”或“未指定值”(可能是后者,但我不清楚)
这又意味着函数将返回一个未指定的值。这意味着,这绝对不能保证你会得到什么价值
如果你运气不好,你可能会得到零分,因此继续使用上面那段糟糕的代码,而不知道你以后肯定会遇到很多麻烦
如果你是幸运的,你会马上得到类似0x719Ab32d的东西,所以你会马上知道你搞砸了
如果您试图编译这个问题,任何一个像样的C编译器都会给您一个警告,因此您提出这个问题的事实意味着您没有启用足够数量的警告。在未启用最大可能警告数的情况下,不要尝试编写C代码(或任何代码);它永远不会带来任何好处。了解如何在C编译器上启用警告,并尽可能多地启用警告。问题不是“哪一个更好”。问题是“两者都有效吗?”
答案是:不,它们不会同时起作用。一个是正确的,另一个是不可能的。因此,性能甚至不是问题
以下结果导致a
具有c99标准第3.17.2节和第3.17.3节中提到的“不确定值”或“未指定值”(可能是后者,但我不清楚)
这又意味着函数将返回一个未指定的值。这意味着,这绝对不能保证你会得到什么价值
如果你运气不好,你可能会得到零分,因此继续使用上面那段糟糕的代码,而不知道你以后肯定会遇到很多麻烦
如果你是幸运的,你会马上得到类似0x719Ab32d的东西,所以你会马上知道你搞砸了
如果您试图编译这个问题,任何一个像样的C编译器都会给您一个警告,因此您提出这个问题的事实意味着您没有启用足够数量的警告。在未启用最大可能警告数的情况下,不要尝试编写C代码(或任何代码);它永远不会带来任何好处。了解如何在C编译器上启用警告,并启用尽可能多的警告。在这两种情况下,您都不需要额外的空间,您可以这样做-
int f(int x)
{
if(x)
return 42;
else
return 0;
}
顺便说一句,在第二个函数中,您没有初始化a 在这两种情况下,您都不需要额外的空间来安装,您可以这样做-
int f(int x)
{
if(x)
return 42;
else
return 0;
}
顺便说一句,在第二个函数中,您没有初始化a 注意:我假设第二个代码段中未初始化的a是一个类型,它是int a=0 我们可以使用gdb检查差异:
(gdb) list f1
19 {
20 int a;
21 if (x)
22 a = 42;
23 else
24 a = 0;
25 return a;
26 }
(gdb) list f2
28 int f2(int x)
29 {
30 int a = 0;
31 if (x)
32 a = 42;
33 return a;
34 }
现在让我们看一下带-O3的汇编代码:
(gdb) disassemble f1
Dump of assembler code for function f1:
0x00000000004007a0 <+0>: cmp $0x1,%edi
0x00000000004007a3 <+3>: sbb %eax,%eax
0x00000000004007a5 <+5>: not %eax
0x00000000004007a7 <+7>: and $0x2a,%eax
0x00000000004007aa <+10>: retq
End of assembler dump.
(gdb) disassemble f2
Dump of assembler code for function f2:
0x00000000004007b0 <+0>: cmp $0x1,%edi
0x00000000004007b3 <+3>: sbb %eax,%eax
0x00000000004007b5 <+5>: not %eax
0x00000000004007b7 <+7>: and $0x2a,%eax
0x00000000004007ba <+10>: retq
End of assembler dump.
(gdb)反汇编f1
函数f1的汇编程序代码转储:
0x00000000004007a0:cmp$0x1,%edi
0x00000000004007a3:sbb%eax,%eax
0x00000000004007a5:不是%eax
0x00000000004007a7:和$0x2a,%eax
0x00000000004007aa:retq
汇编程序转储结束。
(gdb)分解f2
函数f2的汇编程序代码转储:
0x00000000004007b0:cmp$0x1,%edi
0x00000000004007b3:sbb%eax,%eax
0x00000000004007b5:不是%eax
0x00000000004007b7:和$0x2a,%eax
0x00000000004007ba:retq
汇编程序转储结束。
正如你所看到的,没有区别。让我们使用-O0禁用优化:
(gdb) disassemble f1
Dump of assembler code for function f1:
0x00000000004006cd <+0>: push %rbp
0x00000000004006ce <+1>: mov %rsp,%rbp
0x00000000004006d1 <+4>: mov %edi,-0x14(%rbp)
0x00000000004006d4 <+7>: cmpl $0x0,-0x14(%rbp)
0x00000000004006d8 <+11>: je 0x4006e3 <f1+22>
0x00000000004006da <+13>: movl $0x2a,-0x4(%rbp)
0x00000000004006e1 <+20>: jmp 0x4006ea <f1+29>
0x00000000004006e3 <+22>: movl $0x0,-0x4(%rbp)
0x00000000004006ea <+29>: mov -0x4(%rbp),%eax
0x00000000004006ed <+32>: pop %rbp
0x00000000004006ee <+33>: retq
End of assembler dump.
(gdb) disassemble f2
Dump of assembler code for function f2:
0x00000000004006ef <+0>: push %rbp
0x00000000004006f0 <+1>: mov %rsp,%rbp
0x00000000004006f3 <+4>: mov %edi,-0x14(%rbp)
0x00000000004006f6 <+7>: movl $0x0,-0x4(%rbp)
0x00000000004006fd <+14>: cmpl $0x0,-0x14(%rbp)
0x0000000000400701 <+18>: je 0x40070a <f2+27>
0x0000000000400703 <+20>: movl $0x2a,-0x4(%rbp)
0x000000000040070a <+27>: mov -0x4(%rbp),%eax
0x000000000040070d <+30>: pop %rbp
0x000000000040070e <+31>: retq
End of assembler dump.
(gdb)反汇编f1
组件转储