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

C 返回一个int或传递一个int指针——什么更好?,c,C,这两个哪一个更好 void SetBit(int *flag, int bit) { *flag |= 1 << bit; } void SetBit(int*标志,int位) { *flag |=1我喜欢第二个,因为它没有任何副作用。如果您想修改flag,只需将结果分配给它本身: flag = SetBit(flag, 4); 都不是 int SetBit(int flag, int bit) { return flag | 1 << bit; }

这两个哪一个更好

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

*flag |=1我喜欢第二个,因为它没有任何副作用。如果您想修改
flag
,只需将结果分配给它本身:

flag = SetBit(flag, 4);
都不是

int SetBit(int flag, int bit)
{
    return flag | 1 << bit;
}
int SetBit(int标志,int位)
{

返回标志| 1我更喜欢第二个

但是,我建议将函数的名称更改为更具描述性的名称(假设这是实际名称)。“SetBit”对描述函数的作用或返回的内容没有多大作用:)

这取决于具体情况

一是命令式风格,二是功能性风格

如果你想做

SetBit(SetBit(... SetBit(flag, b1), b2),...), bn)
做第二个。 如果你愿意

SetBit(&flag, b1)
SetBit(&flag, b2)
...
SetBit(&flag, bn)
做第一个。在C语言中,我更喜欢后者(即命令式)。在其他语言/上下文中,前者可能是个好主意。

这取决于情况

在这种情况下,任何一种方法都是有效的。但我可以想到两种特殊情况,我倾向于使用指针

  • 如果要传递的类型很大,并且值副本的成本很高,出于性能原因,请使用指针

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


  • 我个人认为,在这些情况之外,第二个(通过值传递/返回)更清晰,可读性更强。

    第二个更好,因为它不会崩溃


    如果传入无效的空指针,则第一个指针可能会崩溃,因此需要一些代码来检查和处理该指针。

    传递一个
    int
    以节省取消指针引用的时间。

    我将使用宏:

    #define BIT_SET(a, bit) ((a) | (1 << (bit)))
    

    #定义位集(a,BIT)((a)|(1老实说,我认为这只是鼓励人们使用“幻数”作为标志:

    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;
    

    \define SUPERMODE\u MASK(如果函数要内联,则可以先定义1。如果没有内联,则传递指向int的指针的开销会太大。(在64位LP64 ARCH上,int为4字节,指针为8。)

    第二…函数名SetBit()会引起一些轻微的混淆。名称意味着函数会更改某些内容,而实际上它不会。只要您对名称满意,那么从性能角度来看,它是一个更好的选择


    例如,Linux内核在许多类似的事情上使用指针变量,因为数据的内存位置通常是重要的,或者是可移植性所必需的。但它们要么使所有这些函数成为预处理器宏,要么用gcc的always_inline属性标记。对于用户区域,我认为应该首选第二个应用程序编程。只有选择一个更好的名称。

    如果使用函数的唯一模式是“变量= DOOMEOTY(变量)”,性能不是问题,我会考虑“DOWOMETY(变量)”;我唯一倾向于前者的是,如果目标有时不是源代码,或者如果性能至关重要,并且编译器无法有效处理后一种情况(在嵌入式系统中很常见),那么我会选择前者

    应注意,后一种格式允许前一种格式不允许的内容。在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 子轨道(ByRef N为整数,ByVal位为整数) 将值设置为整数 做 OldValue=N 线程时循环。联锁。比较交换(N,OldValue或位,OldValue)OldValue 端接头
    此代码的效果始终是to或将指定的位转换为N,即使在函数运行时其他内容更改了N。使用读取和返回策略不可能实现这种行为。

    我个人认为最好使用整个int(或char或short或其他)作为布尔标志。当然它使用了更多的内存,但可读性更高。除非内存是一个严重的限制,否则尽可能避免位攻击。@Polaris:我猜人们会认为这是一个性能问题(在重读几次之前,我几乎投了反对票…)@对于如此琐碎的事情,为什么要编写一个单独的函数?太多不需要的调用总是会对性能造成危害。@Arpan:因为现在任何合理的编译器都会将调用内联到这个函数中,这会使代码更可读。@Arpan:2个原因,这会使代码更可读,也不会出现错误typos…flag=SetBit(flag,A_flag);与flag |=1相反,它没有?对我来说似乎是有意义的--它设置了给定flag变量中的位。实际上我不同意-函数设置了位。该函数可以在任何必须设置位的上下文中使用。@Polaris:bit指定的一个参数。@Polaris:你会怎么称呼这个函数?我认为它的名字很清楚很简单,函数所做的就是在标志中设置位。它是将位设置为1还是0?函数样式使用不当(嵌套函数太深)不是避免它的借口。如果你想在单独的行中列出它们,你可以将SetBit的结果分配给每行的flag变量。你真的会认真地建议在C中使用第一个模式吗?(没有否决票,但我不得不质疑你是否会全部提及,因为这几乎是不可读的!)@白金我不确定,但我想不出一个好的和直接的理由来证明函数构造。真的,如果你在同一个值上连续做了很多次,我认为不使用'flag |=0xDEADBEEF'或你想要的位模式是什么,可能有点愚蠢。我会发现这更容易重新定义当然,速度也更快。除非您对select()或somet使用FD_SET 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