C功能过度使用参数?

时间:2009-03-31 04:25:40

标签: c

我有遗留的C代码库,我在下面的样式中找到了很多函数实现。

char *DoStuff(char *inPtr, char *outPtr, char *error, long *amount)
{
    *error = 0;
    *amount = 0;

    // Read bytes from inPtr and decode them as a long storing in amount
    // before returning as a formatted string in outPtr.

    return (outPtr);
}

使用DoStuff:

myOutPtr = DoStuff(myInPtr, myOutPtr, myError, &myAmount);

我觉得非常迟钝,当我需要实现类似的功能时,我最终会这样做:

long NewDoStuff(char *inPtr, char *error)
{
    long amount = 0;
    *error = 0;

    // Read bytes from inPtr and decode them as a long storing in amount.

    return amount;
}

使用NewDoStuff:

myAmount = NewDoStuff(myInPtr, myError);
myOutPtr += sprintf (myOutPtr, "%d", myAmount); 

我不禁想知道顶级例子中是否有一些我缺少的东西,是否有充分的理由使用这种方法?

5 个答案:

答案 0 :(得分:1)

这是C标准库样式。返回值用于辅助函数调用的链接。

此外,DoStuff是更清洁的IMO。你真的应该使用snprintf。缓冲区管理内部的更改不会影响您的代码。但是,NewDoStuff已不再适用。

答案 1 :(得分:1)

一个优点是,如果您的代码中有很多次调用这些函数,那么一遍又一遍地重复sprintf次调用将很快变得乏味。

此外,返回out指针使您可以执行以下操作:

DoOtherStuff(DoStuff(myInPtr, myOutPtr, myError, &myAmount), &myOther);

使用您的新方法,等效代码非常详细:

myAmount = DoNewStuff(myInPtr, myError);
myOutPtr += sprintf("%d", myAmount);
myOther  = DoOtherStuff(myInPtr, myError);
myOutPtr += sprintf("%d", myOther);

答案 2 :(得分:0)

您提供的代码有点不清楚(例如,为什么要使用sprintf的结果添加myOutPtr。

然而,一般来说,你实际上描述的是将一个函数分解为一个函数的函数,该函数执行一个事务,一个代码执行其他操作(连接)。

将责任分为两个功能是一个好主意。但是,您可能希望为此连接和格式设置单独的功能,但实际上并不清楚。

此外,每次将函数调用分解为多个调用时,都会创建代码复制。代码复制永远不是一个好主意,所以你需要一个函数来做到这一点,你最终会(这是C)看起来像你的原始DoStuff。

所以我不确定你能做些什么呢。非OOP语言的一个限制是您必须发送大量参数(除非您使用了结构)。你可能无法避开巨大的界面。

答案 3 :(得分:0)

如果你在每次调用NewDoStuff之后都要进行sprintf调用,那么你就是在重复自己(因此违反了DRY原则)。当您意识到需要以不同方式对其进行格式化时,您需要在每个位置更改它而不仅仅是一个位置。

答案 4 :(得分:0)

根据经验,如果我的一个函数的接口超过110列,我强烈期待使用一个结构(如果我采用最好的方法)。我不想做的就是使用一个函数来完成5件事并将其分解为5个函数,除非函数中的某些功能不仅有用,而且需要它自己。

我赞成第一个功能,但我也很习惯标准的C风格。