如何解决这些库函数的参数顺序重要吗?
考虑这些库函数:
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()
、fread
和 fwrite()
都将尝试交换计数和大小参数的相同工作。顺便提一下,这些参数以不同的顺序为 fread
/fwrite
和 calloc
指定:
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
。如果 size
或 nmemb
为零,则 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.
从 p
到 p + 8
将 8 个 1 Byte 元素写入文件流 s
。
然而,这个,
fwrite(p,s); // Will return 1 if successful.
将一个从 p
到 p + 8
的 8 字节元素写入文件流 s
。
当我们处理可能包含不同数据的 struct
对象时,差异是显而易见的。
当我们写入网络流时,差异也很明显。
在 calloc
的情况下,内存单元是连续的并不重要。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。