首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C语言中带有空指针的泛型编程

C语言中带有空指针的泛型编程
EN

Stack Overflow用户
提问于 2010-03-16 23:21:47
回答 6查看 12.5K关注 0票数 10

尽管可以用空指针(泛型指针)用C编写泛型代码,但我发现调试代码相当困难,因为空指针可以在没有编译器警告的情况下使用任何指针类型。(例如,函数foo()接受空指针,该指针应该是指向struct的指针,但如果传递了char数组,编译器不会报错。)在C中使用void指针时,你们都使用哪种方法/策略?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-03-16 23:28:36

解决方案是除非迫不得已,否则不要使用void*。实际需要空指针的地方非常小:线程函数的参数,以及需要通过泛型函数传递特定于实现的数据的少数其他地方。在任何情况下,接受void*参数的代码都应该只接受通过空指针传递的一种数据类型,并且该类型应该记录在注释中,并被所有调用者从属地遵守。

票数 10
EN

Stack Overflow用户

发布于 2010-03-16 23:28:13

这可能会有所帮助:

comp.lang.c FAQ list · Question 4.9

问:假设我想写一个函数,它接受一个泛型指针作为参数,并且我想模拟通过引用传递它。我可以给形参类型void **,然后这样做吗?

代码语言:javascript
运行
复制
void f(void **);
double *dp;
f((void **)&dp);

答:不是便携的。像这样的代码可能会工作,有时也是推荐的,但它依赖于具有相同内部表示的所有指针类型(这是常见的,但不是通用的;请参阅问题5.17)。

在C中没有泛型指针到指针类型。void *仅用作泛型指针,因为当其他指针类型被赋值到void *时,会自动应用转换(如果需要);如果尝试对指向void *以外的指针类型的void **值进行间接转换,则无法执行这些转换。当您使用void **指针值时(例如,当您使用*运算符访问void **指向的void *值时),编译器无法知道该void *值是否曾经从某个其他指针类型转换而来。它必须假设它只是一个void *;它不能执行任何隐式转换。

换句话说,您使用的任何void **值必须是某个实际void *值的地址;像(void **)&dp这样的强制转换,尽管它们可能会关闭编译器,但它们是不可移植的(甚至可能不会做您想做的事情;另请参阅问题13.9)。如果void **指向的指针不是void *,并且它的大小或表示形式与void *不同,那么编译器将无法正确访问它。

要使上面的代码片段工作,您必须使用一个中间void *变量:

代码语言:javascript
运行
复制
double *dp;
void *vp = dp;
f(&vp);
dp = vp;

对vp的赋值和来自vp的赋值使编译器有机会在必要时执行任何转换。

同样,到目前为止的讨论假设不同的指针类型可能有不同的大小或表示,这在今天很少见,但也不是闻所未闻。为了更清楚地理解void **的问题,可以将这种情况与类似的情况进行比较,例如,int和double类型,它们可能具有不同的大小,当然也具有不同的表示形式。如果我们有一个函数

代码语言:javascript
运行
复制
void incme(double *p)
{
    *p += 1;
}

然后我们可以做类似这样的事情

代码语言:javascript
运行
复制
int i = 1;
double d = i;
incme(&d);
i = d;

I将递增1。(这类似于包含辅助vp的正确void **代码)。另一方面,如果我们尝试像这样的东西

代码语言:javascript
运行
复制
int i = 1;
incme((double *)&i);    /* WRONG */

(此代码类似于问题中的片段),则它不太可能工作。

票数 4
EN

Stack Overflow用户

发布于 2012-07-31 13:40:22

Arya的解决方案可以稍微修改一下,以支持可变大小:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <string.h>

void swap(void *vp1,void *vp2,int size)
{
  char buf[size];
  memcpy(buf,vp1,size);
  memcpy(vp1,vp2,size);
  memcpy(vp2,buf,size);  //memcpy ->inbuilt function in std-c
}

int main()
{
  int array1[] = {1, 2, 3};
  int array2[] = {10, 20, 30};
  swap(array1, array2, 3 * sizeof(int));

  int i;
  printf("array1: ");
  for (i = 0; i < 3; i++)
    printf(" %d", array1[i]);
  printf("\n");

  printf("array2: ");
  for (i = 0; i < 3; i++)
    printf(" %d", array2[i]);
  printf("\n");

  return 0;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2455612

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档