请问这个指针为什么这么定义?

#defineAEEGETPVTBL(p,iname)(*((AEEVTBL(iname)**)((void*)p)))这个为什么把p变为二级指针又变回一级指针,它跟下面... #define AEEGETPVTBL(p,iname) (*((AEEVTBL(iname) **)((void *)p)))
这个为什么把p变为二级指针又变回一级指针,它跟下面的有区别吗?
#define AEEGETPVTBL(p,iname) (((AEEVTBL(iname) *)((void *)p)))

还有在程序中经常有这样的强制转换:(TypeName*)(void*)p
为什么中间要有一个void先转换一下?
请问无论二级还是多级指针都可以转化为void *类型吗?
展开
 我来答
百度网友fefbf9e
2011-04-30 · TA获得超过1364个赞
知道小有建树答主
回答量:176
采纳率:0%
帮助的人:106万
展开全部
区别大着呢
首先,你必须搞明白这个宏是做什么用的,我给你详细讲一下:

1) 最外层的*,说明这是一个取“指针指向地址内容”的操作,比如int a; int *p=&a; int c=*p;最后一句*p就是取p所指向地址的内容,这里p指向a(p存了a的地址)。先不管那一堆括号,可以这样缩写来看,#define AEEGETPVTBL(p,iname) (*((暂时忽略)p)),也就是取出p的内容,至于p的类型,下面说明。从这个意义上来说,你给的另一个写法完全是另一回事,#define AEEGETPVTBL(p,iname) ((((暂时忽略)p))),它返回的是p本身,而不是其内容
1补充) 我假定你明白这样的宏代表什么意思,简单理解就是类似于定义一种函数,只不过在编译阶段特殊处理
类似例子:
int a;
int *p = &a;
int **pp = &p;
*((int **)(void* pp));//正确
(int *)(void* pp);//有问题

2) 我们再来看忽略的部分:((AEEVTBL(iname) **)((void *)p))
AEEVTBL(iname):
其原型为#define AEEVTBL(iname) iname##Vtbl,就是返回一个源代码字符串(注意不是"abcd"这样的字符串),比如这样的代码AEEVTBL(haha) i;相当于hahaVtbl i;它把iname当作一种可变字符串和Vtbl连接起来,这样你就可以用编译期可变的类型来写代码了(不理解也没关系,就是返回一种类型)
那么也就是说这里代表一种类型,和iname有关,为了理解,我们假定为type
(void *)p:
很简单,把p转换为void*类型,这是一种不带类型信息的指针,我们假定为vp

((AEEVTBL(iname) **)((void *)p)) 化简为 ((type **)vp)
#define AEEGETPVTBL(p,iname) (*((AEEVTBL(iname) **)((void *)p)))化简为#define AEEGETPVTBL(p,iname) (*((type **)vp))
串起来就是,先把p强制转换为void*,然后再强制转换为type**,最后取出其地址内容,而你的另一个不是这样的

最后,解释一下void转换问题
任何类型的指针,包括0,都可以隐式的转换为void*,隐式的意思就是说,有这么个函数void f(void*),你传入任何类型的指针都是可以的,编译器会自动帮你先转为void*。在你的代码里,如果去掉void*,也不会出错,因为强制转换(TypeName*)p就好比那个接受void*的函数,会进行隐式转换。但是为什么这样写呢?一般说来,编译器背地里做的事可能会带来某些未知的影响,而且也不便于代码阅读,这样写是一种好的代码习惯。
追问
谢谢了!您解释的好详细啊,请问无论二级还是多级指针都可以转化为void *类型吗?在vc里语法上没有报错
另外这个程序为什么还是返回地址,而不是一个ASC码值呢
#include
main()
{
char a='c';
char *pchar = &a;
char **ppchar = &pchar;
int *i = *((int **)(void *)ppchar);
printf("%d\n",*i);
}
追答
1. 指针也是一种变量,只不过它专门存储内存地址,具有固定长度,一般为32位或者64位,无论一级还是多级指针都是这样。而void*是一种特殊的指针,任何指针类型都可以转换为void*,无论几级的。

2. 要用printf输出十六进制数字,要用%x或者%X或者%p
大雅新科技有限公司
2024-11-19 广告
这方面更多更全面的信息其实可以找下大雅新。深圳市大雅新科技有限公司从事KVM延长器,DVI延长器,USB延长器,键盘鼠标延长器,双绞线视频传输器,VGA视频双绞线传输器,VGA延长器,VGA视频延长器,DVI KVM 切换器等,优质供应商,... 点击进入详情页
本回答由大雅新科技有限公司提供
wskjuf
2011-04-29 · TA获得超过1289个赞
知道大有可为答主
回答量:1731
采纳率:0%
帮助的人:1790万
展开全部
这些宏应该跟虚函数表有关,以前在windows的某些头文件中见过类似的这些东西。可能《COM本质论》或《COM 技术内幕——微软组件对象模型》里,或者是一些atl书籍提到过这些类似的宏,记不清了。

楼主一定要看到实际的代码,否则这些东西是很难正确理解的。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
阳光xl不锈
2011-04-29 · TA获得超过194个赞
知道答主
回答量:94
采纳率:0%
帮助的人:74.2万
展开全部
有区别,第一个是代表变量,第二个代表变量的地址
void 表示无返回值,就是说这个指针不可以作为返回值类型,只能作为局部变量
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式