C编程中void指针的概念
在C编程语言中没有使用types转换的情况下是否可以解引用void指针?
另外,是否有任何方法来推广一个函数,它可以接收一个指针并将其存储在一个void指针中,并且通过使用void pointe,我们可以创build一个广义函数吗?
例如:
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,这将是有益的。
此外,指针算术与空指针可能吗?
是否有可能取消引用无效C指令语言中的空指针…
不, void
表示没有types,它不是可以解引用或分配的东西。
有没有什么办法来推广一个函数,它可以接收指针并将其存储在void指针中,并通过使用该void指针我们可以创build一个广义函数。
您不能以便携的方式取消引用它,因为它可能不正确alignment。 在某些像ARM这样的体系结构中,这可能是一个问题,在这种体系结构中,指向数据types的指针必须在数据types大小的边界alignment(例如,指向32位整数的指针必须在4字节边界alignment才能被取消引用)。
例如,从void*
读取uint16_t
:
/* 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);
此外,指针算术与空指针可能…
由于缺less指针下面的具体值以及大小,指针算术不可能在void
的指针上。
void* p = ... void *p2 = p + 1; /* what exactly is the size of void?? */
在C中, void *
可以被转换为指向不同types的对象的指针,而不需要显式的强制转换:
void abc(void *a, int b) { int *test = a; /* ... */
尽pipe如此,这并不能帮助您以更通用的方式编写函数。
您不能通过将其转换为不同的指针types来取消引用void *
,因为取消引用指针正在获取指向的对象的值。 裸void
不是一个有效的types,所以解除void *
是不可能的。
指针算术是指针指向对象sizeof
的倍数改变指针值。 同样,因为void
不是真正的types,所以sizeof(void)
没有意义,所以指针运算在void *
上是void *
。 (有些实现允许使用char *
的等价指针运算。)
您应该知道,在C中,不像Java或C#那样,绝对不可能成功“猜测”void *指针指向的对象的types。 类似“getClass()”的东西根本就不存在,因为这个信息是无处可寻的。 出于这个原因,你所寻找的那种“通用”总是带有明确的元信息,比如你的例子中的“int b”或者printf函数族中的格式化string。
一个void指针被称为generics指针,它可以引用任何数据types的variables。
到目前为止我对void指针的低估如下。
当使用关键字void声明一个指针variables时 – 它变成一个通用指针variables。 任何数据types的variables(char,int,float等)的地址都可以赋给一个void指针variables。
main() { int *p; void *vp; vp=p; }
由于其他数据types指针可以分配给void指针,所以我在absolut_value(代码如下所示)函数中使用它。 做一个普通的function。
我试图写一个简单的C代码,它采用整数或浮点数作为参数,并尝试使其+ ve,如果为负。 我写了下面的代码,
#include<stdio.h> void 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指针variables来解引用它。 这是因为void指针没有与之关联的数据types。 编译器无法知道(或猜测)void指针所指向的数据types。 因此,要获取由void指针指向的数据,我们使用void指针位置内的正确types的数据对它进行types转换。
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) ); }
如果程序员不确定最终用户input的数据的数据types,则void指针可能非常有用。 在这种情况下,程序员可以使用void指针来指向未知数据types的位置。 程序可以设定为要求用户通知数据types,并且可以根据用户input的信息执行types转换。 下面给出了一个代码片段。
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<stdio.h> #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; }
谢谢,
c中的void指针被称为generics指针 。 通用指针的字面含义是指向任何types的数据的指针 。
void *ptr;
-
我们不能将generics指针取消引用到任何其他指针。
-
我们可以使用sizeof运算符来查找generics指针的大小。
-
generics指针可以容纳任何types的指针,如char指针,结构体指针,指针数组等等,不需要任何types转换。
-
任何types的指针可以容纳通用指针而不用任何types转换。
-
当我们想要返回适用于所有types指针的指针时,使用通用指针。 例如malloc函数的返回types是generics指针,因为它可以dynamic分配内存空间来存储整数,浮点数,结构等,因此我们input它的返回types为适当的指针types。
void abc(void *a, int b) { char *format[] = {"%d", "%c", "%f"}; printf(format[b-1], a); }
不,这是不可能的。 什么types的应该取消引用的价值?
我想使这个函数是通用的,而不使用ifs; 可能吗?
我看到的唯一简单的方法是使用重载..这是不可用的C编程语言AFAIK。
你认为你的程序是C ++编程语言吗? 还是有禁止使用的限制?
您可以轻松打印一个无效的打印机
int p=15; void *q; q=&p; printf("%d",*((int*)q));
因为C是静态types的强types语言,所以在编译之前必须确定variables的types。 当你试图在C中模拟generics时,你最终会尝试重写C ++,所以最好使用C ++。
这将无法正常工作,但void *可以帮助您定义函数的泛指针并将其作为parameter passing给另一个函数(类似于Java中的callback),或者将其定义为类似于oop的结构。