struct { void (*fun)(void); char *tip; }

这篇博客介绍了如何在TQ2440板子的程序中使用结构体数组CmdTip来存储函数指针和提示信息,并展示了如何通过用户输入选择并调用相应函数。

//

//

//

struct {

void (*fun)(void);

char *tip;

}CmdTip[] = {

{ Temp_function, "Please input 1-11 to select test" } ,

{ BUZZER_PWM_Test, "Test PWM" } ,

{ RTC_Display, "RTC time display" } ,

{ Test_Adc, "Test ADC" } ,

{ KeyScan_Test, "Test interrupt and key scan" } ,

{ Test_Touchpanel, "Test Touchpanel" } ,

{ Lcd_TFT_Test, "Test TFT LCD" } ,

{ Test_Iic, "Test IIC EEPROM" } ,

{ PlayMusicTest, "UDA1341 play music" } ,

{ RecordTest, "UDA1341 record voice" } ,

{ Test_SDI, "Test SD Card" } ,

{ Camera_Test, "Test CMOS Camera"},

{ 0, 0}

};

//

//

//

while(1)

{

U8 idx;

Uart_Printf("\nPlease select function : \n");

for(i=0; CmdTip[i].fun!=0; i++)

Uart_Printf("%d : %s\n", i, CmdTip[i].tip);

idx = Uart_GetIntNum_GJ() ;

if(idx<i)

{

(*CmdTip[idx].fun)();

Delay(20);

Uart_Init( 0,115200 );

}

}

以上是一个结构体数组,是TQ2440板子资料中的一段程序。

该结构体采用结构体类型变量的第三种定义方法,直接定义结构体类型变量并赋值。结构中有两个成员,一个指针函数其返回值类型为void,参数类型也为void。当使用CmdTip[i].fun返回的是一个函数的地址,除最后一个元素外,返回的地址值不为0,而结构体数组的最后一个元素为{0,0},其目的就在于结束循环。

struct { void (*fun)(void); char *tip; }_攻城步兵_新浪博客

在 C 语言中,`void *fun` 是一个**返回通用指针的函数声明**,表示函数 `fun` 返回一个 `void *` 类型的指针(即不指定具体数据类型的指针)。以下是详细解释: --- ### **1. `void *fun` 的含义** #### **(1) 基本定义** - **`void *fun`** 声明了一个名为 `fun` 的函数,该函数: - **返回值**:返回一个 `void *` 类型的指针(可指向任意类型的数据)。 - **参数列表**:未指定参数(可能是 `void fun(void)` 的简写,也可能是接受任意参数的旧式 C 声明)。 #### **(2) 常见形式** ```c void *fun(); // 旧式 C 声明:可能接受任意参数(不推荐) void *fun(void); // 明确声明无参数(推荐) ``` - 在 C++ 中,`void *fun()` 和 `void *fun(void)` 完全等价,均表示无参数。 --- ### **2. `void *fun` 的用途** #### **(1) 返回通用指针** - 适用于需要返回不确定类型指针的场景,例如: - 动态内存分配(如 `malloc` 返回 `void *`,用户可转换为 `int *`、`char *` 等)。 - 通用数据结构(如链表、哈希表的节点可能返回 `void *` 存储任意数据)。 #### **(2) 示例代码** ```c #include <stdlib.h> // 示例 1:返回动态分配的内存 void *allocate_int(int value) { int *p = (int *)malloc(sizeof(int)); if (p != NULL) { *p = value; } return p; // 返回 void* 类型(实际是 int*) } // 示例 2:返回结构体指针 typedef struct { int x; int y; } Point; void *create_point(int x, int y) { Point *p = (Point *)malloc(sizeof(Point)); if (p != NULL) { p->x = x; p->y = y; } return p; // 返回 void* 类型(实际是 Point*) } int main() { // 使用示例 1 int *num = (int *)allocate_int(42); printf("%d\n", *num); free(num); // 使用示例 2 Point *pos = (Point *)create_point(10, 20); printf("(%d, %d)\n", pos->x, pos->y); free(pos); return 0; } ``` --- ### **3. 关键注意事项** #### **(1) 必须强制类型转换** - `void *` 返回后需转换为具体类型才能解引用: ```c int *ptr = (int *)fun(); // 转换为 int* ``` - 直接解引用 `void *` 会导致编译错误。 #### **(2) 安全性** - 需确保转换后的类型与实际数据类型匹配,否则可能引发未定义行为(如内存越界、数据损坏)。 #### **(3) 与 `void fun()` 的区别** - `void *fun`:返回指针,无返回值(`void`)。 - `void fun()`:无返回值,且可能无参数(C 中需明确 `void` 避免歧义)。 --- ### **4. 常见问题** #### **(1) 为什么 `malloc` 返回 `void *`?** - 通用性:用户可自由将返回的指针转换为所需类型(如 `int *`、`struct *`)。 #### **(2) `void *fun` 可以返回函数指针吗?** - 不可以。`void *` 是数据指针,与函数指针(如 `int (*)()`)不兼容。需使用 `typedef` 明确类型。 #### **(3) C 和 C++ 中 `void *fun` 的差异?** - 在 C++ 中,`void *` 到其他指针类型的转换需显式静态转换(`static_cast`)。 - 在 C 中,允许隐式转换(但显式转换更安全)。 #### **(4) 如何避免 `void *` 的滥用?** - 使用泛型编程(如 C++ 模板)或特定类型指针替代。 - 在 C 中,可通过 `typedef` 定义具体指针类型提高可读性。 #### **(5) `void *fun` 和 `int *fun` 的区别?** - `void *fun` 更通用,但需手动转换;`int *fun` 直接返回 `int` 类型指针,类型安全但灵活性低。 --- ### **5. 关键总结** | 问题 | 答案 | |-------------------------------|----------------------------------------------------------------------| | **`void *fun` 的含义** | 返回 `void *` 类型指针的函数,指向任意类型数据。 | | **是否需要类型转换?** | 是的,使用前必须转换为具体指针类型。 | | **典型用途** | 动态内存分配、通用数据结构(如链表、哈希表)。 | | **与 `void fun()` 的区别** | 前者返回指针,后者无返回值(C 中需明确 `void` 避免歧义)。 | --- ### **扩展问题** #### **Q1: `void *fun` 可以返回局部变量的地址吗?** - 不可以!局部变量在函数返回后失效,返回其地址会导致悬空指针。 #### **Q2: 如何设计一个安全的 `void *fun` 接口?** - 明确文档说明返回指针的实际类型和生命周期管理责任(如是否需调用者释放内存)。 #### **Q3: C 中 `void *fun` 和 `void *fun(void)` 的区别?** - 在 C 中,`void *fun()` 可能接受任意参数;`void *fun(void)` 明确无参数(推荐)。 #### **Q4: `void *fun` 在多线程环境中安全吗?** - 取决于实现:若返回动态分配的内存或全局数据,需同步访问;否则(如返回局部变量地址)绝对不安全。 #### **Q5: 为什么 `pthread_create` 的线程函数返回 `void *`?** - 允许线程返回任意类型的结果(如 `int`、结构体等),由主线程通过 `pthread_join` 获取并转换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心超人dev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值