Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C函数过度使用参数?_C - Fatal编程技术网

C函数过度使用参数?

C函数过度使用参数?,c,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

我在工作中使用了遗留的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); 

我忍不住想知道,在上面的示例中,我是否遗漏了一些东西,是否有充分的理由使用这种方法?

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


另外,
DoStuff
在我看来更干净。你真的应该使用
snprintf
。缓冲区管理内部的更改不会影响代码。但是,对于
NewDoStuff

来说,这不再是事实。您提供的代码有点不清楚(例如,为什么要将myOutPtr添加到sprintf的结果中

但是,一般来说,您实际上描述的是将一个做两件事的函数分解为一个做一件事的函数和一个做其他事情的代码(串联)

将职责分为两个函数是一个好主意。但是,对于这种连接和格式设置,您可能希望有一个单独的函数,这真的不清楚

此外,每次将一个函数调用分解为多个调用时,您都在创建代码复制。代码复制从来都不是一个好主意,因此您需要一个函数来实现这一点,并且最终(这是C)会得到与原始DoStuff类似的东西


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

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

一个优点是,如果您的代码中有许多、许多对这些函数的调用,那么反复重复
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);

根据经验,如果我的一个函数的接口超过110列,我会非常注意使用结构(如果我采用的是最好的方法)我们要做的是将一个函数分解成5个函数,除非函数中的某些功能不仅有用,而且本身也需要


我喜欢第一个函数,但我也非常习惯于标准的C风格。

那是什么+=sprintf?写入字符串,然后将指针向前移动写入的字节数。它不应该是=而不是+=?不。sprintf返回写入的字节数。我想将char*指针向前移动那么多字节在sprintf调用之后添加,以便下一个sprintf调用充当追加。在上面的MSDN链接中有类似的示例。缓冲区管理内部的更改意味着什么?我相信所有指针在这两种方法中都是相同的,尽管我可能是错的。@sipwiz:我假设
dostuf
会很小心在“myOutPtr+=sprintf(myOutPtr,“%d”,myAmount);”部分中,提示了上述语句。