返回一个int或传递一个int指针 - 什么更好?

时间:2010-06-30 14:06:18

标签: c

这两个中哪一个更好?

void SetBit(int *flag, int bit)
{
    *flag |= 1 << bit;
}

或者

int SetBit(int flag, int bit)
{
    flag |= 1 << bit;
    return flag;
}

11 个答案:

答案 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)

取决于。

在这种情况下,无论哪种方式都可行。但我可以想到两个特殊情况,我倾向于使用指针。

  1. 如果您传入的类型很大且值副本很昂贵,请出于性能原因使用指针。

  2. 如果您需要返回其他内容,可能是状态代码或成功/失败指示,那么您需要使用指针,以便留出空间来返回您需要返回的值。

  3. 我个人认为,在这些情况之外,第二个(按价值传递/返回)更清晰,更具可读性。

答案 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,即使在函数运行时其他内容发生了其他变化。使用读取和返回策略无法实现此类行为。