关键词(四)
- 一.具有争议的关键词—goto
- 二.“空”的关键字—void
- 1.void为什么不能定义变量
- 2.void修饰函数返回值和参数
- 3.void指针
一.具有争议的关键词—goto
goto语句非常灵活,其实就是从goto这个位置直接跳转到goto后面的那个数据(end)所对应的位置,对中间的代码进行跳过,直接读取下面的代码(end下面)
当然我们也可以向上跳转
但注意这里会出现死循环,因为首先从1开始向后打印,遇到goto再返回end所标记的位置,再向下打印,又遇到goto,再返回end所标记的位置,这样一直循环打印1,2,3,4,2,3,4,2,3,4
goto语句的基本使用
ps:goto语句只能在本代码块内使用,不能跨函数和文件,总体来说goto语句的使用很简单,但想要灵活使用只有不断练习
为什么goto语句颇具争议呢?
所以的确很多公司禁用goto语句,但有人使用goto语句吗?
当然有,并且用的人很多,甚至在Linux内核源代码里就充满了大量goto语句
大量的goto语句,数以几十万个
只能说目前公司的业务没达到Linux那么复杂,所以还没必要使用goto语句
二.“空”的关键字—void
1.void为什么不能定义变量
首先void是一种类型,像int ,char,long等都可以用来定义变量,那么void可不可以呢?
很显然是不能的,那既然是一种类型为什么不能用来定义变量呢?首先我们来看看void在vs中是否开辟了空间
从这里可以看出void在VS里是没有开辟空间的,那就很好理解了,因为定义一个变量是需要空间的,但void没有空间,当然不能用来定义变量。
但注意以上情况是在VS里,如果是在Linux环境里,又有什么不同呢?
可以看到在Linux环境里,void的大小是一个字节,但它依然不能用来定义变量。
所以综上:void不能用来定义变量不仅是因为它的空间大小不确定,更是因为void本身就被编译器定义为空类型,强制的不允许定义变量。(这是编译器的规定)
其实void的作用是来告诉编译器我是空类型,用来充当一些特殊作用
2.void修饰函数返回值和参数
场景一:void作为返回类型
在c语言中,函数返回可以不带类型,默认返回类型是int
所以理论上如果你想返回int类型的话可以不用写返回类型,但这里很容易给人带来误解,你到底是忘了写返回类型?还是不想返回?还是想返回int类型?所以还是建议写上返回类型
如果你不想有返回值,那么用void修饰
加上void,如果你准备接收,那么void就不能够通过(当然如果你不接收还是能通过的)
从上可以看出,加上void的好处就是不仅能告诉别人这里是不需要返回值的,而且编译器不允许你将这个数据保存起来,方便你发现错误(强制要求要写)
场景二:void作为参数
如果我们给函数的参数里放上void,再传参,那么还能不能通过呢?答案是可以的,但会出现一个警告(在Linux里会直接报错)
如果参数里不加void,就不会出现这条警告
这条警告就说明编译器已经意识到你在进行一个错误的操作,可以对你进行提醒同时这个void也可以提醒别人这个函数不需要参数(不做强制要求)
3.void指针
上文说到void不能用来定义变量,那么void * 可不可以用来定义变量呢?
答案是可以的,这是因为指针本身就会开辟空间,不论是什么类型指针,在32位机器里都占4个字节,故可以用来定义变量(如果对指针还不了解可以看看这篇博客 什么是指针)
void * 的性质一
从以上代码中我们可以看到x,y是不同的类型,按理说不同的类型是不能直接赋值的,那我们这样写会不会报错呢?
答案是不会并且连警告都没有。故我们得出一个结论:void*类型可以被任何指针类型所接受
接下来我们反过来尝试,将不同类型指针赋值给void*类型
这里也不会出现任何问题,我们又可以得出一个结论:void*可以接收任何指针类型(常用)
至此,总结一下:void*既可以赋值给任意指针类型,也可以接收任何指针类型
void性质二
在指针变量中我们是可以直接对变量进行++或者–操作的
那么void*类型可不可以这样直接对变量进行操作呢?
答案是不行的(在VS中),为什么呢?因为对变量操作本质上是跳过指针的类型大小,例如int*p中,p++就是跳过一个整形(4个字节),而前文说到,void是没有开辟空间的,那么x++相当于跳过了0个字节,这样是毫无意义的,所以编译器报错
但注意前文我们说到,在Linux环境下void是一个字节,那么可不可以对void*x进行操作呢?答案是可以的。因为在Linux环境下void的大小是1个字节,那么x++就相当于跳过一个字节是有意义的,故可以通过
这里得出结论:在VS下,不能对空类型的变量进行直接操作;在Linux环境下可以对空类型的变量进行操作
为什么在VS和Linux下void的类型不同呢?
根本原因就是采用的c标准不同
性质三:void * 能直接解引用吗
答案是不行的。因为解引用(*x)对于的是指针所指向的类型,所以 *x所对应的类型是void,而在VS中,void是没有空间的,所以我们无法用void来解释这一段数据
在Linux环境里也不能解引用,虽然在Linux中void有一个字节,但前面我们说过void是不能用来定义变量的,而解引用后*x对应的类型就是void,发生矛盾
得出结论:在c语言中不能对void*进行解引用