微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

这些库函数的参数顺序重要吗?

如何解决这些库函数的参数顺序重要吗?

考虑这些库函数

void *calloc(size_t num,size_t size);
size_t fwrite(const void *ptr,size_t size,size_t count,FILE *stream);

我的问题是我是否可以安全地切换一些参数。这是:

calloc(1,8);
fwrite(p,1,8,s);

和这个一样吗?

calloc(8,1);
fwrite(p,s);

是的,我没有使用返回值。这不是重点。我的问题很简单,如果我切换元素数量的参数和元素大小的参数是否重要。可能还有更多的库函数适用于此,所以不要只限于我给出的两个示例。

解决方法

calloc()freadfwrite() 都将尝试交换计数和大小参数的相同工作。顺便提一下,这些参数以不同的顺序为 fread/fwritecalloc 指定:

size_t fread(void *ptr,size_t size,size_t nmemb,FILE *stream);
size_t fwrite(const void *ptr,FILE *stream);
void *calloc(size_t nmemb,size_t size);

虽然对 calloc() 没有区别,但将 fread()fwrite() 中的参数转置会对返回值产生影响,即成功读取或写入的元素数。确保使用正确的值并将返回值与 nmemb 参数(第三个参数)进行比较:

#include <stdio.h>

struct chunk {
    int a,b,c;
};

size_t copy_chunks(FILE *from,FILE *to) {
    struct chunk array[64];
    size_t total = 0,nread,nwritten;
    while ((nread = fread(array,sizeof(*array),64)) != 0) {
        nwritten = fread(array,nread);
        total += nwritten;
        if (nwritten != nread) {
            fprintf(stderr,"write error: wrote %zu of %zu elements\n",nwritten,nread);
            break;
    }
    return total;
}

请注意,在上述写入错误的情况下,实际写入的字节数是不确定的。

以下是来自 C 标准的文本:

7.21.8.2 fwrite 函数

概要

 size_t fwrite(const void * restrict ptr,FILE * restrict stream);

fwrite 函数从 ptr 指向的数组中,将最多 nmemb 个元素的大小由 size 指定到 stream 指向的流中{1}}。对于每个对象,对 size 函数进行 fputc 调用,从正好覆盖该对象的 unsigned char 数组中获取值(按顺序)。流的文件位置指示符(如果已定义)按成功写入的字符数前进。如果发生错误,则流的文件位置指示符的结果值是不确定的。

退货

fwrite 函数返回成功写入的元素数,只有在遇到写入错误时才会小于 nmemb。如果 sizenmemb 为零,则 fwrite 返回零并且流的状态保持不变。

如果你不关心返回值,那确实没什么区别……但是忽略错误可能会有所不同,这取决于意外情况的后果。还要考虑代码的后续读者,并通过使用适当的参数让他们更容易理解代码的作用。

其他库函数采用 void * 指针、大小和计数参数,如果您以错误的顺序传递它们,如果不是未定义,则行为会受到严重影响:

void *bsearch(const void *key,const void *base,int (*compar)(const void *,const void *));

void qsort(void *base,const void *));

void *bsearch_s(const void *key,rsize_t nmemb,rsize_t size,int (*compar)(const void *k,const void *y,void *context),void *context);
errno_t qsort_s(void *base,int (*compar)(const void *x,void *context);
,

size 指的是一个对象的大小,而 num 指的是此类对象的数量。我不明白你怎么能交换它。例如 这个,

fwrite(p,1,8,s); // Will return 8 if successful.

pp + 8 将 8 个 1 Byte 元素写入文件流 s

然而,这个,

fwrite(p,s); // Will return 1 if successful.

将一个从 pp + 8 的 8 字节元素写入文件流 s

当我们处理可能包含不同数据的 struct 对象时,差异是显而易见的。

当我们写入网络流时,差异也很明显。

calloc 的情况下,内存单元是连续的并不重要。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。