首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

将void指针(数据)转换为函数指针

将 void 指针转换为函数指针是一种 C 语言中的类型转换,它可以将一个 void 指针转换为一个函数指针。这种转换可以在 C 语言中用于实现一些特定的功能,例如实现回调函数或者动态加载函数。

以下是一个简单的示例代码,演示如何将 void 指针转换为函数指针:

代码语言:c
复制
#include<stdio.h>

void func() {
    printf("This is a function.\n");
}

int main() {
    void (*func_ptr)();
    void *void_ptr = &func;
    func_ptr = (void (*)()) void_ptr;
    (*func_ptr)();
    return 0;
}

在上面的代码中,我们首先定义了一个名为 func 的函数,然后在 main 函数中定义了一个函数指针 func_ptr 和一个 void 指针 void_ptr。我们将 func 函数的地址赋值给 void_ptr,然后使用类型转换将 void_ptr 转换为 func_ptr,最后通过 func_ptr 调用 func 函数。

需要注意的是,这种类型转换可能会导致一些问题,例如在不同的编译器和平台上可能会有不同的行为。因此,在使用这种类型转换时,需要特别小心,确保代码的可移植性和正确性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

你必须知道的指针基础-7.void指针与函数指针

一、不能动的“地址”—void指针 1.1 void指针初探 ?   void *表示一个“不知道类型”的指针,也就不知道从这个指针地址开始多少字节为一个数据。...和用int表示指针异曲同工,只是更明确是“指针”。   因此void*只能表示一个地址,不能用来&取值,也不能++--移动指针,因此不知道多少字节是一个数据单位。...函数指针是一个指向函数的指针,我们可以在C中轻松地定义一个函数指针: typedef void (*intFunc)(int i);   这里我们定义了一个无返回值的,只有一个int类型参数的函数指针intFunc...具体体现为for循环的代码是复用的,但是怎么处理这些数据不确定,因此把处理数据的逻辑由函数指针指定。...); // getMax 函数参数说明: // data 待比较数据数组的首地址,uniteSize单元字节个数 // length:数据的长度。

95820

C语言中的函数指针(*(void(*)())0)();

第三个问题:这个地方也是比较绕的地方,我们直接定义一个函数指针时要指明函数的返回值类型以及入参类型等,正常我们定义一个有一个int入参没有返回值的函数指针变量是 void (*funcp)(int);,...函数指针变量和整形变量相对比的话,void (*)(int) 就相当于int,而变量名funcp就和a等同了。...看到这里,再回头看看上面的(*(void(*)())0)();语句,你会发现(void(*)())0是将0强转成无返回值无入参的函数指针地址,外面一层就是取地址执行函数。...就是将0地址作为函数的入口地址进行执行。仔细分析一下就能明白。...函数指针相关的知识点还是很重要的,在一些较大的项目中,我们经常会看到这样的语句 typedef void (*HANDLER) (int);,这是定义一种函数指针类型,后面直接使用HANDLER就可以定义入参一个

1.8K20
  • 【C 语言】二级指针作为输入 ( 指针数组 | 将 二级指针 作为函数输入 | 抽象函数业务逻辑 )

    , 同时还要传入 一级指针的个数 ; 实参是 指针数组 , 形参 退化为 二级指针 , 需要人为指定 数组的元素个数 ; 验证指针合法性 : 函数中 , 只要是指针 , 就有可能为 NULL , 函数入口就要验证该指针合法性...printf("%s\n", array[i]); printf("%s\n", *(array + i)); } return 0; } 二、字符串排序 ---- 将...指针数组 作为参数 , 传入函数中 ; 函数的 二级指针 形参 , 既要作为 输入 , 又要作为输出 ; int sort_array(char **array, int num) { // 验证指针合法性...char *tmp; // 对 指针数组 进行排序 , 排序依据是 指针 指向的数据对比 for(i = 0; i < num; i++) { for...char *tmp; // 对 指针数组 进行排序 , 排序依据是 指针 指向的数据对比 for(i = 0; i < num; i++) { for

    60410

    【C++】多态 ⑩ ( 不建议将所有函数都声明为 virtual 虚函数 | 多态的理解层次 | 父类指针和子类指针步长 )

    是 根据 指针类型 进行的 , 指针 自增 ++ , 指针的地址值 会增加 指针类型字节大小 ; 指针的 步长 是 根据 指针 指向的 内存空间 的数据类型确定的 ; 子类 继承 父类 , 如果 子类...没有添加任何 成员函数 与 成员方法 , 那么子类指针 与 父类指针 的步长是相同的 ; 一、不建议将所有函数都声明为 virtual 虚函数 C++ 类中 , 每个 成员函数 都可以声明为 virtual...; 三、父类指针和子类指针步长 指针数据类型 : C++ 中 指针 是 数据类型 的 一种 , 对 指针 进行 自增 ++ 或 自减 – 操作 , 指针的 地址值 是根据 指针类型 改变的 ; 指针运算...是 根据 指针 指向的 内存空间 的数据类型确定的 ; 子类 继承 父类 , 如果 子类 没有添加任何 成员函数 与 成员方法 , 那么子类指针 与 父类指针 的步长是相同的 ; 代码示例 : #include...0; } 执行结果 : 执行 子类 virtual void fun(int a) 函数 执行 子类 virtual void fun(int a) 函数 执行 子类 virtual void fun

    30350

    【C 语言】数据类型本质 ( void 关键字作用 | 数据类型封装 | 作为 参数 或 返回值 代表无 | void* 指针赋值与被赋值 | void 类型变量不存在 )

    文章目录 一、数据类型封装 二、作为 参数 或 返回值 代表无 三、void* 指针赋值与被赋值 四、void 类型变量不存在 一、数据类型封装 ---- 实现函数 的 底层函数开发者 , 不想将 底层的数据结构...这就意味着 函数调用者 不知道 该类型的结构 ; void 数据类型 的 字面含义 是 " 无类型 " , void* 指针 是 " 无类型指针 " , void* 指针 可以指向任何数据类型 ; 下面的...memcpy 函数 , 传入的参数是 2 个 void* 指针 类型的 内存地址 , 该函数根本不关心 上层应用 传入的 实参 的 指针 具体指向什么数据类型的数据 , 传入的 指针类型 可以是...任何数据类型指针 ; void *memcpy(void *destin, void *source, unsigned n); 只要上层应用调用上述函数 , 就会从 void *source 指针指向的内存空间...int size); 如果分配内存完毕 , 将其赋值给一个其它类型指针时 , 需要强转 ; int *p = (int*) malloc(sizeof(int) * 10); 四、void 类型变量不存在

    2.5K10

    【C 语言】二级指针内存模型 ( 指针数组 | 二维数组 | 自定义二级指针 | 将 一、二 模型数据拷贝到 三 模型中 并 排序 )

    文章目录 一、指针数组 和 二维数组 数据 拷贝到 自定义二级指针 中 1、函数形参 设计规则 2、三种内存模型 对应 函数形参 指针退化规则 二、完整代码示例 一、指针数组 和 二维数组 数据 拷贝到...自定义二级指针 中 ---- 将 指针数组 和 二维数组 中的数据 拷贝到 自定义二级指针 内存模型中 , 并进行排序 ; 1、函数形参 设计规则 函数形参 设计规则 : 向 函数中 传入 二级指针..., 如果只是 使用 该 二级指针 指向的数据 , 可以 直接传入 二级指针 作为形参 ; 如果 需要 修改 二级指针 的指向 , 则需要 传入 三级指针 ; 2、三种内存模型 对应 函数形参 指针退化规则...char **p3 = NULL; 退化为 : // 二维指针 char **p3 代码示例 : /** * @brief copy_data 将 指针数组 和 二维数组 中的数据拷贝到...// 存储 p3 指向的一级指针个数 int len3 = 0; // 将 指针数组 二维数组 数据 拷贝到 二级指针 中 copy_data(p1, 3, p2, 3, &p3

    63220

    C++中的四种类型转换运算符

    int、int 转 double、const 转非 const、向上转型等;void 指针和具体类型指针之间的转换,例如void *转int *、char *转void *等;有转换构造函数或者类型转换函数的类与其它类型之间的转换...,例如 double 转 Complex(调用转换构造函数)、Complex 转 double(调用类型转换函数)。...不同类型的数据存储格式不一样,长度也不一样,用 A 类型的指针指向 B 类型的数据后,会按照 A 类型的方式来处理数据:如果是读取操作,可能会得到一堆没有意义的值;如果是写入操作,可能会使 B 类型的数据遭到破坏...指针转换为具体类型指针 void *p2 = static_castvoid*>(p1); //将具体类型指针,转换为void指针 double real= static_cast...将A*转换为int*,使用指针直接访问 private 成员刺穿了一个类的封装性,更好的办法是让类提供 get/set 函数,间接地访问成员变量。

    29920

    static_cast, dynamic_cast, const_cast 和 reinterpret_cast 怎么用

    主要用于, 基本数据类型之间的转换。如把 int 转换成 char,把 int 转换成 enum。这种转换的安全性需要开发人员来保证。 void 指针转换成目标类型的指针。...任何类型的表达式转换成 void 类型。 有转换构造函数或类型转换函数的类与其它类型之间的转换。...例如 double 转 Complex(调用转换构造函数)、Complex 转 double(调用类型转换函数)。 类层次结构中基类和子类之间指针或引用的转换。...void 指针转换为具体类型指针 void *p2 = static_castvoid*>(p1); // 将具体类型指针,转换为 void 指针 double real= static_cast指针之间的转换、int 和指针之间的转换(有些编译器只允许 int 转指针,不允许反过来)。

    1.8K10

    C++避坑---函数参数求值顺序和使用独立语句将newed对象存储于智能指针中

    char b() { cout << "b" << endl; return 'b'; } char c() { cout << "c" << endl; return 'c'; } void...newed对象与智能指针 我们使用《 Effective C++》中的例子,假设有两个函数priority和processWight,其对应的原型如下: int priority(); void processWidget...调用shared_ptr的构造函数(使用Widget对象的指针作为构造参数)。 调用priority函数。...Widget>构造函数的调用,完成“资源被创建”和“资源被管理对象接管”的无缝操作后,将智能指针传给processWidget函数。...总 结 虽然C++17已经能够规避到我们上面讨论过的风险,但是考虑到我们代码的普适性,仍建议我们:使用独立语句将newed对象存储于智能指针中,来保证“资源被创建”和“资源被管理对象接管”之间不会发生任何干扰

    53710

    C++中的类型转换

    ,不能转就编译失败 显式类型转化:需要用户自己处理 示例: void Test () { int i = 1; // 隐式类型转换 double d = i; printf...0; } void Test () { // // reinterpret_cast可以编译器以FUNC的定义方式去看待DoSomething函数 // 所以非常的BUG,下面转换函数指针的代码是不可移植的...用于基本数据类型之间的转换,如把int转换为char,这种带来安全性问题由程序员来保证 使用特点: 主要执行非多态的转换操作,用于代替C中通常的转换操作 隐式转换都建议使用static_cast...,非法访问等各种问题) const_cast,字面上理解就是去const属性 使用场景: 常量指针转换为非常量指针,并且仍然指向原来的对象 常量引用被转换为非常量引用,并且仍然指向原来的对象...尽量避免使用 reinterpreter_cast,仅仅重新解释类型,但没有进行二进制的转换 使用场景: 不到万不得已,不用使用这个转换符,高危操作 使用特点: reinterpret_cast可以将整型转换为指针

    1.9K20

    void和void*

    一:问:C语言中函数名前void可以有返回值吗? 在C语言中,如果一个函数被声明为void类型,那么它不能返回任何值。void在这里表示“无类型”或“空类型”,用于指定该函数不返回任何数据。...如果你需要函数返回某种类型的数据,那么你应该在函数定义中指定返回类型,而不是void。...二:问:C语言中函数名前void*可以有返回值吗? 是的,在C语言中,函数名定义为返回void*类型确实可以返回值。void*是一个特殊的指针类型,被称为通用指针或空指针,它可以指向任何类型的数据。...因此,当函数被定义为返回void*类型时,它可以返回一个指向任何类型数据的指针。...= NULL) { // 将void*转换为int*类型 int* intPtr = (int*)result; printf("The value is

    10210

    C++的四种转换(const_cast、static_cast、dynamic_cast、reinterpreter_cast)

    static_cast 相当于C语言中的强制转换:(类型)表达式或类型(表达式),用于各种隐式转换 非const转const、void*转指针、int和char相互转换 用于基类和子类之间的指针和引用转换...,非指针直接报错 向上转化是安全的,如果向下转能(指针或引用)成功但是不安全,结果未知; dynamic_cast 用于动态类型转换。...只能用于含有虚函数的类,必须用在多态体系种,用于类层次间的向上和向下转化。只能转指针或引用。向下转化时,如果是非法的对于指针返回NULL,对于引用抛异常。...比如将int转指针,可能会出问题,尽量少用;随意的转换编译都会通过,但是不安全的转换运行时会异常 错误的使用reinterpret_cast很容易导致程序的不安全,只有将转换后的类型值转换回到其原始类型...reinterpret_cast不能转换掉表达式的const 可以用在将void*转换为int类型 unsigned short Hash( void *p ) { unsigned int val

    3.6K10

    C指针之舞——指针探秘之旅(2)

    1.函数指针数组 函数指针就是一个指针,指针中所保存的地址中的内容是一个函数,同之前说过的数组指针相似,函数指针的定义为: 返回类型 (* 指针名) (函数参数) //eg: int (*pc)...x,int y) ,这样的话便是一个名为pa的函数,函数参数为 int x,int y,函数的返回类型时 int * 通过一个例子来认识一下函数指针数组: (*(void (*)())0)();...1.先看 void ( * ) ( ) ,这是一个标准的函数指针,函数返回类型为void,无函数参数 2.再看蓝色括号,该括号的代表强制转换,例如:(float)3 指的是将int类型的3转换为float...类型,在这里指的是将int类型的0转换为函数指针类型 3.看蓝色括号前面的 * ,这里是解地址符,指找到地址是0的函数 4.红色的括号包括着地址是0的这个函数(函数指针此时是0),后面再跟着一个绿色的括号...,相当于调用函数 所以该代码是一次函数调用,调用的是一个返回类型为void,无函数参数,函数名为0 的一个函数 2.回调函数 定义:回调函数是利用函数指针调⽤的函数,通俗来讲,只要是一个函数参数里面有函数指针

    7410

    C++的四种强制转换

    比如一个库函数导出的是double型数据,而我们使用该数据的函数的参数要求是整型,于是我们就需要对其进行转换。反之亦然。 整型和指针相互转换。...因为枚举一般只是用于表意,而实际参与运算的还是整型数据。 指针和无类型指针相互转换。一个典型的场景是,win32编程中,线程函数的入参要求是个LPVOID型数据。...而我们往往将类对象的指针传递进去,以方便我们调用封装在类中的相关函数和变量。即CreateThread时将指针转为void*型,在线程函数中将void*转为指针。 无关系类指针的相互转换。...驱动类函数执行的是类的this指针所指向的数据区。其实类的非静态函数的第一个参数——也是隐藏的参数是这个类的this指针。通过该this指针,该函数才能访问到对象的成员数据。...因为将Parent对象转换为Child指针存在潜在的安全问题。dynamic_cast将会对这次操作返回Null。以保证我们代码的运行安全性。

    2.3K30

    【C++从小白到大牛】C++的隐式和显示类型转换基础知识讲解

    隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败 显式类型转化:需要用户自己处理 void Test () { int i = 1; // 隐式类型转换...隐式类型转换 指针和整形 强制类型转换 不同类型的指针之间 强制类型转换 CPP: 构造函数只支持 内置类型->自定义类型之间,本质借助构造...为什么C++需要四种类型转换 C风格的转换格式很简单,但是有不少缺点的: 隐式类型转化有些情况下可能会出问题:比如数据精度丢失 显式类型转换将所有情况混合在一起,代码不够清晰 因此C++提出了自己的类型转化风格...4.4dynamic_cast dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换) 向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则,切片操作...,能成功则转换,不能则返回0 父类的对象不可能支持强制类型转换为子类,这里向下转换只支持对象的指针/引用 class A { public: // 父类必须含有虚函数 virtual void

    13410

    void*到底是怎样的存在?

    ,这样的道理也可用于很多场合的强制类型转换,例如将int类型指针转换为char型指针,并不会改变内存的实际内容,只是修改了解释方式而已。...因为对于这种通用型接口,你不知道用户的数据类型是什么,但是你必须能够处理用户的各种类型数据,因而会使用void*。void*能包容地接受各种类型的指针。...也就是说,如果你期望接口能够接受任何类型的参数,你可以使用void*类型。 但是在具体使用的时候,你必须转换为具体的指针类型。例如,你传入接口的是int*,那么你在使用的时候就应该按照int*使用。...void *)); 它的第三个参数就是比较函数,它接受的参数都是const void*,如果你的比较对象是一个结构体类型,那么你自己在实现compar函数的时候,也必须是转换为该结构体类型使用。...更多函数指针相关内容可以参考《高级指针话题-函数指针》,那里有更多的介绍。 总结 void*很强大,但是一定要在合适的时候使用;同时强转很逆天,但是一定要注意前后的类型是否真的能正确转换。

    57010

    【C++】类型转换

    隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败 显式类型转化:需要用户自己处理 例如: void Test() { int i = 1; // 隐式类型转换...2. reinterpret_cast reinterpret_cast 操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。...,类似于宏一样,当我们需要打印数据时,就直接用初始数据替代我们的 const 变量;所以当我们内存中的数据被修改了,但是编译器没有去内存中去取数据,所以 a 的值没有受影响。...4. dynamic_cast dynamic_cast 用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换),这个是C语言不具备的。...A a; B b; func(&a); func(&b); return 0; } 如果是 func(&b); 那么在 func 函数内就是将父类的对象重新转换为子类

    11710

    C++:特殊类设计和四种类型转换

    C++98: 1、将拷贝构造函数与赋值运算符重载只声明不定义。...1、隐式类型转换:编译器在编译阶段自动进行,能转就转,不能转就编译失败。相近类型才可以进行隐式类型转换 ,比如int和double 他们本质上都是表示数据的大小。...cout << a << endl; return 0; }  2.2.2 reinterpret_cast reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型...用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换) 向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则) 向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast...因为派生类会继承基类的虚函数表,所以通过这个虚函数表,我们就可以知道该类对象的父类,在转换的时候就可以用来判断对象有无继承关系。 所以虚函数对于正确的基类指针转换为子类指针是非常重要的。

    13510
    领券