Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.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,我已经在这个问题上努力了好几个小时了。假设您有一个以int值为参数的函数。我需要做的是取这个int值,并将该值解释为要添加到地址的字节数: void* foo(int size){ node->pointer += size; //assume node->pointer is of type void* } 上面所做的实际上是向指针添加size*4字节,因为int是4字节。将其转换为(char*),即 这不管用。 如何以最简单的方式做到这一点?如果您不介意使用GCC扩展()并

我已经在这个问题上努力了好几个小时了。假设您有一个以int值为参数的函数。我需要做的是取这个int值,并将该值解释为要添加到地址的字节数:

void* foo(int size){
  node->pointer += size; //assume node->pointer is of type void*
}
上面所做的实际上是向指针添加size*4字节,因为int是4字节。将其转换为(char*),即

这不管用。
如何以最简单的方式做到这一点?

如果您不介意使用GCC扩展()并且您实际上正在使用GCC(或Clang),那么您可以使用
+=
编写(或多或少)您编写的内容:

void foo(int size)
{
    node->pointer += size; // Not standard — using GCC extension
}
但它不是标准的C,因此不可移植。根据C11(ISO/IEC 9899-2011):

  • :void类型包含一组空值;它是一个不完整的对象类型,无法完成
  • :sizeof运算符不得应用于具有函数类型或不完整类型的表达式、此类类型的括号名称或
  • :对于加法,两个操作数都应具有算术类型,或者一个操作数应为指向完整对象类型的指针,另一个操作数应具有整数类型
  • :对于减法,以下其中一项应适用:
    • 两个操作数都具有算术类型
    • 两个操作数都是指向兼容完整对象类型的合格或不合格版本的指针;或
    • 左操作数是指向完整对象类型的指针,右操作数是整数类型
  • :仅对于运算符
    +=
    -=
    而言,左操作数应为指向完整对象类型的原子指针、限定指针或非限定指针,右操作数应为整数类型;或者,左操作数应具有原子、限定或非限定算术类型,右操作数应具有算术类型
由于
void
类型不完整且无法完成,因此
void*
是指向不完整类型的指针,因此不能将
void
用于
sizeof
,也不能将
void*
用于
+
-
进行指针运算,因此,您也不能将
void*
与复合赋值
+=
-=
一起使用

标准C当量为:

void foo(int size)
{
    node->pointer = (char *)node->pointer + size;
}

与您的代码相比,此代码不会返回值(尽管您说过会返回,因为返回类型是
void*
)。由于
节点->指针
是一个
无效*
,您不需要将其转换回
无效*
;这是C,转换是自动的。

编写示例代码供您参考。我使用了与上面回答类似的概念

#include <stdio.h>

struct node{
 int payload;
 void *ptr;
}*n;

void foo(int x){
 n->ptr = (char *)n->ptr +x;
}

int main(){
  n = malloc(sizeof(struct node));
  n->payload = 10; //random payload
  n->ptr = n;

  printf("%p\n", n->ptr);
  foo(2); //increment by 2
  printf("%p\n", n->ptr);
}
#包括
结构节点{
有效载荷;
无效*ptr;
}*n;
void foo(int x){
n->ptr=(char*)n->ptr+x;
}
int main(){
n=malloc(sizeof(struct node));
n->有效载荷=10;//随机有效载荷
n->ptr=n;
printf(“%p\n”,n->ptr);
foo(2);//增加2
printf(“%p\n”,n->ptr);
}

尝试
节点->指针=(void*)((char*)(节点->指针)+大小)非常感谢!我不敢相信我忽略了把它扔回虚空@因为
char*
会自动转换为
void*
,所以不需要显式转换为
void*
。对吗?您的标题询问如何向“void pointer”添加若干字节,但您的问题暗示您正在向指向
int
的指针添加字节,其中指出“上面所做的实际上是向指针添加大小*4字节,因为int是4字节。”
节点->指针的实际类型是什么?@EricPostpischil它是void*类型在Visual Studio中也可以。你是说它在一些奇怪的平台上是不兼容的吗?我的意思是C标准说它是不允许的。我还没有得到我的报价。一种是C11;还需要其他人。但是你不能确定一个不完整类型的大小,
void
无法完成,要增加一个指针,你需要知道字节大小,所以…正如我所说的,我还没有准备好所有相关的引号,我需要花一两个小时才能扩展我的答案-有一些“生命”这需要生活。对不起,我误解了你关于什么是标准和什么不是标准的回答,尽管它写得很清楚<代码>节点->指针=(字符*)节点->指针+大小在Visual Studio中工作,而不是其他。我已经添加了C标准中最相关的部分。既然有一种C标准的方法可以做到这一点,那么先给出答案不是更好吗?GCC扩展似乎没有增加多少价值。
#include <stdio.h>

struct node{
 int payload;
 void *ptr;
}*n;

void foo(int x){
 n->ptr = (char *)n->ptr +x;
}

int main(){
  n = malloc(sizeof(struct node));
  n->payload = 10; //random payload
  n->ptr = n;

  printf("%p\n", n->ptr);
  foo(2); //increment by 2
  printf("%p\n", n->ptr);
}