【c语言】通用指针和函数指针特性学习笔记
特性介绍
通用指针
定义:通用指针类型,即void*,它能够指向任意类型的数据。这意味着你可以把任意类型的指针赋值给void*类型的指针变量。
重要特性:不指定类型,与其他具体类型的指针(如int*、char*)不同,void*不指定所指向数据的类型。因此,编译器不清楚它指向的数据占用多少字节,也不知道如何解释这些数据。
简单的案例:
#include <stdio.h>
// 通用交换函数
void swap(void *a, void *b, size_t size) {
char temp[size];
memcpy(temp, a, size);
memcpy(a, b, size);
memcpy(b, temp, size);
}
int main() {
int x = 10, y = 20;
swap(&x, &y, sizeof(int));
printf("x = %d, y = %d\n", x, y);
double a = 3.14, b = 2.71;
swap(&a, &b, sizeof(double));
printf("a = %f, b = %f\n", a, b);
return 0;
}
其他注意事项:
1.int类型的指针或者float类型的基础类型的指针可以直接传给void*类型的指针,无需进行显式的强制类型转换。
2.不能直接解引用 void* 指针:因为 void* 不指定所指向数据的类型,所以不能直接对其进行解引用操作。若要访问 void* 指针所指向的数据,需要先将其显式转换为具体类型的指针。
3.类型安全问题:尽管可以将任意类型的指针赋值给 void* 指针,但在使用 void* 指针时,要确保知道它实际指向的数据类型,不然可能会引发未定义行为。
4.不要把函数指针赋值给void*,部分编译器可能不支持:根据 C 语言标准(如 C11 标准的 6.3.2.3 节第 8 条),把函数指针赋值给void*或者进行反向赋值的行为,并没有被明确规定。虽然有些编译器可能会支持这种赋值操作,但这样做会让代码的可移植性变差。更为妥当的处理方式是使用函数指针类型,或者借助_Generic关键字(从 C11 标准开始支持)来处理不同类型的函数指针
函数指针
定义:
函数指针的定义格式如下:
返回值类型 (*指针变量名)(参数列表);
其中,返回值类型 是函数的返回值类型,* 表明这是一个指针,指针变量名 是函数指针的名称,参数列表 是函数的参数类型和数量。
函数指针
简单的案例:
#include <stdio.h>
// 定义两个简单的运算函数
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int main() {
int num1 = 10, num2 = 5;
int result;
// 定义一个函数指针,指向返回值为 int,参数为两个 int 的函数
int (*operation)(int, int);
// 让函数指针指向 add 函数
operation = add;
result = operation(num1, num2);
printf("加法结果: %d\n", result);
// 让函数指针指向 subtract 函数
operation = subtract;
result = operation(num1, num2);
printf("减法结果: %d\n", result);
return 0;
}
以下是综合使用上述两种指针的案例,以我自己写的按钮触发函数为例子
ps:【此句为后续补充】,下面的count不要使用void*,还是老老实实的使用uint16*,否则当传入的指针类型不是uint16的时候会发生越界或者截断
void my_key(gpio_pin_enum switch_pin,uint16 time,void (*no_para)(void),void (*no_para_no)(void) ,void* count)//放入中断中使用
{
uint8 b=gpio_get_level(switch_pin);
if(b==0)//按键按下
{
(*(uint16*)count)++;
if(*(uint16*)count>time)//
{
no_para();
*(uint16*)count=0;
}
}
else
{
no_para_no();
*(uint16*)count=0;
}
}
更多推荐

所有评论(0)