这两个中哪一个更好?
void SetBit(int *flag, int bit)
{
*flag |= 1 << bit;
}
或者
int SetBit(int flag, int bit)
{
flag |= 1 << bit;
return flag;
}
答案 0 :(得分:7)
我喜欢第二个,因为它没有任何副作用。如果您想修改flag
,只需将结果分配给自己:
flag = SetBit(flag, 4);
答案 1 :(得分:6)
都不是。
int SetBit(int flag, int bit)
{
return flag | 1 << bit;
}
答案 2 :(得分:5)
取决于。
第一个是势在必行的风格,第二个是功能风格。如果你想做
SetBit(SetBit(... SetBit(flag, b1), b2),...), bn)
做第二个。 如果你想要
SetBit(&flag, b1)
SetBit(&flag, b2)
...
SetBit(&flag, bn)
做第一个。在C中,我更喜欢后者(即必要的)。在其他语言/语境中,前者可能是一个好主意。
答案 3 :(得分:5)
我会使用一个宏:
#define BIT_SET(a, bit) ((a) | (1 << (bit)))
答案 4 :(得分:5)
说实话,我认为这只是鼓励人们使用“魔术数字”作为旗帜:
SetBit(&flags, 12); // 12 is the flag for Super mode
你真正想要的是命名常数:
#define SUPERMODE_FLAG 12
...
SetBit(&flags, SUPERMODE_FLAG);
但是如果你要使用命名常量,你也可以命名掩码而不是位数,在这种情况下操作非常简单,不需要辅助函数:
#define SUPERMODE_MASK (1 << 12)
....
flags |= SUPERMODE_MASK;
在不寻常的情况下,你在不知道它们是什么意思的情况下按数字操纵各个位,然后我更喜欢第二个与Kristo相同的原因 - 我发现无副作用的函数比mutators更容易推理
答案 5 :(得分:1)
我更喜欢第二个......
但是,我建议您更改函数名称以使其更具描述性(假设这是实际名称)。 “SetBit”对描述函数的作用或返回没有太大作用:)
答案 6 :(得分:1)
取决于。
在这种情况下,无论哪种方式都可行。但我可以想到两个特殊情况,我倾向于使用指针。
如果您传入的类型很大且值副本很昂贵,请出于性能原因使用指针。
如果您需要返回其他内容,可能是状态代码或成功/失败指示,那么您需要使用指针,以便留出空间来返回您需要返回的值。
我个人认为,在这些情况之外,第二个(按价值传递/返回)更清晰,更具可读性。
答案 7 :(得分:1)
第二个更好,因为它不会崩溃。
如果传入 NULL 无效指针,第一个将可能会崩溃,因此你需要有一些代码来检查和处理它。
答案 8 :(得分:0)
传递int
以节省取消引用指针的时间。
答案 9 :(得分:0)
如果要内联函数,首先是OK。没有内联过多的开销来传递指向int的指针。 (在64位LP64 archs上,int是4个字节,指针是8。)
第二......函数名称SetBit()会引起一些轻微的混淆。名称暗示函数改变了某些东西,而事实上它没有改变。只要您对该名称没有问题,那么它在性能方面就是更好的选择。
E.g。 Linux内核使用指针变体的许多类似的东西,因为数据的内存位置通常是重要的或可移植性所需。但是它们要么将所有这些函数都设置为预处理器宏,要么使用gcc的always_inline属性进行标记。对于用户域,普通应用程序编程,我会说第二个应该是首选。只选择一个更好的名字。
答案 10 :(得分:0)
如果使用该函数的唯一模式是“variable = doSomething(variable);”并且性能不是问题,我会考虑“doSomething(&amp; variable);”更清晰。我唯一喜欢前者的方法是,如果目的地有时不是源,或者性能是至关重要的,而且一个人的编译器无法有效地处理后一种情况(在嵌入式系统中很常见)。
应该注意的是,后一种格式允许前者没有。在VB风格:
Sub OrBits(ByRef N as Integer, ByVal Bits as Integer) Dim OldValue as Integer Do OldValue = N Loop While Threading.Interlocked.CompareExchange(N, OldValue or Bits, OldValue) <> OldValue End Sub
此代码的效果将始终是将指定的位转换为N,即使在函数运行时其他内容发生了其他变化。使用读取和返回策略无法实现此类行为。