在程序中,每一个变量都应该有相应的数据类型,数据的类型决定了编译器可以为之开辟多少的空间来存放数据。
例如:int 类型需要 4 个字节,char 类型需要 1 个字节,指针类型需要 4 个字节等等。
但 C 语言中还有一种特殊的数据类型——void。
void 表示为“无”、“空”、“没有”的意思。
在这里就把 void 理解为啥也不是。
作为一个数据类型,如果用 void 声明变量会是什么情况呢?
编译器要给数据分配多少的内存空间,是要依据变量定义时的数据类型。
而 void 类型比较特殊。虽然也是一种数据类型,但不确定性太强了。
如果可以用 void 声明变量,你要是开心先给个 int 整型的数据,不开心再给个 char 字符型的数据,或者 double 类型的数据。
这要求的内存空间一会儿大,一会儿小的,编译器也很难办。
内存就那么点,经不起这么折腾。
因此,void 数据类型是不能直接用在变量声明的。
那么 void 应该被用在哪里呢?
void 最常使用就是用在函数里面,第一个就是函数的参数。
通常会看到如下的函数原型定义:
int func(void);int func();
这两个函数表示的意义是一样的,都是无参数、返回值为 int 类型的函数。
但有一点不同。根据不同的编译器,对语法检验严格程度也有所不同。用 g++ 编译就有可能出现以下的情况:
int func1(void){ return 1;}int func2(){ return 2;}int main(){ func1(); func2(); func1(123); // error func2(123); func1(3.14); // error func2(3.14); return 0;}
参数部分为 void 的函数,在调用函数的时候,有传入实际参数的时候会产生报错,传入的参数太多了!实际上参数为 void 的函数是不能传入任何类型的参数。
而参数部分啥都没有的函数,调用函数的时候可以传入任意类型是不会报错的。
不过这个问题大体上没有人会这么做,因为毫无意义。
void 的另一个作用,就是在函数的返回类型上面。
有时候,我们只需要函数运行的过程,而不是为了获取最后的结果。此时就可以使用 void 类型,表示该函数没有返回值。
例如:我只想交换 a 和 b 两个变量分别存储的数据。
#include<stdio.h>void swap(int *a, int *b){ int temp; temp=*a, *a=*b, *b=temp;}int main(){ int a=3, b=5; swap(&a, &b); printf("a=%d, b=%d\n", a, b); return 0;}
运行结果:a=5,b=3
一般在 void 定义的函数里面,return 是多余的。不过,即便加上 return 返回值(gcc 6.3版本中),也对函数没有什么影响。
既无法重新使用其他数据类型定义的变量来接收函数的返回值,也不能在 printf 函数中使用的。
void * 指针表示为无类型指针,作为一个指针类型,编译器已经为其妥善安排了 4 个字节的小房间。
因此,void * 指针类型可以用来定义变量。
void *p;p = NULL;
void * 指针虽名为无类型指针,但可以指向任何一种类型的数据,即其他类型指针的指可以不通过强制转换直接赋给 void * 指针。
void *p;int *a;p = a;float *f;p = f;
在 C 语言当中,对指针类型的转换要求不是那么严苛,可以不通过强制转换就可以进行相互间的赋值。
int *a = NULL;float *b = NULL;char *c = NULL;a = b;b = c;c = a;
虽然编译器(gcc 6.3版本)不会显示有错误,编译照常会通过。只是会给出类似下面的警告:
警告 C4133 “=”: 从“float *”到“int *”的类型不兼容
而在 C++ 当中,这一点要求就明显比较严格了。它不允许两个不同的类型指针相互赋值,除了 void * 指针。
其他的类型指针可以把值直接赋给 void * 指针,但反过来,void * 指针的值想要赋值给其他类型的指针,也需要通过强制转换。
void *p = NULL;int *a = (int *)p; // 通过float *b = p; // 报错
void * 指针还有一个非常强大之处,在函数定义的时候,作为参数。当调用的时候,无论什么类型的类型指针或数组都可以正常运行。
#include<stdio.h>int test(void * dst){...}int main(){ char *c = "123456"; int arr[] = {1, 2, 3, 4, 5, 6}; test(c); // 正常编译 test(arr); // 正常编译 return 0;}
不过 void * 指针也有一个致命的缺点,当对该指针进行算数操作,就会显示以下这个错误。
根据 ANSI C 标准规定,进行算数操作的指针,必须明确知道该指针所指向的数据类型大小。也就是所指向的数据,都必须是具体的类型,而不是空泛的 void 类型。
关于 C 语言 void 数据类型的内容就到此结束了。
问:卡牌大师游戏闪退怎么解决?答:游戏闪退无非就是内存不足的问题,通常情况下,内存不足就会出现游戏闪退。这个时候将不用的程序清理掉,就可以玩了。当然也会出现因游戏文件包损坏,导致游戏闪退弹出。这种情况一般都是非法安装外挂和辅助造成的,所以建议大家不要用辅助等类型的第三方软件。以上就是常见的二种现象,
2024-11-22 10:29:28
炸麻叶儿是我们北方的传统特色小吃,小时候逢年过节、家家户户都会预备一些,焦香酥脆、越嚼越香,可是那时候最好的零食。现在生活条件好了,各式各样的零食应接不暇,眼看着这些传统的、经典的小吃逐渐淡出了大家的视野,着实觉得有些可惜。今天,我就把这款地道的、河南特有的、酥的直掉渣的炸麻叶做法,再给大家分享一遍
2024-11-22 09:35:04
最近发现,越来越多的人开始喜欢机械手表了。相比石英手表,机械手表虽然更贵,但是也更有质感和品味,也是不争的事实。相信很多越来越喜欢机械表的人都是认定了这个理儿。其实,我们常听说的一些大牌钟表,都是以机械手表见长,甚至有不少大牌手表都没有石英手表,比如朗格、宝玑等。论知名度和影响力,以下这些机械手表比
2024-11-22 09:19:48
用料青辣椒一根 红萝卜一根 生芒果一颗 盐渍话梅3粒切丝 日本话梅片6片切丝 备用 柠檬汁适量 矿泉水适量 少许盐 糖 太太乐鸡汁适量调一个咸鲜口 好了… 做法步骤1、买一个芒果准备学做牛肉芒果条菜的…2、切开一看 哇~生的 …3、只能改菜了 凉拌吧 红萝卜切丝 青椒切丝 盐渍话梅切丝(切出来成粒了
2024-11-22 09:04:05
传说东汉刘秀在未登大宝前有过一段很落魄的日子,亏得一位农村老汉割了一种野菜给刘秀充饥,刘秀吃后觉得甚是美味,便给野菜起了“救菜”的名字。此菜就是现在的韭菜,古语有云:“春初早韭,秋末晚菘”,意思是初春时刻,在经历过一个寒冬的缓慢生长后,是韭菜最为鲜嫩完美的一段时间,晚秋次之,夏天味道最差,所以各位碰
2024-11-22 08:49:26
今天来跟大家分享一个洋葱肉丸汤的做法,这样做出来的肉丸子非常好吃,比较鲜嫩,一点也不柴,爽滑可口,而且汤汁喝起来特别鲜美,光看着就让人特别有食欲,而且它的营养特别丰富。这道洋葱肉丸汤的做法是比较简单的,很容易就能够做出来,非常适合在夏天食用。如果家里有小朋友,那么经常给它吃这样的洋葱肉丸汤,可以起到
2024-11-22 08:34:03