提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:以下是本篇文章正文内容,下面案例可供参考
一、void是否可以定义变量?为什么?
1.void是否可以定义变量
代码如下(示例):
#include <stdio.h>
#include <windows.h>
int main()
{
void a;
system("pause");
return 0;
}
在vs2022和gcc4.8.5下不能编译通过
2.为什么void不能定义变量
定义变量的本质:开辟空间
而void作为空类型,理论上是不应该开辟空间的,即使开了空间,也仅仅作为一个占位符看待
在vs2022中,sizeof(void)=0
在Linux中,sizeof(void)=1(但编译器依旧理解成,无法定义变量)
所以,既然无法开辟空间,那么也就无法作为正常变量使用,既然无法使用,编译器干脆不让他定义变量。
二、void修饰函数的返回值和参数
1.void用来作为函数返回值
代码示例1:
#include <stdio.h>
#include <windows.h>
void show()
{
printf("no return value!\n");
}
int main()
{
show();
system("pause");
return 0;
}
输出结果:
代码示例2:
直接返回return 1也是可以通过编译的,且不会有警告
但如果有变量去接收则会报错![](https://i-blog.csdnimg.cn/blog_migrate/86c83fdafdacc7a3495daf6b9328fd58.png)
结论:void作为函数返回值,代表不需要,这里是一个"占位符"的概念,是告知编译器和给阅读源代码的工程师看的。
2.void作为函数参数
//如果一个函数没有参数,我们可以不写, 如test1()
#include <stdio.h>
#include <windows.h>
int test1() //函数默认不需要参数
{
return 1;
}
int test2(void) //明确函数不需要参数
{
return 1;
}
int main()
{
printf("%d\n", test1(10)); //依旧传入参数,编译器不会告警或者报错
printf("%d\n", test2(10)); //依旧传入参数,编译器会告警(vs)或者报错(gcc)
system("pause");
return 0;
}
结论:如果一个函数没有参数,将参数列表设置成void,是一个不错的习惯,因为可以将错误明确提前发现,另外阅读你代码的人,也一眼看出,不需要参数,相当于“自解释” 。
三.void指针
#include <stdio.h>
#include <windows.h>
int main()
{
void *p = NULL; //可以
system("pause");
return 0;
}
void不可以定义变量,为什么void*可以呢?
因为void*是指针,是指针,空间大小就能明确出来(32位系统为4个字节,64位为8个字节)
注意:
1.void*能够接受任意指针类型
2.void*可以被任何指针接受
3.void*定义的的指针变量不可以进行运算操作
vs2022中,sizeof(void)为0个字节
#include <stdio.h>
#include <windows.h>
int main()
{
void *p = NULL;
p++; //报错
p += 1; //报错
system("pause");
return 0;
}
而在gcc 4.8.5中是能通过编译运行的,因为在gcc 4.8.5中sizeof(void)为1个字节
但原因是因为使用的C标准扩展的问题