void 类型指针以及指针数组
2016-05-03 18:02
477 查看
void 类型比较特殊,它可以表示所有的类型,但是又不能像其他类型那样声明成实体。在很多项目中的函数的参数使用void* 型数组,在void*数组中,即可以有int型,可以有char型,也可以有结构体,将这些参数放在一个void* 型数组中。
值得注意的是,不能直接使用void型变量,而是使用void*,即void 型的指针。
比如:
这里第一行声明是正确的,第二行声明是错误的,第三行是正确的。
void指针变量的正确用法为:
1.将int型转换成void*型:
这里可以有人认为c = (int*)&a;这里已经将c的类型强制转换成了int*型,事实上是没有的,还需要在使用的时候进行强制转换。
2.将char* 转换成void*型:
这两种方法本质是一样的,个人喜好而已。
void* 类型的数组使用
//以下内容参考: http://www.cnblogs.com/CoolSummer/p/3205679.html
这里附上的总结:
1.void类型表示无类型,也可以看成是任意类型。
比如: void* c = (int )a; void c = (char *)a;等等
2.可以使用任意类型的指针为void型指针赋值,但是不能用void型指针为已知类型的指针赋值。
void* c = (int *)a; 正确
int b = (void)d; 错误
3.函数的参数使用void型指针,表示可以传入任意类型的参数。
int add(void* a, void* b);
所以当你看到这样一个参数列表时,根本不知的a,b 的具体类型(int or unsigned int 等等)。
4.void可以看成是一种抽象类型,想想virtual,虚函数、虚基类,他们都是抽象的,是虚的。所以不能实例化一个虚的东西,也就是说不能声明一个void型的变量(注意这里我说的是变量,不是指针)。可以想象成void类型是所有已知类型之上的一个抽象类型。
所以在使用malloc时一般都会在前面加上一个指针类型进行强制转换。
5.既然void类型是抽象的,那么就不能对它进行具体的算数运算,例如void * pvoid; pvoid++; pvoid +=2;都是invalid,指针的++操作是给当前分配的内存空间增大一个单元的空间,可是void类型你都不知道它要存啥,你当然不知道他一个单元要多大,所以就不能做算术运算。
值得注意的是,不能直接使用void型变量,而是使用void*,即void 型的指针。
比如:
int a; void b; void* c;
这里第一行声明是正确的,第二行声明是错误的,第三行是正确的。
void指针变量的正确用法为:
1.将int型转换成void*型:
void *c = NULL; int a = 10; c = (int*)&a; std::cout<<(*(int*)c);
这里有很多人会犯这样的错误 : ‘void*’不是一个指向对象的类型,代码如下
void *c = NULL; int a = 10; c = (int*)&a; std::cout<<(*c)<<endl;
这里可以有人认为c = (int*)&a;这里已经将c的类型强制转换成了int*型,事实上是没有的,还需要在使用的时候进行强制转换。
2.将char* 转换成void*型:
1. char* 开辟数组 void *c = NULL; char *a = NULL; a = (char*)malloc(sizeof(char)*10); char *b = a; for(int i =0;i < 5;i++){ *(b++) = i+'a'; } *b = '\0'; c = (char*)a; cout<<(char*)c; /***输出结果: abcde***/ 2. void* 开辟数组 void *c = NULL; char *a = NULL; c = (char*)malloc(sizeof(char)*10); a = (char*) c; for(int i =0;i < 5;i++){ *(a++) = i+'a'; } *a = '\0'; cout<<(char*)c; /***输出结果: abcde***/
这两种方法本质是一样的,个人喜好而已。
void* 类型的数组使用
比如说我在一个函数中需要使用int型参数一个,char型参数一个,char*型参数一个,而我又不想使参数列表太长,所以我决定使用void*数组替代以上三个参数。
void* arg[3]; //声明一个void*型数组 int a = 10; char b = 'b'; char *c = NULL; //原来的参数是 a ,b ,c arg[0] = (int*)&a; arg[1] = (char*)&b; arg[2] = malloc(sizeof(char)*10); c = (char*)arg[2]; for(int i = 0; i < 5;i++){ *(c++) = i+'a'; } *c = '\0'; //转换后的参数为arg 是一个void*型的数组,在使用时也需要按照对应的类型进行强制转换 cout<<*(int*)arg[0]<<'\n'; cout<<*(char*)arg[1]<<'\n'; cout<<(char*)arg[2]<<'\n'; /***输出: 10 b abcde ***/
void* 数组虽然可以使函数的参数个数变少,但是缺点也是显而易见的,当你在函数的参数列表中看到一个void*数组时,你是不知道它究竟代表什么意思,所以在使用void*型数组传参时一定要写好注释,利人利己。以上是我的个人经验,其他的利弊还没有深入探究。
//以下内容参考: http://www.cnblogs.com/CoolSummer/p/3205679.html
这里附上的总结:
1.void类型表示无类型,也可以看成是任意类型。
比如: void* c = (int )a; void c = (char *)a;等等
2.可以使用任意类型的指针为void型指针赋值,但是不能用void型指针为已知类型的指针赋值。
void* c = (int *)a; 正确
int b = (void)d; 错误
3.函数的参数使用void型指针,表示可以传入任意类型的参数。
int add(void* a, void* b);
所以当你看到这样一个参数列表时,根本不知的a,b 的具体类型(int or unsigned int 等等)。
4.void可以看成是一种抽象类型,想想virtual,虚函数、虚基类,他们都是抽象的,是虚的。所以不能实例化一个虚的东西,也就是说不能声明一个void型的变量(注意这里我说的是变量,不是指针)。可以想象成void类型是所有已知类型之上的一个抽象类型。
所以在使用malloc时一般都会在前面加上一个指针类型进行强制转换。
5.既然void类型是抽象的,那么就不能对它进行具体的算数运算,例如void * pvoid; pvoid++; pvoid +=2;都是invalid,指针的++操作是给当前分配的内存空间增大一个单元的空间,可是void类型你都不知道它要存啥,你当然不知道他一个单元要多大,所以就不能做算术运算。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- Java 6 JVM参数选项大全(中文版)
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- autoit 命令行参数说明
- 给IE加个参数 永远不怕IE主页被修改
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- 写批处理必备的一些命令参数使用技巧
- Lua教程(二):C++和Lua相互传递数据示例
- ASP 调用带参数输出的COM接口
- PowerShell实现参数互斥示例
- C#从命令行读取参数的方法
- DIV+CSS经常用到的属性、参数及说明
- C++联合体转换成C#结构的实现方法
- C# Pointer指针应用实例简述
- asp获取URL参数的几种方法分析总结[原创]_应用技巧_脚本之家
- C#读取命令行参数的方法