关于 void * 的问题,恳请各位高手指点

新加坡下雨了 2011-08-27 05:18:19

情况一:

// 在数组赋值的时候,我才用循环赋0的方法,给数组赋值,这是赋值的函数
// 其中pArray是要被赋值为0的数组地址,可以是U8,U16,U32或者S8的,所以我用了void *
void ArrayeEvaluate( void * pArray, U8 length)
{
U8 i;
for( i = 0; i < length; i ++)
{
* pArray ++ = 0; // 这一行提示 'const void *' : unknown size
}
}


// 事先已经定义了数组
union
{
U8 State1[ 12 ];
U16 State2[ 13 ];
U32 State3[ 14 ];
S8 State4[ 15 ];
} EDID;

// 调用上面函数的格式为:

ArrayeEvaluate( EDID.State1, 12 );

提示:'const void *' : unknown size,我知道是因为void *不能确定长度,但是我想知道一下,每次调用的长度都不是确定的,怎么能让程序自己知道哪次是U8哪次是U16哪次是U32???

情况二:

还有的地方提示:illegal indirection

提示illegal indirection的时候,通常是如下的情况:

void ArrayeEvaluate( void * pArray, U8 length)
{
* ChooseNumber = 0; // 提示illegal indirection
for( i = 0; i < 8; i ++ )
{
* ChooseNumber |= 1 << ( tempChoose & 0x0000000f ); // 提示illegal indirection
tempChoose >>= 4;
}
* ChooseNumber >>= 1; // 提示illegal indirection
}



以上两种情况,恳请各位指点迷津啊,我是真的没有办法了,说得越详细越好啊
...全文
197 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
AnYidan 2011-08-28
  • 打赏
  • 举报
回复
为何 void * 指针类型可以供转换成任何类型的指针 -- 因为在一个系统中任何类型指针的长度都相同,可以表示其所有的内存空间地址

为何void * 指针类型不可以 dereference -- 因为多字节变量的地址是地址值最小的那个,而不同类型的变量的长度很可能不同,(指针的类型实际上是指针指向的变量的类型),你不告诉 compiler 指针类型就 dereference,compiler 不知道从指针指向的地址处向后延伸多长是你想要的 data
黑娃 2011-08-27
  • 打赏
  • 举报
回复
按照您的这个思路是不能直接判断void*的具体长度的,由于只有你调用该函数时才知道其类型长度,建议您直接用memset进行设置。如果非要在这个函数里面去判定它的长度,你可以再设定一个标志变量来指示,可是那样显得没必要了
gykgod 2011-08-27
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 luuillu 的回复:]

看来楼主想用C实现泛型的函数。
要是使用c++直接用模板就可以实现了。而c语言不支持泛型编程。有两种解决方案:
一种方案是直接使用memset:
把ArrayeEvaluate( EDID.State1, 12 );
改成 memset(EDID.State1, 0, 12*sizeof((EDID.State1)[0]))


另一种方案是使用宏。
在C语言中用宏勉强可以实现部……
[/Quote]

您总是那么高效 给力 膜拜~
AndyZhang 2011-08-27
  • 打赏
  • 举报
回复
就是为了让你以后强制转换一下就可以用,开始不知道是什么类型的
tyr 2011-08-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 singaporeraining 的回复:]
引用 4 楼 luciferisnotsatan 的回复:
void*可以指向任何类型,但不能解引用。在加个参数,说明类型不就行了


不能解引用,是指这个指针指的数据,不能运算?
另外,将void * p 强制转换后,可以给 * p 赋值么?
[/Quote]

你就当空指针是一个不能解除引用的纯地址吧。
强制转换后是一个新的指针,不是空指针本身了。
luuillu 2011-08-27
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 luuillu 的回复:]


另一种方案是使用宏。
在C语言中用宏勉强可以实现部分……
[/Quote]
修改一下,第五行少写一个斜杠。

#define ArrayeEvaluate(pArray, length) \
{\
unsigned i; \
for( i = 0; i < length; i ++) \
{\
pArray[i]= 0; \
} \
}

luuillu 2011-08-27
  • 打赏
  • 举报
回复
看来楼主想用C实现泛型的函数。
要是使用c++直接用模板就可以实现了。而c语言不支持泛型编程。有两种解决方案:
一种方案是直接使用memset:
把ArrayeEvaluate( EDID.State1, 12 );
改成 memset(EDID.State1, 0, 12*sizeof((EDID.State1)[0]))


另一种方案是使用宏。
在C语言中用宏勉强可以实现部分泛型效果。

可以这样实现ArrayeEvaluate

#define ArrayeEvaluate(pArray, length) \
{\
unsigned i; \
for( i = 0; i < length; i ++) \
{
pArray[i]= 0; \
} \
}



新加坡下雨了 2011-08-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 luciferisnotsatan 的回复:]
void*可以指向任何类型,但不能解引用。在加个参数,说明类型不就行了
[/Quote]

不能解引用,是指这个指针指的数据,不能运算?
另外,将void * p 强制转换后,可以给 * p 赋值么?
luciferisnotsatan 2011-08-27
  • 打赏
  • 举报
回复
void*可以指向任何类型,但不能解引用。在加个参数,说明类型不就行了
仙度瑞城 2011-08-27
  • 打赏
  • 举报
回复
void*是可以指向任何类型的指针
新加坡下雨了 2011-08-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 bdmh 的回复:]
void是无类型的,不知道给他加多少字节地址,你可以把地址转为int,然后加上一个偏移,再把这个新数值转为void*
[/Quote]

可是如果传递过来的地址指针是U8或者long int形式的。转换成int不就有误了么?我就是这个地方弄不明白,怎么办怎么办怎么办?
bdmh 2011-08-27
  • 打赏
  • 举报
回复
void是无类型的,不知道给他加多少字节地址,你可以把地址转为int,然后加上一个偏移,再把这个新数值转为void*

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧