CC++语言中void及void指针的深层探索
c语言中void函数的用法
C语言中void函数的用法1.什么是v oid函数在C语言中,vo id是一种特殊的数据类型,代表无类型。
vo i d函数是一种特殊的函数,它不返回任何值。
通常,在程序中我们会定义一些函数来完成某些具体的功能,而vo id函数就是其中的一种类型。
2. vo id函数的定义和声明定义vo id函数非常简单,只需要在函数名称前面加上关键字v oi d即可。
例如:v o id pr in tH el lo(){p r in tf("He ll oW orl d!\n");}在上面的例子中,我们定义了一个名为pr i nt He ll o的vo id函数,它没有任何参数,并且在函数体中输出了"H el lo Wo rl d!"。
3. vo id函数的调用调用v oi d函数也很简单,只需要在函数名称后面加上一对括号即可。
例如,要调用上面定义的pr in tH el lo函数,可以这样写:p r in tH el lo();4. vo id函数的参数虽然vo id函数不返回任何值,但是它可以接受参数。
通过在函数定义和声明时,括号内写上参数列表即可。
例如,我们定义一个名为su m的v oi d函数,用于计算两个整数的和:v o id su m(in ta,i ntb){i n tr es ul t=a+b;p r in tf("Th es um is:%d\n",r es ul t);}在上面的例子中,su m函数接受两个整数参数a和b,并在函数体中计算它们的和并输出。
5. vo id函数的特点-不返回任何值:与其他类型的函数不同,v oi d函数没有返回值,它的作用主要是完成一些操作或执行一些任务。
-可以有参数:虽然不返回任何值,但vo i d函数可以接受参数,在函数体内进行一些操作。
-可以调用其他函数:在vo id函数内部,可以调用其他函数,这样可以实现更复杂的功能。
浅谈void及void指针
浅谈void及void指针在编程的过程中,大家都很熟悉void,但是对于void指针恐怕就没有那么熟悉吧,今天我在这里进行一些浅谈,希望对各位朋友有一定的帮助。
首先我们要知道数据类型,什么是数据类型,可以理解为一种数据的结构,每种数据类型都有相应的数据结构,既然是结构那么就有相应的结构信息,包括在内存中占有多少字节等等的东西。
内存是连续的,我们通常都说电脑的内存是2G,那么内存是在电脑出厂或者内存条出厂的时候就制定了每一个内存单元的标识的,内存是由内存单元组成的,一个内存单元我们通常是用一个字节来描述的,内存单元是由电荷位组成的,也就是说一个内存单元是由8个电位组成的,不要问我为什么是8个,我也不知道,呵呵。
好了,知道了内存单元,那么我们就能够知道数据类型的具体东西了,通常我们说一个int类型的变量占有4个字节,也就是说我们定义了一个变量那么它在内存里面是占有连续的4个字节。
好了,终于到了主题,那么void是什么数据类型呢,我的理解为未知的数据类型,这里的未知是指不知道在内存中占有多少字节,因此编译器在编译的过程中也就不能为其分配内存,所以我们就不能定义void类型的变量,那么void 指针又是怎么回事呢?首先明白,指针是存放对象地址(当对象占有多个字节的时候,存放的是第一个字节的地址)对象,而CPU就根据这个指针对象所存放的地址去进行一些操作,由于CPU是32位的,也就是我们通常说的32位机,那么CPU的寻址范围就是2的32次方,也就是4G的地址空间,而内存又只有2G,所以为了不浪费CPU的寻址能力,操作系统就提供了一种虚拟内存。
(扯远了)好了,CPU能够寻找2的32次方的地址空间,而一个字节只有8位,那么4个字节刚好能够把CPU所有的寻址空间都能够表述出来,因此所有的指针都是4个字节。
那么为什么我们平时还在定义不同数据类型的指针呢,可以直接定义一个数据指针就解决了我所有问题啊!你很聪明,不过设计C++语言的人比我们更聪明,如果我们都用一种数据类型来表示我们的地址,那么当一个int类型的变量的第一个字节的地址被保存到指针变量中的时候和一个char类型的变量的地址被保存到指针变量中的时候我们怎么知道是char类型的地址还是int类型的地址呢,因此指针变量包含了一个信息就是这个变量描述的地址应该是几个字节连续的,比如说我们定义了一个int类型的指针,那么指针变量知道这个地址是后面三个字节都是连续的,因此不能分开,是一个整体。
void指针的背后藏着什么?
void指针的背后藏着什么?1. 不能动的“地址”之 void指针1.1 void指针初探void *表示一个“不知道类型”的指针,也就不知道从这个指针地址开始多少字节为一个数据。
和用int表示指针异曲同工,只是更明确是“指针”。
因此void *只能表示一个地址,不能用来&取值,也不能++和--移动指针,因此不知道多少字节是一个数据单位。
int nums[] = {3,5,6,7,9};void* ptr1 = nums;//int i = *ptr1; // 对于void指针没法直接取值int* ptr2 = (int*)nums;printf('%d,%d\n',ptr1,ptr2);int i = *ptr2;printf('%d\n',i);从输出结果可以看出,无论是无类型的void指针还是int类型指针,指向的地址都是一样的:PS:void *就是一个不能动的“地址”,在进行&、移动指针之前必须转型为类型指针。
1.2 void指针的用途这里我们看一下我们之前了解的memset函数,其第一个参数就是一个void指针,它可以帮我们屏蔽各种不同类型指针的差异。
如下面代码所示,我们既可以传入一个int类型数组的指针,也可以传入一个char类型数组的指针:int nums[20];memset(nums,0,sizeof(nums));char chs[2];memset(chs,0,sizeof(chs));那么,我们也可以试着自己动手模拟一下这个memset函数,暂且命名为mymemset吧:void mymemset(void *data,int num,int byteSize){// char就是一个字节,而计算机中是以字节为单位存储的char *ptr = (char*)data;int i;for(i=0;i<byteSize;i++){*ptr=num;ptr++;}}int main(int argc, char *argv[]){int nums[20];mymemset(nums,0,sizeof(nums));int i,len=sizeof(nums)/sizeof(int);for(i=0;i<len;i++){printf('%d ',nums[i]);}printf('\n');return 0;}在这个mymemset函数中,我们利用void指针接收不同类型的指针,利用char类型(一个字节)逐个字节读取内存中的每一个字节,最后依次填充指定的数字。
C语言指针详细讲解
类型转换错误
01 总结词
类型转换错误是指试图将一个类型的指针 转换为另一个类型,导致程序崩溃或未定 义行为。
02 详细描述
类型转换错误通常发生在以下情况
03
1. 强制类型转换
04
强制类型转换是一种不安全的操作,它可能 会导致内存访问错误或程序崩溃。例如,将 一个int类型的指针强制转换为char类型的 指针,然后试图访问该地址,可能会导致程 序崩溃。
指向void的指针的使用
01
什么是指向void的指针
指向void的指针是一个特殊类型的指针,它可以指向任何类型的数据,
但是不能直接对其进行操作。
02
为何使用指向void的指针
使用指向void的指针可以在不知道指针所指向的数据类型的情况下,传
递数据或函数的参数。
03
如何使用指向void的指针
在C语言中,可以使用void关键字定义一个指向void的指针。例如:
3
在C语言中,指针变量通常用"*"表示其类型。
指针的类型
指针的类型取决于它所指向的变量的类型。 如果指针指向一个浮点数,则该指针的类型为float *。
如果指针指向一个整数,则该指针的类型为int *。 如果指针指向一个字符,则该指针的类型为char *。
指针的变量
指针变量可以声明为任何类型,包括int 、float、char等。
c语言指针详细讲解
汇报人: 日期:
目 录
• c语言指针基本概念 • c语言指针的运算 • c语言指针与数组 • c语言指针与函数 • c语言指针的使用技巧与注意事项 • c语言指针常见错误分析
01
c语言指针基本概念
指针的定义
void c语言
void c语言
Void是C语言中的一种特殊的数据类型,代表没有值。
它通常用在函数的返回值类型中,表示该函数没有返回值。
例如,下面的函数就是一个没有返回值的函数:
void printHello() {
printf('Hello
');
}
在这个函数中,我们使用了void作为返回值类型,表示该函数不需要返回任何值。
除了作为函数返回值类型外,void还可以用来定义指针类型。
如果我们定义一个void指针:
void *ptr;
那么这个指针可以指向任意类型的数据,因为它没有指定具体的数据类型。
在使用void指针时,我们通常需要将它强制转换为其他指针类型,以便进行正确的操作。
除了这些用法之外,void还可以用在其他一些场合,例如在函数参数表中,表示该参数不需要传递任何数据。
总的来说,void是C 语言中非常重要的一个关键字,我们需要充分理解其各种用法,以便正确地应用它。
- 1 -。
C语言指针的奥秘
C语言指针的奥秘 Document number【SA80SAB-SAA9SYT-SAATC-SA6UT-SA18】让你不再害怕指针前言:复杂类型说明要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧:intp;以P是一个返回整型数据的指针intp[3];以P是一个指向由整型数据组成的数组的指针int**p;于二级指针以及更高级的指针极少用在复杂的类型中,所以后面更复杂的类型我们就不考虑多级指针了,最多只考虑一级指针.intp(int);以P是一个参数为一个整数据且返回一个指向由整型指针变量组成的数组的指针变量的函数.说到这里也就差不多了,我们的任务也就这么多,理解了这几个类型,其它的类型对我们来说也是小菜了,不过我们一般不会用太复杂的类型,那样会大大减小程序的可读性,请慎用,这上面的几种类型已经足够我们用了.1、细说指针指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
要搞清一个指针需要搞清指针的四方面的内容:指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。
让我们分别说明。
先声明几个指针放着做例子:例一:(1)int*ptr;(2)char*ptr;(3)int**ptr;(4)int(*ptr)[3];(5)int*(*ptr)[4];1.指针的类型从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。
这是指针本身所具有的类型。
让我们看看例一中各个指针的类型:(1)int*ptr;针所指向的类型当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
在c语言中void的作用
在c语言中void的作用在C语言中,void是一个关键字,用来表示一个函数没有返回值或一个指针没有特定类型的指针。
void的作用主要有以下几个方面:1.函数返回值为空:void可以用来表示一个函数没有返回值。
在C语言中,函数可以返回各种类型的值,如整数、浮点数、字符等。
但是有些函数仅仅是用来执行一系列操作,而不需要返回任何值。
比如,当我们需要打印一些信息或执行一些操作时,可以将函数的返回类型声明为void。
例如:```void printMessageprintf("Hello, World!\n");```在上面的例子中,printMessage(函数不需要返回任何值,它仅仅打印一条消息。
使用void作为返回类型可以明确表明这一点。
2.函数参数为空:在C语言中,函数可以有参数,用来接收传递给函数的值。
有时候我们需要定义一个函数,不需要任何参数。
这时我们可以使用void来表示函数没有参数。
例如:```int getRandomNumber(void)return rand(;```在函数定义中,使用void关键字表示函数没有参数,即不接收任何值。
3.指针类型未知:void可以用来声明一个指针,而不指定具体的数据类型。
这在涉及多种数据类型的程序中非常有用。
例如,在编写通用内存分配函数时,可以使用void指针来分配内存,并将其转换为其他数据类型的指针。
例如:```void* allocateMemory(size_t size)void* memory = malloc(size);return memory;```在上面的例子中,allocateMemory(函数使用void指针来分配内存。
因为void指针没有特定的数据类型,可以将其转换为任何其他类型的指针。
4.泛型指针:void指针也可以用作泛型指针,以便在不同的数据类型之间进行转换。
在C语言中,没有内置的泛型类型,但可以使用void指针来模拟泛型。
C语言中指针的奥秘_C语言程序设计教程
C语言中指针的奥秘定义含义void *p void指针类型int i; 定义整型变量iint *p p 为指向整型数据的指针变量int a[n]; 定义整型数组a,它有n 个元素int *p[n]; 定义指针数组p,它由n 个指向整型数据的指针元素组成int (*p)[n]; p 为指向含n 个元素的一维数组的指针变量数组指针int *p(); p 为带回一个指针的函数,该指针指向整型数据指针型函数int (*p)(); p 为指向函数的指针,该函数返回一个整型值函数指针Int(*p[10])P是一个有10个指针的数组,该指针指向一个函数();int **p; P 是一个指针变量,它指向一个指向整型数据的指针变量数组指针和指针数组的区别●数组指针(也称行指针):指向多维数组的指针变量 || 区别指向数组的指针,即一个普通指针,指向一个数组: int a[3];int *p = a;定义 int (*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。
也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]所以数组指针也称指向一维数组的指针,亦称行指针。
●指针数组:一个数组的元素值为指针,是一组有序的指针的集合定义 int *p[n];[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。
这里执行p+1是错误的,这样赋值也是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。
深入理解C语言指针的奥秘
1、指针指针的类型去掉指针名字,剩下的是指针的类型。
这是指针本身所具有的类型。
(1)int*ptr;//指针的类型是int*(2)char*ptr;//指针的类型是char*(3)int**ptr;//指针的类型是int**(4)int(*ptr)[3];//指针的类型是int(*)[3](5)int*(*ptr)[4];//指针的类型是int*(*)[4]指针所指向的类型当通过指针访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
去掉指针名字和*,剩下的是指针所指向的类型。
(1)int*ptr;//指针所指向的类型是int(2)char*ptr;//指针所指向的的类型是char(3)int**ptr;//指针所指向的的类型是int*(4)int(*ptr)[3];//指针所指向的的类型是int()[3](5)int*(*ptr)[4];//指针所指向的的类型是int*()[4]指针的值32位程序里内存地址都是32位。
指针指向的内存区是从指针的值所代表的内存地址开始,长度为si zeof(指针所指向的类型)的一片内存区。
即指针指向的是首地址。
void main(){ int num;scanf("%d",&num);printf("num=%d\n", num);}假设系统分配给变量num的4字节存储单元为3000至3003,则起始地址3000就是变量num在内存中的地址指针本身所占据的内存区sizeof(指针的类型)。
32位平台里,指针本身占据了4个字节的长度。
指针的算数运算与普通算数是不同的,指针ptr加n,结果是移动一个元素单元,即增加n*sizeof(ptr 所指向的类型)个字节。
因为存一个数是sizeof个字节。
注意类型要匹配。
2、数组和指针的关系数组的数组名是常量指针,指向数组首地址。
int array[10]={0,1,2,3,4,5,6,7,8,9};value=array[0];//也可写成:value=*array;value=array[3];//也可写成:value=*(array+3);注意,该指针的值是不能修改的,即类似array++的表达式是错误的。
C语言指针的奥秘
C语言指针的奥秘集团标准化工作小组 #Q8QGGQT-GX8G08Q8-GNQGJ8-MHHGN#让你不再害怕指针前言:复杂类型说明要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧:int p; 以P 是一个返回整型数据的指针int p[3]; 以P 是一个指向由整型数据组成的数组的指针int **p; 于二级指针以及更高级的指针极少用在复杂的类型中,所以后面更复杂的类型我们就不考虑多级指针了,最多只考虑一级指针.int p(int); 以P 是一个参数为一个整数据且返回一个指向由整型指针变量组成的数组的指针变量的函数.说到这里也就差不多了,我们的任务也就这么多,理解了这几个类型,其它的类型对我们来说也是小菜了,不过我们一般不会用太复杂的类型,那样会大大减小程序的可读性,请慎用,这上面的几种类型已经足够我们用了.1、细说指针指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
要搞清一个指针需要搞清指针的四方面的内容:指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。
让我们分别说明。
先声明几个指针放着做例子:例一:(1)int*ptr;(2)char*ptr;(3)int**ptr;(4)int(*ptr)[3];(5)int*(*ptr)[4];1.指针的类型从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。
这是指针本身所具有的类型。
让我们看看例一中各个指针的类型:(1)int*ptr;针所指向的类型当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
C++语言void 及void指针深层探索
void目录void含义void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。
void几乎只有“注释”和限制程序的作用,定义一个void变量没有意义,不妨试着定义:void a;这行语句编译时会出错,提示“illegal use of type 'void'”。
不过,即使void a的编译不会出错,它也没有任何实际意义。
void真正发挥的作用在于:(1)对函数返回的限定;(2)对函数参数的限定。
众所周知,如果指针p1和p2的类型相同,那么我们可以直接在p1和p2间互相赋值;如果p1和p2指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的指针类型转换为左边指针的类型。
例如:float *p1;int *p2;p1 = p2;其中p1 = p2语句会编译出错,提示“'=' : cannot convert from 'int *' to 'float *'”,必须改为:p1 = (float *)p2;而void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:void *p1;int *p2;p1 = p2;但这并不意味着,void *也可以无需强制类型转换地赋给其它类型的指针。
因为“无类型”可以包容“有类型”,而“有类型”则不能包容“无类型”。
道理很简单,我们可以说“男人和女人都是人”,但不能说“人是男人”或者“人是女人”。
下面的语句编译出错:void *p1;int *p2;p2 = p1;提示“'=' : cannot convert from 'void *' to 'int *'”。
[编辑本段]void的使用下面给出void关键字的使用规则:规则一如果函数没有返回值,那么应声明为void类型在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理。
c语言中void的用法
c语言中void的用法c语言中void的用法的用法你知道吗?下面就跟你们详细介绍下c语言中void的用法的用法,希望对你们有用。
c语言中void的用法的用法如下:void指针是什么?void指针一般被称为通用指针或泛指针,它是C关于“纯粹地址(raw address)”的一种约定。
void指针指向某个对象,但该对象不属于任何类型。
请看下例:int*ip;void*p;在上例中,ip指向一个整型值,而p指向的对象不属于任何类型。
在C中,任何时候你都可以用其它类型的指针来代替void指针(在C++中同样可以),或者用void指针来代替其它类型的指针(在C++中需要进行强制转换),并且不需要进行强制转换。
例如,你可以把char *类型的指针传递给需要void指针的函数。
什么时候使用void指针?当进行纯粹的内存操作时,或者传递一个指向未定类型的指针时,可以使用void指针。
void指针也常常用作函数指针。
有些C代码只进行纯粹的内存操作。
在较早版本的C中,这一点是通过字符指针(char *)实现的,但是这容易产生混淆,因为人们不容易判断一个字符指针究竟是指向一个字符串,还是指向一个字符数组,或者仅仅是指向内存中的某个地址。
例如,strcpy()函数将一个字符串拷贝到另一个字符串中,strncpy()函数将一个字符串中的部分内容拷贝到另一个字符串中:char *strepy(char'strl,const char *str2);char *strncpy(char *strl,const char *str2,size_t n);memcpy()函数将内存中的数据从一个位置拷贝到另一个位置:void *memcpy(void *addrl,void *addr2,size_t n);memcpy()函数使用了void指针,以说明该函数只进行纯粹的内存拷贝,包括NULL字符(零字节)在内的任何内容都将被拷贝。
c语言void的用法
c语言void的用法近年来,计算机技术的不断进步,让编程语言也得到了飞速发展。
而在其中最为重要的一门编程语言——C语言中,void常常是被提及的一个关键词,它在C语言中有着极其重要和独特的用法和作用。
本文将从多个角度介绍C语言中void的用法,以帮助读者更加深入地理解C语言的语言规范和编程特点。
1. 作为函数的返回值void在C语言中被用来表示无返回值,即函数不返回任何值,一般用于对函数中的一个操作进行处理而无需返回值。
例如:void showMessage(char* message) {printf("%s\n", message);}在上述代码中,我们定义了一个名为showMessage的函数,它的返回类型是void,也就是说该函数在执行完毕后不会返回任何值,而是仅仅会将信息打印出来。
2. 作为函数的参数C语言允许在函数中传递引用给其他函数,进而可以使用void指针类型来作为多个不同数据类型的函数参数。
void指针类型可以指向任意类型的数据,但不能直接被解引用运算符(*)所操作。
例如:void swap(void *x, void *y, int size) {void *tmp = malloc(size);memcpy(tmp, x, size);memcpy(x, y, size);memcpy(y, tmp, size);free(tmp);}在上述代码中,swap函数用void指针类型作为参数,来表示该函数具有对任何数据类型进行交换的能力,从而提高了函数的灵活性和扩展性。
3. 作为通用指针类型在C语言中,指针类型的数据类型是非常重要的,指针可以对内存地址进行操作,从而可以实现对程序的控制。
而当定义指针类型时,如果不确定指针所指对象的类型,就可以使用void指针类型对其进行定义。
例如:void *p;在上述代码中,我们定义了一个名为p的指针,它是void指针类型,可以用于指向任何类型的数据。
void指针的用法
void指针的用法
Void指针是一种特殊类型的指针,它可以指向任何数据类
型的地址,包括基本数据类型、自定义类型和函数。
由于
void指针并不知道它所指向的数据的具体类型,所以在使用void指针前,必须将其转换为适当的类型。
在C语言中,使用void指针可以实现灵活的内存分配和动
态类型检查。
一种常见的用法是将void指针作为函数参数,
使函数能够处理不同类型的数据。
例如,可以使用void指针来实现通用的动态数组。
通过将
数据的地址存储在void指针中,可以在运行时根据需要分配
和释放内存。
当需要访问存储在动态数组中的数据时,可以通过将void指针转换为正确的指针类型来实现。
另一个常见的用法是在需要传递复杂数据结构的函数之间
传递指针。
使用void指针作为参数类型可以使函数具有更大
的灵活性,因为它可以接受任何类型的指针。
在函数中,可以将void指针转换为适当的指针类型,以便对数据进行操作。
需要注意的是,由于void指针的特殊性,使用时需要谨慎。
在转换void指针为其他类型指针之前,必须确保这个转换是
类型安全的。
否则,可能会导致内存错误或未定义的行为。
void指针在C语言中具有重要的用途,它可以用于实现灵
活的内存管理和处理不同类型的数据。
通过正确地使用和转换void指针,我们能够编写出更加通用和灵活的代码。
c语言中void的用法
在C语言中,`void`是一个特殊的关键字,用于表示“无类型”。
它可以在不同的上下文中具有不同的含义和用途。
下面是`void`在C语言中的一些常见用法:1. 函数返回类型为`void`:当一个函数的返回类型为`void`时,它表示该函数不返回任何值。
这样的函数通常用于执行某些操作或产生某些副作用,而不是计算并返回一个值。
例如:```cvoid printHello() {printf("Hello, World!\n");}```这个函数不返回任何值,它的目的是在控制台上打印一条消息。
2. 函数参数为`void`类型:当一个函数的参数列表中包含一个`void`类型的参数时,表示该函数可以接受任何类型的参数。
通常在编写通用函数或回调函数时使用这种用法。
例如:```cvoid printValue(void *data) {printf("%d\n", *(int *)data);}```这个函数接受一个指向`void`的指针作为参数,然后将其强制转换为指向整数的指针,并打印出该整数值。
3. 指针类型为`void`类型:在某些情况下,可以使用`void`类型的指针来存储任意类型的数据。
这通常用于编写通用的函数或实现某些特定的功能。
例如:```cvoid *genericPointer;genericPointer = malloc(sizeof(int));*(int *)genericPointer = 10;```这个例子中,我们声明了一个指向`void`的指针`genericPointer`,然后将其指向一个整数类型的内存块,并将整数值存储在该内存块中。
需要注意的是,在使用`void`类型时需要特别小心,因为它表示“无类型”,所以在使用时需要进行适当的类型转换和强制类型转换。
此外,在使用`void`类型的指针时需要特别小心,因为它可以指向任何类型的数据,如果不正确地进行类型转换,可能会导致未定义的行为。
void在c语言中的作用
void在c语言中的作用
在C语言中,`void`是一种特殊的数据类型,用于表示“无类型”或“无值”。
它常用于以下几个方面:
1. 函数返回类型:当函数不需要返回值时,可以将函数的返回类型声明为`void`。
例如:`void funcName();`
2. 函数参数类型:当函数不需要接收任何参数时,可以将函数的参数列表声明为`void`。
例如:`void funcName(void);`
3. 指针类型:`void*`是一种泛型指针类型,可以指向任意类型的数据。
通过
`void*`指针,可以实现对不同类型的数据进行通用处理。
4. 函数指针类型:`void (*funcPtr)(void)`是一个函数指针类型,它可以指向不返回任何值且不接收任何参数的函数。
总的来说,`void`主要用于表示没有返回值或没有参数的函数,也可以用于指向不同类型数据的指针。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.概述
许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误。
本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧。
2.void的含义
void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。
void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来定义:
void a;
这行语句编译时会出错,提示“illegal use of type 'void'”。
不过,即使void a的编译不会出错,它也没有任何实际意义。
void真正发挥的作用在于:
(1)对函数返回的限定;
(2)对函数参数的限定。
众所周知,如果指针p1和p2的类型相同,那么我们可以直接在p1和p2间互相赋值;如果p1和p2指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的指针类型转换为左边指针的类型。
例如:
float *p1;
int *p2;
p1 = p2;
其中p1 = p2语句会编译出错,提示“'=' : cannot convert from 'int *' to 'float *'”,必须改为:
p1 = (float *)p2;
而void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:
void *p1;
int *p2;
p1 = p2;
但这并不意味着,void
*也可以无需强制类型转换地赋给其它类型的指针。
因为“无类型”可以包容“有类型”,而“有类型”则不能包容“无类型”。
道理很简单,我们可以说“男人和女人都是人”,但不能说“人是男人”或者“人是女人”。
下面的语句编译出错:
void *p1;
int *p2;
p2 = p1;
提示“'=' : cannot convert from 'void *' to 'int *'”。
3.void的使用
下面给出void关键字的使用规则:
规则一如果函数没有返回值,那么应声明为void类型
在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理。
但是许多程序员却误以为其为void类型。
例如:
add ( int a, int b )
{
return a + b;
}
int main(int argc, char* argv[])
{
printf ( "2 + 3 = %d", add ( 2, 3) );
}
程序运行的结果为输出:
2 +
3 = 5
这说明不加返回值说明的函数的确为int函数。
林锐博士《高质量C/C++编程》中提到:“C++语言有很严格的类型安全检查,不允许上述情况(指函数不加类型声明)发生”。
可是编译器并不一定这么认定,譬如在Visual C++6.0中上述add函数的编译无错也无警告且运行正确,所以不能寄希望于编译器会做严格的类型检查。
因此,为了避免混乱,我们在编写C/C++程序时,对于任何函数都必须一个不漏地指定其类型。
如果函数没有返回值,一定要声明为void类型。
这既是程序良好可读性的需要,也是编程规范性的要求。
另外,加上void类型声明后,也可以发挥代码的“自注释”作用。
代码的“自注释”即代码能自己注释自己。
规则二如果函数无参数,那么应声明其参数为void
在C++语言中声明一个这样的函数:
int function(void)
{
return 1;
}
则进行下面的调用是不合法的:
function(2);
因为在C++中,函数参数为void的意思是这个函数不接受任何参数。
我们在Turbo C 2.0中编译:
#include "stdio.h"
fun()
{
return 1;
}
main()
{
printf("%d",fun(2));
getchar();
}
编译正确且输出1,这说明,在C语言中,可以给无参数的函数传送任意类型的参数,但是在C++编译器中编译同样的代码则会出错。
在C++中,不能向无参数的函数传送任何参数,出错提示“'fun'
: function does not take 1 parameters”。
所以,无论在C还是C++中,若函数不接受任何参数,一定要指明参数为void。
规则三小心使用void指针类型
按照ANSI(American National Standards
Institute)标准,不能对void指针进行算法操作,即下列操作都是不合法的:
void * pvoid;
pvoid++; //ANSI:错误
pvoid += 1; //ANSI:错误
//ANSI标准之所以这样认定,是因为它坚持:进行算法操作的指针必须是确定知道其指向数据类型大小的。
//例如:
int *pint;
pint++; //ANSI:正确
pint++的结果是使其增大sizeof(int)。
但是大名鼎鼎的GNU(GNU's Not Unix的缩写)则不这么认定,它指定void *的算法操作与char *一致。
因此下列语句在GNU编译器中皆正确:
pvoid++; //GNU:正确
pvoid += 1; //GNU:正确
pvoid++的执行结果是其增大了1。
在实际的程序设计中,为迎合ANSI标准,并提高程序的可移植性,我们可以这样编写实现同样功能的代码:
void * pvoid;
(char *)pvoid++; //ANSI:正确;GNU:正确
(char *)pvoid += 1; //ANSI:错误;GNU:正确
GNU和ANSI还有一些区别,总体而言,GNU较ANSI更“开放”,提供了对更多语法的支持。
但是我们在真实设计时,还是应该尽可能地迎合ANSI标准。
规则四如果函数的参数可以是任意类型指针,那么应声明其参数为void *
典型的如内存操作函数memcpy和memset的函数原型分别为:
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
这样,任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型。
如果memcpy和memset的参数类型不是void
*,而是char *,那才叫真的奇怪了!这样的memcpy和memset明显不是一个“纯粹的,脱离低级趣味的”函数!
下面的代码执行正确:
//示例:memset接受任意类型指针
int intarray[100];
memset ( intarray, 0, 100*sizeof(int) ); //将intarray清0
//示例:memcpy接受任意类型指针
int intarray1[100], intarray2[100];
memcpy ( intarray1, intarray2, 100*sizeof(int) ); //将intarray2拷贝给intarray1
有趣的是,memcpy和memset函数返回的也是void *类型,标准库函数的编写者是多么地富有学问啊!
规则五void不能代表一个真实的变量
下面代码都企图让void代表一个真实的变量,因此都是错误的代码:
void a; //错误
function(void a); //错误
void体现了一种抽象,这个世界上的变量都是“有类型”的,譬如一个人不是男人就是女人(还有人妖?)。
void的出现只是为了一种抽象的需要,如果你正确地理解了面向对象中“抽象基类”的概念,也很容易理解void数据类型。
正如不能给抽象基类定义一个实例,我们也不能定义一个void(让我们类比的称void为“抽象数据类型”)变量。
4.总结
小小的void蕴藏着很丰富的设计哲学,作为一名程序设计人员,对问题进行深一个层次的思考必然使我们受益匪浅。
相关知识:
void指针类型
ANSI
C标准规定用动态存储分配函数时返回void指针,它可以用来指向一个抽象的类型的数据,再将它的值赋给另一指针变量时要进行强制类型转换使之适合于被赋值的变量的类型,如:
char *p1;
void *p2;
...
p1=(char *)p2;
或:p2=(void *)p1;
也可以将一个函数定义为void *类型,如:
void *fun(char ch1,char ch2)
表示函数fun返回的是一个地址,它指向“空类型”,如需要引用此地址,也需要根据情况对之进行类型转换,如:
p1=(char *)fun(ch1,ch2)。