开发者社区> 问答> 正文

为什么一个指针可以转换为int ? 400 请求报错 

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <unistd.h>

void* thr_fn1(void* arg)

{

   printf("thread 1 exiting\n");

   return (void* )1;

}

void* thr_fn2(void* arg)

{

   printf("thread2 exiting\n");

   pthread_exit( (void*)2 );

}

void* thr_fn3(void* arg)

{

   while(1)

   {

      printf("thread 3 writing\n");

      sleep(1);

   }

}

int main(void)

{

   pthread_t tid;

   void* tret;

   pthread_create(&tid, NULL, thr_fn1, NULL);

   pthread_join(tid, &tret);

    

   printf("thread1 exit code %d\n", (int)tret);

   pthread_create(&tid, NULL, thr_fn2, NULL);

   pthread_join(tid, &tret);

   printf("thread 2 exit code %d\n", (int)tret);

   pthread_create(&tid, NULL, thr_fn3, NULL);

   sleep(3);

   pthread_cancel(tid);

   pthread_join(tid, &tret);

   printf("thread 3 exit code %d\n", (int)tret);

   return 0;

} 这是一个创建线程的程序,首先创建一个线程,这个线程打印  "thread 1 exiting\n" 然后通过 void* tret    这个指针获得之前创建的线程的退出状态(后面还程序还 没看), 我不 明白的是 printf("thread1 exit code %d\n", (int)tret);  一个void*的指针怎么能 转换为int类型,会不会报错?

展开
收起
kun坤 2020-05-29 09:53:06 624 0
1 条回答
写回答
取消 提交回答
  • java飘过,用过JNA,int 和指针都是32位的。SO......######指针里面存的就是一个内存地址,内存地址就可以用一个整数来表示。so……c忘光了######指针是一个地址,而且是32位,和int类型一样,在机器中表现的就是一个“数字”而已######太官方啦,有木有别的解释, return (void* )1 是什么意思,这个1代表什么?内存?######(void ) -1 代表什么意思?  ######(void)-1 表示把-1转换为一个无类型指针,这个指针存储的值就是-1. 看看关于C和指针方面的书,这都是比较基础的######void代表的是void type而不是void value######都是void了怎么还能存-1呢?######哈。首先要明确,机器处理的对象就是数字。当然不同位宽的数字有不同的辅助操作。而核心操作基本上就是加(减),乘,位操作,和取址操作。比较操作其实可以等同为减操作。 除非有硬件除法器,否则是没有除的概念。除法是调用系统库运算的结果。 由于核心操作都一样,所以不同类型,无非是位宽和核心操作前辅助操作的差异而已。 高级语言是为了方便你,帮你约束各个位宽,而落在机器上没有本质差异。 指针类型,无论指向的地址类型是什么 ,都是一个类型,就是“指针”类型。这个和机器的地址宽度有关。有时不和总线地址宽度有关,主要看CPU内部怎么处理了。但对于一个具体平台和OS,指针类型的位宽都是一致的。 需要注意的是,只有int和指针类型的位宽相同时,强制的转换才没有问题。否则还是会报错。int不等于指针类型的位宽。只是碰巧32位如此。######

    引用来自“中山野鬼”的答案

    哈。首先要明确,机器处理的对象就是数字。当然不同位宽的数字有不同的辅助操作。而核心操作基本上就是加(减),乘,位操作,和取址操作。比较操作其实可以等同为减操作。 除非有硬件除法器,否则是没有除的概念。除法是调用系统库运算的结果。 由于核心操作都一样,所以不同类型,无非是位宽和核心操作前辅助操作的差异而已。 高级语言是为了方便你,帮你约束各个位宽,而落在机器上没有本质差异。 指针类型,无论指向的地址类型是什么 ,都是一个类型,就是“指针”类型。这个和机器的地址宽度有关。有时不和总线地址宽度有关,主要看CPU内部怎么处理了。但对于一个具体平台和OS,指针类型的位宽都是一致的。 需要注意的是,只有int和指针类型的位宽相同时,强制的转换才没有问题。否则还是会报错。int不等于指针类型的位宽。只是碰巧32位如此。
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <string.h>
    
    struct stu                            //我自己定义的学生结构
    {
        char name[20];
        int age;
    };
    void* thr_fn1(void* arg)                //线程thr_fn1
    {
     
        printf("thread 1 exiting\n");
        printf("%d\n", ((struct stu*)arg)->age);        //把void* arg准换为结构体的指针,取出age成员
    
       //((char*)arg)[20], ((int*)arg)[5]  用这样也可以读name , age
       return (void* )1;
     
    } 
        int main(void)
     42 {
     43    struct stu ones;
     44    struct stu* pones = &ones;
     45    memcpy(ones.name, "sgc", 4);
     46    ones.age =10;
     47 
     48    pthread_t tid;
     49    void* tret;
     50    pthread_create(&tid, NULL, thr_fn1, (void*)pones);    //创建线程1,传入结构体的指针并转换为void*
     51    pthread_join(tid, &tret);                             //等待线程1结束
           return 0;
      } 我又不懂, void* 的一般用法有哪些,都在什么地方用? ######

    引用来自“gcshang”的答案

    引用来自“中山野鬼”的答案

    哈。首先要明确,机器处理的对象就是数字。当然不同位宽的数字有不同的辅助操作。而核心操作基本上就是加(减),乘,位操作,和取址操作。比较操作其实可以等同为减操作。 除非有硬件除法器,否则是没有除的概念。除法是调用系统库运算的结果。 由于核心操作都一样,所以不同类型,无非是位宽和核心操作前辅助操作的差异而已。 高级语言是为了方便你,帮你约束各个位宽,而落在机器上没有本质差异。 指针类型,无论指向的地址类型是什么 ,都是一个类型,就是“指针”类型。这个和机器的地址宽度有关。有时不和总线地址宽度有关,主要看CPU内部怎么处理了。但对于一个具体平台和OS,指针类型的位宽都是一致的。 需要注意的是,只有int和指针类型的位宽相同时,强制的转换才没有问题。否则还是会报错。int不等于指针类型的位宽。只是碰巧32位如此。
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <string.h>
    
    struct stu                            //我自己定义的学生结构
    {
        char name[20];
        int age;
    };
    void* thr_fn1(void* arg)                //线程thr_fn1
    {
     
        printf("thread 1 exiting\n");
        printf("%d\n", ((struct stu*)arg)->age);        //把void* arg准换为结构体的指针,取出age成员
    
       //((char*)arg)[20], ((int*)arg)[5]  用这样也可以读name , age
       return (void* )1;
     
    } 
        int main(void)
     42 {
     43    struct stu ones;
     44    struct stu* pones = &ones;
     45    memcpy(ones.name, "sgc", 4);
     46    ones.age =10;
     47 
     48    pthread_t tid;
     49    void* tret;
     50    pthread_create(&tid, NULL, thr_fn1, (void*)pones);    //创建线程1,传入结构体的指针并转换为void*
     51    pthread_join(tid, &tret);                             //等待线程1结束
           return 0;
      } 我又不懂, void* 的一般用法有哪些,都在什么地方用?
    void 只要你觉得这个不知道啥类型 你就可以用void ######

    引用来自“小耶果”的答案

    (void*)-1 表示把-1转换为一个无类型指针,这个指针存储的值就是-1. 看看关于C和指针方面的书,这都是比较基础的
     #include <stdio.h> 02    #include <stdlib.h> 03    #include <pthread.h> 04    #include <unistd.h> 05    #include <string.h> 06      07    struct stu                            //我自己定义的学生结构 08    { 09        char name[20]; 10        int age; 11    }; 12    void* thr_fn1(void* arg)                //线程thr_fn1 13    { 14      15        printf("thread 1 exiting\n"); 16        printf("%d\n", ((struct stu*)arg)->age);        //把void* arg准换为结构体的指针,取出age成员 17      18       //((char*)arg)[20], ((int*)arg)[5]  用这样也可以读name , age 19       return (void* )1; 20      21    } 22        int main(void) 23     { 24         struct stu ones; 25         struct stu* pones = &ones; 26         memcpy(ones.name, "sgc", 4); 27         ones.age =10; 28      29         pthread_t tid; 30         void* tret; 31         pthread_create(&tid, NULL, thr_fn1, (void*)pones);    //创建线程1,传入结构体的指针并转换为void* 32         pthread_join(tid, &tret);                             //等待线程1结束 33     } 你看我把指向结构体的指针pones转换为void*传入到线程thr_fn1的函数中,然后再函数中把void* 的指针转换为 结构体指针,然后访问结构体成员是否有问题?void*的典型用法是怎样的 ?
    2020-05-29 11:40:27
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载