`
hankgong
  • 浏览: 200207 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

void* 泛型指针一点小技巧

 
阅读更多

void *有人把它叫为generic pointer,中文翻译为泛型指针。一般来说,它的用法应该是作为指针来用,比如下面的例子

 

int main()
{
  int i;
  char c;
  void *the_data;

  i = 6;
  c = 'a';

  the_data = &i;
  printf("the_data points to the integer value %d\n", *(int*) the_data);

  the_data = &c;
  printf("the_data now points to the character %c\n", *(char*) the_data);

  return 0;
}

 

 这里the_data就是作为一个可以任意指向的多功能指针来用的,但是下面的例子里面

 

#include <pthread.h>
#include <stdio.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);
}

 

 在上面的pthread传递参数的时候,t或者threadid明明就不是指针,这里为什么也用void*。pthread_create函数里面的定义就规定必须传递void*的参数,这是我们是不能选的,如果按照一定要是指针的思维,程序应该是下面的才对

 

#include <iostream>
#include <pthread.h>
//#include <stdio.h>
#include <stdlib.h>

#define NUM_THREADS 5

using namespace std;

void *PrintHello(void *threadid) {
    long tid;
    cout<<"Checking generic pointer"<<threadid<<endl;
    tid = *(long*)threadid;
    cout<<"Hello world! It's me, thread #"<< tid <<endl;
    pthread_exit(NULL);
}

int main()
{
    pthread_t threads[NUM_THREADS];
    int rc;
    long t;

    for(t=0; t<NUM_THREADS; t++){
        cout<<"In main: creating thread"<<t<<endl;

        rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&t);



        if(rc){
            cout<<"ERROR; return code from  pthread_create() is"<<rc<<endl;
            exit(-1);
        }


    }

    pthread_exit(NULL);
    //cout << "Hello World!" << endl;
    return 0;
}

 

 可以这样的话,你会发现在PrintHello里面打印的threadid是错误的,是什么原因呢?

 

 

 

 

 

 

解答:

如果用上面的方式,传递的就是t的地址给threadid,那么PrintHello的时候,主程序里面的t的修改是另外一个线程,所以不能保证PrintHello打印的这个地址的数没有被主程序修改过。

 

那么怎么传递才对?我们上面的倒数第二个其实是对的,这个时候t的值其实是作为地址传递给threadid,然后用long转换的时候就又变成了原来的值了,虽然他们其实不是地址,但是被编译器或者程序当作地址来做个转换又何妨!

 

 

分享到:
评论

相关推荐

    泛型编程与C标准库.doc

    虽然C语言本身不支持像C++那样的模板机制,但是通过巧妙地使用`void *`指针和函数指针,开发者仍然能够在一定程度上实现泛型编程的效果。这种方式不仅增加了代码的灵活性,也提高了代码的复用性,使得开发者能够在...

    C语言泛型编程实例教程

    虽然C语言本身并不直接支持泛型,但通过一些技巧,如使用无类型指针`void*`和辅助函数,可以模拟泛型编程的效果。 1. **无类型指针**: 在C语言中,`void*`指针可以存储任何类型的数据的地址,是实现泛型编程的...

    C语言实现链式栈的模板

    5. **类型检查和转换**:虽然C语言不支持泛型,但我们可以使用`void*`进行类型转换,并在运行时进行类型检查,以确保数据操作的正确性。 例如,如果我们想为整型数据创建一个链式栈,可以这样做: ```c // 定义整型...

    嵌入式C精华.pdf

    - **应用场景**:`void*`指针在泛型编程中十分有用,尤其是在实现多态性或通用函数时。 #### C/C++语言可变参数表深层探索 - **可变参数列表**:在C/C++中,函数可以接受数量不定的参数,通过`va_list`、`va_start...

    顺序栈数据结构

    - **泛型设计**:除了整数,顺序栈还可以用于存储其他类型的数据,通过模板类实现泛型编程。 - **错误处理**:在实际应用中,应添加适当的错误检查,如弹栈时栈为空、压栈时栈已满等情况。 5. **应用场景** 顺序...

    C++程序设计原理与实践附录A

    - **定义**: C++是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程。 - **发展历程**: C++由Bjarne Stroustrup于1979年在贝尔实验室开始设计和实现,...

    c++笔试题 c++笔试题 c++笔试题

    了解内存的分配和释放,防止内存泄漏和悬空指针是编程中的重要技巧。 4. **类与对象**:C++支持面向对象编程,类是对象的蓝图,对象则是类的实例。掌握构造函数、析构函数、成员函数、封装、继承、多态等概念,能够...

    网上转摘的华为笔试题目及答案

    - **掌握沟通技巧**:良好的沟通能力不仅可以帮助你更好地表达自己,还能帮助你在团队协作中发挥更大的作用。 - **模拟面试**:参加模拟面试可以帮助你适应真实的面试环境,提高临场应变能力。 以上解析涵盖了华为...

    .Net的一些技巧 C#

    ### .Net的一些技巧与C#知识点详解 #### 1. 说说.NET框架与结构? - **结构**:在.NET框架中,结构是一种值类型的数据结构,它存储在栈上而不是堆上。当一个结构被赋值时,实际上复制的是整个结构的值,这意味着...

    一些C++小程序

    通过学习和分析这些小程序,可以更深入地理解C++语言的工作原理和编程技巧。实践是掌握编程技能的最佳途径,所以尝试编译和运行这些程序,查看它们如何实现上述知识点,将有助于提升你的C++编程能力。

    Think in C++ Volumn 2双页印刷

    《Think in C++ Volume 2》是一本专注于教授高级 C++ 编程技巧和技术的书籍,它作为第二卷,延续了第一卷的基础概念,并深入探讨了更复杂的主题。本书适合已经掌握了 C++ 基础知识并希望进一步提高编程技能的读者。 ...

    more Effective C# 改善C#的50个具体办法(中文版)

    20. **利用泛型(Generic)提高代码复用**:泛型允许创建类型参数化的类、接口和方法,提高代码的灵活性和效率。 21. **理解并使用委托和事件的弱引用**:弱引用防止委托引用阻止对象被垃圾回收,适用于长时间存在...

    C++基础大学教程例题

    在大学的C++基础课程中,初学者会接触到一系列的核心概念和编程技巧。"C++基础大学教程例题"这个主题旨在帮助初学者通过实际的编程例子深入理解C++语言。下面将详细介绍C++的基础知识,并结合可能在教程中出现的例题...

    Objective-C一些小技巧

    Objective-C是一门强大的...总的来说,Objective-C的这些小技巧和概念构成了其强大的面向对象编程基础,使得开发者能够构建出灵活、可维护的软件系统。理解和掌握这些技巧对于编写高质量的Objective-C代码至关重要。

    C#中数组做参数的小例子

    本篇文章将深入探讨如何在C#中使用数组作为函数参数,这是一项常见的编程技巧,尤其对于处理批量数据时非常有用。我们将通过实例来阐述这一概念。 首先,了解数组的基本概念是必要的。在C#中,数组可以是一维、二维...

    Visual C# 语言编程技术培训教材

    - 探讨C#中的高级编程技术,如泛型、委托、事件、异步编程等。 - **WinForm控件的高级使用:** - 进一步探索WinForm控件的高级特性和用法。 - **第六讲、C#的高级编程技术、异常、代表、系统环境信息(二)** -...

    C++随手笔记C++随手笔记

    - 使用`void*`指针可以存储任意类型的指针。 - 在进行类型转换时需要特别小心,以防止类型不匹配的问题。 #### 46. 函数指针 - 函数指针可以作为函数的参数或返回值。 - 使用函数指针可以实现回调等功能。 #### 47...

Global site tag (gtag.js) - Google Analytics