空指针的打印值

这是《 UNIX环境中的高级编程》一书中的fig11.3

#include <pthread.h>

#include "apue.h"

void* thr_fn1(void* arg) {
    printf("thread 1 returning\n");
    return ((void*)1);
}

void* thr_fn2(void* arg) {
    printf("thread 2 exiting\n");
    pthread_exit((void*)2);
}

int main(void) {
    int err;
    pthread_t tid1, tid2;
    void* tret;

    err = pthread_create(&tid1, NULL, thr_fn1, NULL);
    if (err != 0) err_exit(err, "can't create thread 1");
    err = pthread_create(&tid2, NULL, thr_fn2, NULL);
    if (err != 0) err_exit(err, "can't create thread 2");

    err = pthread_join(tid1, &tret);
    if (err != 0) err_exit(err, "can't join with thread 1");
    printf("thread 1 exit code %ld\n", (long)tret);

    err = pthread_join(tid2, &tret);
    if (err != 0) err_exit(err, "can't join with thread 2");
    printf("thread 2 exit code %ld\n", (long)tret);
    exit(0);
}

我很困惑为什么我不能类型转换void指向long的指针并取消引用它

printf("thread 1 exit code %ld\n", *(long *)tret);

为什么我们可以将tret转换为long类型并获得我们想要的正确值

printf("thread 1 exit code %ld\n", (long)tret);

这里的曲调是什么类型?

我展示了GeeksforGeeks的简单案例,在下面打印void指针的值

#include<stdio.h> 
int main() 
{ 
    int a = 10; 
    void *ptr = &a; 
    printf("%d", *(int *)ptr); 
    return 0; 
} 

上面的两个代码有什么区别?

评论
  • 浅陌初心
    浅陌初心 回复

    我认为这是因为根据pthread_join的手册,它存储线程的返回值,而不是内存地址:如您在thr_fn1和2函数上所看到的,返回值为(void *)1和(void *) 2。

    取消引用指针是没有意义的,因为我们对指针的值感兴趣,而不是指针指向的地址。

    第二种情况使用此技术,因为ptr实际上是一个内存地址。