从 void 指针设置和获取值的不同方法

Different ways of setting and getting values from void pointer

在浏览一些关于 void 指针的链接时,我在设置和从 void 指针获取值时看到了两种类型,

int main() {
    int i = 5;

    //This is first way.

    void *vPtr = (void *) i;

    //printing value of *vPtr,
    printf("Getting value in first way, %d\n", (int)vPtr);

    //This is second way.
    *vPtr = &i;

    //printing in second way,
    printf("Getting value in second way, %d\n", *((int*)vPtr));
}

两者都会给出相同的值。虽然我知道第二种方法是如何工作的,但我不完全确定第一种方法是如何工作的。处理这两者之间的空指针的理想方法是什么?

对于第一种方法,这是我所指的代码片段。虽然他传递的是 long 类型,但我也可以用 int 做同样的事情。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0;t<NUM_THREADS;t++){
     printf("In main: creating thread %ld\n", t);
     rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
     if (rc){
       printf("ERROR; return code from pthread_create() is %d\n", rc);
       exit(-1);
       }
     }

   /* Last thing that main() should do */
   pthread_exit(NULL);
}

第一种方法使用指针作为整数的存储 space;第二种方式单独存储整数,并使用void*指针指向它。

指针能够保存内存地址。由于内存地址本质上是数值,因此指针能够存储数字。但是,此类数字的范围取决于系统。例如,您可以通过将指针传递给带有 %p 格式说明符的 printf 来将指针重新解释为整数。 printf 生成的数值是系统定义的,但您会为您的指针打印一些数字。

第二种方法保证有效。而且,如果你改变i,线程看到的值也会改变。

这意味着指针指向的值必须在线程可以访问它的时间内保持不变。这意味着如果您要更改线程代码以使用第二种方法,那么单个 t 是不够的;您将不得不制作一个 NUM_THREADS 元素的数组,并将每个线程的地址传递给不同的元素。

第二种方法可能适用于大多数硬件,因为 int 通常适合指针的 space。但是,C99 标准对此不作任何保证。进行赋值后,对 i 的更改对线程看到的整数值没有影响。

您可以在 this Q&A 中找到有关将 int 转换为 void* 的主题的更多信息。

void *vPtr = (void *) i;

i 解释为指向某物的指针。在您的示例中,vPtr 现在将指向地址 0x00000005

 *vPtr = &i;

这需要 i 地址

这完全取决于你想做什么。