是否可以在C编程语言中取消引用void指针而不使用类型转换?
另外,有没有任何方法可以概括一个可以接收指针并将其存储在void指针中的函数,并且通过使用该void指针,我们可以创建一个通用函数吗?
例如:
void abc(void *a, int b) { if(b==1) printf("%d",*(int*)a); // If integer pointer is received else if(b==2) printf("%c",*(char*)a); // If character pointer is received else if(b==3) printf("%f",*(float*)a); // If float pointer is received }
我想在不使用if-else语句的情况下使这个函数变得通用 - 这可能吗?
此外,如果有很好的互联网文章解释了无效指针的概念,那么如果你能提供这些URL会很有用.
是否可以使用void指针进行指针算术?
是否有可能在C编程语言中取消引用void指针而不使用类型转换...
不,void
表示缺少类型,它不是您可以取消引用或分配的东西.
是否有任何方法可以概括一个函数,它可以接收指针并将其存储在void指针中,通过使用该void指针,我们可以创建一个通用函数.
您不能以便携方式取消引用它,因为它可能无法正确对齐.在某些体系结构(如ARM)上可能存在问题,其中指向数据类型的指针必须在数据类型大小的边界处对齐(例如,指向32位整数的指针必须在4字节边界处对齐以进行解引用).
例如,读取uint16_t
距离void*
:
/* may receive wrong value if ptr is not 2-byte aligned */ uint16_t value = *(uint16_t*)ptr; /* portable way of reading a little-endian value */ uint16_t value = *(uint8_t*)ptr | ((*((uint8_t*)ptr+1))<<8);
此外,是否可能使用void指针进行指针运算...
void
由于指针下方缺少具体值,因此指针上的指针算法是不可能的,因此大小也是如此.
void* p = ... void *p2 = p + 1; /* what exactly is the size of void?? */
在C中,a void *
可以转换为指向不同类型对象的指针,而无需显式转换:
void abc(void *a, int b) { int *test = a; /* ... */
但是,这对于以更通用的方式编写函数没有帮助.
您不能取消引用将void *
其转换为不同的指针类型,因为取消引用指针正在获取指向对象的值.裸体void
不是有效类型,因此void *
无法进行derefencing a .
指针算法是指将指针值改变为指向sizeof
对象的倍数.同样,因为void
不是真正的类型,sizeof(void)
没有意义所以指针算术无效void *
.(有些实现允许它,使用等效的指针算法char *
.)
您应该知道在C中,与Java或C#不同,绝对没有可能成功"猜测"void*指针指向的对象类型.类似于"getClass()"的东西根本就不存在,因为这些信息无处可寻.出于这个原因,您正在寻找的那种"通用"总是带有显式的元信息,例如示例中的"int b"或printf函数族中的格式字符串.
void指针称为通用指针,可以引用任何数据类型的变量.
到目前为止,我对void指针的理解如下.
当使用关键字void声明指针变量时 - 它变成通用指针变量.可以将任何数据类型(char,int,float等)的任何变量的地址分配给void指针变量.
main() { int *p; void *vp; vp=p; }
由于其他数据类型指针可以分配给void指针,所以我在absolut_value(下面显示的代码)函数中使用它.做一般功能.
#includevoid absolute_value ( void *j) // works if used float, obviously it must work but thats not my interest here. { if ( *j < 0 ) *j = *j * (-1); } int main() { int i = 40; float f = -40; printf("print intiger i = %d \n",i); printf("print float f = %f \n",f); absolute_value(&i); absolute_value(&f); printf("print intiger i = %d \n",i); printf("print float f = %f \n",f); return 0; }
但是我得到了错误,所以我开始知道我对无效指针的理解是不正确的:(.所以现在我将走向收集点为什么会这样.
我需要更多地了解void指针的东西是.
我们需要对void指针变量进行类型转换以取消引用它.这是因为void指针没有与之关联的数据类型.编译器无法知道(或猜测?)void指针指向的数据类型.因此,为了获取void指针指向的数据,我们使用在void指针位置内保存的正确数据类型对其进行类型转换.
void main() { int a=10; float b=35.75; void *ptr; // Declaring a void pointer ptr=&a; // Assigning address of integer to void pointer. printf("The value of integer variable is= %d",*( (int*) ptr) );// (int*)ptr - is used for type casting. Where as *((int*)ptr) dereferences the typecasted void pointer variable. ptr=&b; // Assigning address of float to void pointer. printf("The value of float variable is= %f",*( (float*) ptr) ); }
如果程序员不确定最终用户输入的数据的数据类型,则void指针可能非常有用.在这种情况下,程序员可以使用void指针指向未知数据类型的位置.可以以要求用户通知数据类型的方式设置程序,并且可以根据用户输入的信息执行类型转换.下面给出了一个代码片段.
void funct(void *a, int z) { if(z==1) printf("%d",*(int*)a); // If user inputs 1, then he means the data is an integer and type casting is done accordingly. else if(z==2) printf("%c",*(char*)a); // Typecasting for character pointer. else if(z==3) printf("%f",*(float*)a); // Typecasting for float pointer }
关于void指针应该记住的另一个重点是 - 指针算法不能在void指针中执行.
void *ptr; int a; ptr=&a; ptr++; // This statement is invalid and will result in an error because 'ptr' is a void pointer variable.
所以现在我明白了我的错误.我正在纠正同样的问题.
参考文献:
http://www.antoarts.com/void-pointers-in-c/
http://www.circuitstoday.com/void-pointers-in-c.
新代码如下所示.
#include#define INT 1 #define FLOAT 2 void absolute_value ( void *j, int *n) { if ( *n == INT) { if ( *((int*)j) < 0 ) *((int*)j) = *((int*)j) * (-1); } if ( *n == FLOAT ) { if ( *((float*)j) < 0 ) *((float*)j) = *((float*)j) * (-1); } } int main() { int i = 0,n=0; float f = 0; printf("Press 1 to enter integer or 2 got float then enter the value to get absolute value\n"); scanf("%d",&n); printf("\n"); if( n == 1) { scanf("%d",&i); printf("value entered before absolute function exec = %d \n",i); absolute_value(&i,&n); printf("value entered after absolute function exec = %d \n",i); } if( n == 2) { scanf("%f",&f); printf("value entered before absolute function exec = %f \n",f); absolute_value(&f,&n); printf("value entered after absolute function exec = %f \n",f); } else printf("unknown entry try again\n"); return 0; }
谢谢,