从 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
的 地址 。
这完全取决于你想做什么。
在浏览一些关于 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
的 地址 。
这完全取决于你想做什么。