聪明文档网

聪明文档网

最新最全的文档下载
当前位置: 首页> c语言中void的作用-

c语言中void的作用-

时间:    下载该word文档
1. 概述
许多初学者对C/C++语言中的voidvoid指针类型不甚理解,因此在使用上 出现了一些错误。本文将对 void 关键字的深刻含义进行解说,并 详述 void void 指针类型的使用方法与技巧。 2. void 的含义
void的字面意思是 无类型” void *则为 无类型指针” void *可以指向任何类 的数据。
void 几乎只有 “注释”和限制程序的作用,因为从来没有人会定义一个 void 量,让我们试着来定义:
void a; 这行语句编译时会出错,提示 illegal use of type 'void' 。不过,即”使 void a 的编译不会出错,它也没有任何实际意义。 void 真正发挥的作用在于: 1 对函数返回的限定; 2 对函数参数的限定。
我们将在第三节对以上二点进行具体说明。
众所周知,如果指针plp2的类型相同,那么我们可以直接在 plp2 互相赋值;如果 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(VC6.0上测试是sizeof(int的倍数 但是大名鼎鼎的 GNU(GNU's Not Unix 的缩写 则不这么认定,它指定 void 的算法操作与 char * 一致。
因此下列语句在 GNU 编译器中皆正确: pvoid++; //GNU :正确 pvoid += 1; //GNU :正确
pvoid++的执行结果是其增大了 1(VC6.0上测试是sizeof(int的倍数 在实际的程序设计中,为迎合 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*, char*, int*, float*... 默认初始值都是 0xCCCCCCCC #include #include //#include void main( {
void *p1; int a = 10; int *p2 = &a; cout << p1 << endl;
cout << (int*p2 << endl; p1 = p2; cout << *(int*p1 << endl;//!!!!!!! 用空类型操作输出值!
cout << (int*p2 << endl; }
/* 输出:
0xCCCCCCCC 0x0012FF78 0x0012FF78 0x0012FF78 */ 在声明同时赋值 NULL ,在 delete 后立即设置为 NULL
debug 版本下指针默认初始值为 0xCCCCCCCC ,在 Release 版本下初始值 0x0000000A ,(在我电脑上 VC6.0 )。对于指针如果暂时没有合适的初始化 值,就应该把它置为 NULL 0)。
对于好的编程习惯来说, declare 一个指针,则初始化为 NULL ,如果是类成员 在构造函数中 initialize ,当对指针使用 delete 时候,则置它为 NULL.
0xCCCCCCCC 只是在 debug 状态下 VC 生成的未定义过的指针值,用来提示 这个指针是未被初始化的,在 release 状态下不会等于这个值(除非巧合)。对 于指针如果暂时没有合适的初始化值,就应该把它置为 NULL 0)。 参考资料: /1004734.html?wtp=tt

免费下载 Word文档免费下载: c语言中void的作用-

  • 29.8

    ¥45 每天只需1.0元
    1个月 推荐
  • 9.9

    ¥15
    1天
  • 59.8

    ¥90
    3个月

选择支付方式

  • 微信付款
郑重提醒:支付后,系统自动为您完成注册

请使用微信扫码支付(元)

订单号:
支付后,系统自动为您完成注册
遇到问题请联系 在线客服

常用手机号:
用于找回密码
图片验证码:
看不清?点击更换
短信验证码:
新密码:
 
绑定后可用手机号登录
请不要关闭本页面,支付完成后请点击【支付完成】按钮
遇到问题请联系 在线客服