10.4 void和void*的区别

虽然在代码中经常见到的void和void*,但是可能不少初学者对它们并不是很了解,接下来看看它们适用于哪些情况。首先来看void,void使用最多的场景是设置函数的返回值类型,如:


include<stdio.h>

void print()

{

printf("Hello World\n");

return;

}

int main()

{

print();

return 0;

}


运行结果:


Hello World


分析上面的代码,print函数的返回值类型为void,意味着其没有返回值,需要注意的是,如果没有对函数的返回值声明任何的类型,那么默认返回值为int型,并不是void类型。看看下面的代码。


include<stdio.h>

include<stdlib.h>

sum(int a[],int n)

{

int i,sm;sm=0;

for(i=0;i<n;i++)

sm+=a[i];

return sm;

}

int main(void)

{

int a[4]={1,2,3,4};

printf("%d\n",sum(a,4));

return 0;

}


运行结果:


10


void也可以作为函数的参数,如果参数没有返回值,那么可以用void来表示,如:


include<stdio.h>

int main(void)

{

printf("Hello World\n");

return 0;

}


运行结果:


Hello World


分析上面的运行结果,因为main函数没有携带任何参数,所以将其参数设置为void,表示其没有传递任何参数信息。

切记不要用void来定义参数,如:


void n;


以上定义在编译时会出现“error C2182:'n':illegal use of type'void'”错误,由此可以看出,void的用途也就体现在两个方面:一是限定函数的返回值,二是限定函数的参数。

接下来介绍void的使用。void同样可以用来限定函数的返回值和参数,而且可以用来定义变量,但是切记不可将其理解为指向void类型的指针。看看下面的代码。


include<stdio.h>

int main()

{

void*n;

printf("void*类型的指针定义成功\n");

return 0;

}


运行结果:


void*类型的指针定义成功


分析上面的运行结果,我们成功地定义了void*类型的指针,该指针并不是某些初学者所理解的空指针,而是一种特殊类型的指针,与之前定义的确定类型指针的不同之处在于,该指针是一种可以指向任意类型的指针,因此称作万能指针。看看下面的代码。


include<stdio.h>

int main()

{

void*n;

int a=0;

int*p;

char c='A';

p=&a;

printf("p=%d,p=%d\n",p,p);

n=p;

printf("n=%d,n=%d\n",n,(int*)n);

char*pc;

pc=&c;

printf("pc=%d,pc=%d\n",pc,pc);

n=pc;

printf("n=%d,n=%d\n",n,(char*)n);

return 0;

}


运行结果:


p=1245048,*p=0

n=1245048,*n=0

pc=1245040,*pc=65

n=1245040,*n=65


分析上面的代码,我们定义了可指向任何类型的指针n,首先将该指针指向int型变量,然后将该指针指向char类型的变量,由此可以看出,void定义的指针类型的确是一种可指向任何类型的指针,没有固定的指向。正是因为void类型的指针没有固定类型,所以不可以对void类型的指针进行自加或者自减运算,如:


include<stdio.h>

int main()

{

void*n;

int a=9;

int*pa;

pa=&a;

printf("pa=%d\tpa=%d",pa,pa);

pa++;

printf("pa++=%d",pa);

//printf("%d",n++);

return 0;

}


运行结果:


pa=1245048*pa=9

pa++=1245052


分析上面的代码,我们对整型指针pa做了自加运算,同时在代码中还有一句打印语句,用于实现对void类型的指针进行自加运算。但是打印语句被注释掉了,如果没有注释掉,那么编译的时候就会出现如下错误:


error C2036:'void*':unknown size


所以在使用void类型的指针时需要注意,由于其所指向的类型是不确定的,因此不可对其进行自加或者自减运算。