C 为什么stdio中的某些函数将流作为最后一个参数?

C 为什么stdio中的某些函数将流作为最后一个参数?,c,libc,C,Libc,stdio中的某些函数似乎将流作为最后一个参数,例如: char *fgets(char *restrict, int, FILE *restrict); int fputs(const char *restrict, FILE *restrict); size_t fread(void *restrict, size_t, size_t, FILE *restrict); size_t fwrite(const void *restrict, size_t, size_

stdio中的某些函数似乎将流作为最后一个参数,例如:

char    *fgets(char *restrict, int, FILE *restrict);
int      fputs(const char *restrict, FILE *restrict);
size_t   fread(void *restrict, size_t, size_t, FILE *restrict);
size_t   fwrite(const void *restrict, size_t, size_t, FILE *restrict);
有些人把它作为第一个论点:

int      fgetpos(FILE *restrict, fpos_t *restrict);
int      fseek(FILE *, long, int);
为什么会出现这种不一致?这些功能是在标准库演变的不同时期添加的吗?在这种情况下,哪一个是第一个,为什么公约会改变


我意识到,由于省略号的原因(对于
fclose
,与朋友一起使用
fprintf
文件*,或多或少需要先使用
文件*
,或者至少提前使用)

我确信,这个问题不会有一个明确而明显的答案,尽管这个问题不是基于意见的,因为一个明确的答案存在于某处,即使它是不可能得到的

然而,我认识到这个问题带来的挫折:如果除了学习函数名和它们所依赖的内容外,还单独记住每个函数的参数顺序,那么就不可能轻松工作。相反,最好有一个一致的参数顺序

为了实现这一点,可以实现一个一致的stdio库,该库将对参数使用一致的顺序,并将每个stdio函数包装到这样一个函数中。例如:

int      mystdio_fseek(long, int, FILE *);
这将返回

int      fseek(FILE *, long, int);

因此,
mystdio\uu
可能是一个前缀,以确保名称几乎相似,但不同,并且参数顺序是一致的。这样,就只需要记住函数名、每个函数所依赖的内容,而不再需要单独记住每个函数的参数顺序。只要不需要微优化,就可以使用这些方法。

另一个例子是fread,fwrite,其参数顺序为:size,count,而calloc,qsort,bsearch的参数顺序相反。至少在位置方法期望第一个参数作为文件句柄的意义上,它们是一致的,虽然带缓冲区的i/o方法要求首先使用缓冲区,但我非常怀疑这是否有任何理由。我只是查看了C基本原理文档,没有提到为什么参数是以一种或另一种特定方式排序的。大多数标准库函数最初都是古老的Unix函数。常识和科学方法从来都不是C89委员会的优先事项。他们只是兴高采烈地随机挑选现有的Unix函数,并将它们扔进标准库,没有顾虑,也没有三思。因此,像
gets
strncpy
这样的gems符合ISO标准。@Lundin我想在C89委员会成立时,这些函数已经是一个不容忽视的事实了。我想人们会更深入地挖掘历史来找到答案——或者至少是一个合理的理论。
fgets(line,MAXLINE,fp)
原型至少保留在K&R'78版本中:“fgets`从文件
fp
读取下一个输入
line
。看起来像是幼稚的编程。。。对于
putchar(c,fp)
:将字符
c
放在文件'fp等@2501中,我同意你的看法,mystdio_uu将是一个更好的前缀。c函数参数顺序的实际标准通常是(从左到右):目标、源(如果适用)以及其他内容。(例如,
memcpy
/
strcpy
的参数顺序非常规范)。如果坚持这一点,则
fseek
的顺序正确,
fprintf(文件*。