编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

软件和网站开发以及相关技术探讨
回复
bearboy1016
帖子: 10
注册时间: 2013-03-19 22:34
系统: linux

编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#1

帖子 bearboy1016 » 2013-03-25 23:14

代码: 全选

void swap(void **p1,void **p2)
{
	void *pt=*p1;
	*p1=*p2;
	*p2=pt;
}
这是将两个指针所指向的地址互换。但有警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?
感觉任何类型都可以传给void才对。这是为什么?
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#2

帖子 cuihao » 2013-03-25 23:32

能接受所有指针的是 void *,不是 void **。
void ** 是指向 void * 类型的指针,是有类型的指针,不是无类型的指针。

你可以忽略warning,也可以这么写:

代码: 全选

void swap(void *pa,void *pb)
{
    void **p1=pa, **p2=pb, *pt;
    pt=*p1;
    *p1=*p2;
    *p2=pt;
}
有些变量是多余的,但为了看清楚,就这么写了。

唔,不怎么写代码,不知道有没错误,反正LZ知道意思就行了……
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#3

帖子 eexpress » 2013-03-26 9:17

强制转换就是。
● 鸣学
bearboy1016
帖子: 10
注册时间: 2013-03-19 22:34
系统: linux

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#4

帖子 bearboy1016 » 2013-03-26 9:34

cuihao 写了:能接受所有指针的是 void *,不是 void **。
void ** 是指向 void * 类型的指针,是有类型的指针,不是无类型的指针。

你可以忽略warning,也可以这么写:

代码: 全选

void swap(void *pa,void *pb)
{
    void **p1=pa, **p2=pb, *pt;
    pt=*p1;
    *p1=*p2;
    *p2=pt;
}
有些变量是多余的,但为了看清楚,就这么写了。

唔,不怎么写代码,不知道有没错误,反正LZ知道意思就行了……
又是你呀,太感谢了。真是热心好人士啊~
按照你的意思,也就是说void**用于指向void*,而void*和char*一样都属于有类型的指针变量。只有void*才能接受所有类型的变量。
那么有没有一种指针,可以指向所有类型的指针呢?可以接受所有类型的指针的地址。
因为将指针作为“变元“(书上是这么称呼实参的。。)传递给一个函数,这个时候要想改变被传递指针所指向的内容,必须要将这个指针的地址传给他。直接传递这个指针好像没用,因为这样只是传递了这个指针所指向的地址,而不是这个指针变量本身的地址。所以在你给出的方案里面,我如果调用函数swap(p3,p4),这样只是将p3,p4内所存的地址(即所指向的变量的地址)传给了函数里的指针pa和pb,然后运行函数对pa和pb进行改变,都只是对改变pa和pb内所存的地址,而没有改变p3和p4呀。
我试了一下,确实不行呀。其中应该该一下:void** p1=&pa,**p2=&pb;
不过真的十分感谢你。
bearboy1016
帖子: 10
注册时间: 2013-03-19 22:34
系统: linux

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#5

帖子 bearboy1016 » 2013-03-26 9:48

eexpress 写了:强制转换就是。
将要代入的变量都转换为void** 类型的吗?我试了一下好像可以。
(void**)&p1(p1为指向char的指针)。地址还可以强制转换啊。。。看来地址也分类型,不知到(void*)&x(x为char类型的变量)行不行。
十分感谢你!
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#6

帖子 cuihao » 2013-03-26 18:18

我那个写法应该是没错的,或者至少不是LZ指出的这个错误。

LZ应该还有一点没转过来。我的原型是 void swap(void *pa,void *pb),接受的参数是指针,但不代表要用指针原型来调用。因为函数要修改指针,应该用 swap(&p3,&p4) 这样调用。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
bearboy1016
帖子: 10
注册时间: 2013-03-19 22:34
系统: linux

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#7

帖子 bearboy1016 » 2013-03-26 20:36

cuihao 写了:我那个写法应该是没错的,或者至少不是LZ指出的这个错误。

LZ应该还有一点没转过来。我的原型是 void swap(void *pa,void *pb),接受的参数是指针,但不代表要用指针原型来调用。因为函数要修改指针,应该用 swap(&p3,&p4) 这样调用。
感谢你,我按照你说的做了,确实可以。
书上说要用指向指针的指针才能存储指针本身的地址。&p3的话,应该是对应char**的指针,我试了一下,char*也不能接受&p3,但是void*可以。难道void*可以接受所有类型变量的地址吗?包括那种char**,void**?
就像我之前说的,初学者,难免会搞错,见谅!呵呵
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#8

帖子 cuihao » 2013-03-26 20:57

void* 就是可以存储所有指针的通用指针,包括普通的指针(int*)、指向指针的指针(int**)、指向指针的指针的指针(int***)……
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
bearboy1016
帖子: 10
注册时间: 2013-03-19 22:34
系统: linux

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#9

帖子 bearboy1016 » 2013-03-26 21:03

cuihao 写了:我那个写法应该是没错的,或者至少不是LZ指出的这个错误。

LZ应该还有一点没转过来。我的原型是 void swap(void *pa,void *pb),接受的参数是指针,但不代表要用指针原型来调用。因为函数要修改指针,应该用 swap(&p3,&p4) 这样调用。
还有一点,就是,将char**的数据传递给void*的时候,比如pa=&p3,这个时候*pa好像就不是代表p3,也就是说void*可以存储char**的值,但不能引用char**所指向的指针是吗?
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#10

帖子 cuihao » 2013-03-26 21:36

void*没有指明指向的数据类型,不能取值,必须得重新转换回去才行。

代码: 全选

*(char**)pa
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
bearboy1016
帖子: 10
注册时间: 2013-03-19 22:34
系统: linux

Re: 编译警告:需要类型 ‘void**’,但实参的类型为 ‘char**'?

#11

帖子 bearboy1016 » 2013-03-26 21:52

cuihao 写了:void*没有指明指向的数据类型,不能取值,必须得重新转换回去才行。

代码: 全选

*(char**)pa
好的,非常感谢你,我会好好总结思考。这个东西还是要多练练。
回复