指针算术和C语言的读/写

时间:2013-11-25 19:40:26

标签: c pointers io filesystems system-calls

我正在编写一些非常低级的C代码来模拟家庭作业项目的“文件系统”。文件系统由固定大小的块(1024B)组成,但允许“文件”跨越多个非连续的块。

我需要能够将任何类型的void *buf写入具有模仿write的函数的文件中。假设我们有以下签名myWrite(int blockNum, void *buf, int nbytes

假设nbytes大于1024,所以我必须写入多个块。所以我需要做类似的事情:

int remainder = nbytes - 1024;
myWrite(firstBlock, buf, 1024);
myWrite(nextBlock, (buf + 1024), remainder);

myWrite调用下面的标准write函数,传入类似的参数。

问题在于指针算术,当我在void*上进行指针算术时,C不喜欢。我得到一个EINVALEARGS(取决于Mac与Linux),说C不喜欢我传递给write系统调用的指针,因为它是通过{{1指针算术。

问题是,我不知道我将写什么样的数据类型。有时它是void,有时它是自定义的,如char *,代表程序代码中的结构。

这有什么办法吗?我需要像这样的通用写。我当前的实现大部分时间都在工作,但有时会失败。

2 个答案:

答案 0 :(得分:2)

  

问题在于指针算术,当我在void*上进行指针算术时,C不喜欢

这是正确的:C禁止你向void*添加整数,因为它不知道如何将数字转换为推进指针的字节数。通常,乘数可以从指针的类型导出。但是,void*没有类型,因此C禁止对其进行算术运算。

C不介意你是否对已知大小的其他指针类型进行指针运算。您可以将void*指针转换为uint8_t*指针,char*指针或指向sizeof(*ptr)等于1的类型的任何其他指针,并且在进行算术运算之前对它进行算术运算:

myWrite(nextBlock, ((char*)buf) + 1024, remainder);

这些功能本身应该继续void*

答案 1 :(得分:2)

坚持使用void * - 指针。

当出现字节智能指针算法的需要时,只需将void *指针转换为char *(因为sizeof(char)被定义为等于1):

int a[2] = {47, 11};
void * p = &a[0];

printf("%d\n", *((int *)p)); /* Prints 47. */

p = ((char *) p) + sizeof(a[0]); /* Increments p by sizeof(int) bytes. */

printf("%d\n", *((int *)p)); /* Prints 11. */

另外作为注释:要输入描述内存或索引数量的整数,请使用size_t,因为它保证足够宽,可以解决/索引代码编译的机器上的所有内容。