函数指针与普通指针的本质区别在于指向目标不同,操作方式和用途也不同。1. 普通指针指向数据变量的内存地址,用于访问和修改数据;2. 函数指针指向函数的入口地址,用于调用函数;3. 函数指针的声明需明确返回类型和参数列表,如 int (*ptr)(int, int);4. 函数指针常用于回调函数、状态机等场景,提升代码灵活性;5. 函数指针存储的是编译时确定的函数地址,位于代码段,而普通指针指向运行时分配的数据地址;6. 使用函数指针可以动态改变程序行为,但语法复杂且可能影响性能和可读性。

函数指针和普通指针,本质上都是指针,但指向的目标和使用方式截然不同。普通指针指向的是变量(数据)的内存地址,而函数指针指向的是函数的入口地址。 这决定了它们的操作对象和用途。

函数指针,顾名思义,指向函数。 普通指针则指向数据。

函数指针的定义、使用以及背后的原理,还有它在C语言编程中的实际价值,是理解C语言高级特性的关键。
立即学习“C语言免费学习笔记(深入)”;
函数指针的声明看起来有点奇怪,但掌握了规律就好理解了。 例如,int (*ptr)(int, int); 声明了一个名为 ptr 的函数指针,它指向一个接受两个 int 参数并返回 int 值的函数。 注意括号的用法,(*ptr) 表示 ptr 是一个指针,而不是一个返回指针的函数。 如果不加括号,int *ptr(int, int); 就变成了声明一个返回 int* 的函数了。

使用函数指针时,可以直接通过指针调用函数,就像调用普通函数一样。 例如,如果有一个函数 int add(int a, int b) { return a + b; },你可以将 add 函数的地址赋给 ptr,然后通过 ptr(3, 5) 来调用 add 函数。
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int (*ptr)(int, int); // 声明一个函数指针
ptr = add; // 将 add 函数的地址赋给 ptr
int result = ptr(3, 5); // 通过 ptr 调用 add 函数
printf("Result: %d\n", result); // 输出:Result: 8
return 0;
}函数指针的类型由函数的返回类型和参数列表决定。 例如,int (*)(int, int) 是一种函数指针类型,表示指向一个接受两个 int 参数并返回 int 值的函数的指针。 普通指针的类型则由它指向的数据类型决定,例如 int* 指向 int 类型的数据。
这意味着,不同类型的函数指针之间不能直接赋值,除非进行类型转换。 这与普通指针类似,不同类型的指针之间也需要进行类型转换才能赋值。 举个例子,你不能直接将一个指向 char 的指针赋值给一个指向 int 的指针,除非你明确地告诉编译器你要这样做。
回调函数是函数指针最常见的应用场景之一。 回调函数是指将一个函数的指针作为参数传递给另一个函数,并在适当的时候被调用的函数。 这允许你在运行时动态地改变函数的行为。
例如,qsort 函数是 C 标准库中的一个排序函数,它接受一个比较函数的指针作为参数。 你可以通过提供不同的比较函数来控制 qsort 函数的排序方式。
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int main() {
int arr[] = {5, 2, 8, 1, 9};
int n = sizeof(arr) / sizeof(arr[0]);
qsort(arr, n, sizeof(int), compare); // 使用 compare 函数进行排序
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]); // 输出:1 2 5 8 9
}
printf("\n");
return 0;
}qsort 函数并不知道如何比较两个元素的大小,它只是简单地调用你提供的 compare 函数来完成比较。 这种方式使得 qsort 函数具有很强的通用性,可以用于排序各种类型的数据。
函数指针存储的是函数的入口地址,这个地址通常是在编译时就确定的,存储在代码段中。 而普通指针存储的是变量的内存地址,这个地址是在程序运行时分配的,存储在数据段或堆栈中。
函数本身并不占用额外的数据内存,它只是一段代码。 函数指针只是指向这段代码的入口点。 普通指针则指向实际的数据,这些数据需要占用一定的内存空间。
状态机是一种常用的编程模型,用于描述对象在不同状态下的行为。 函数指针可以用于实现状态机的状态转移逻辑。 每个状态可以对应一个函数,状态转移可以通过改变函数指针的指向来实现。
例如,一个简单的灯泡状态机可以有两个状态:亮和灭。 每个状态对应一个函数,turn_on 和 turn_off。 状态转移可以通过改变函数指针的指向来实现。
#include <stdio.h>
void turn_on() {
printf("灯亮了\n");
}
void turn_off() {
printf("灯灭了\n");
}
int main() {
void (*state)(); // 声明一个函数指针,指向无参数无返回值的函数
state = turn_off; // 初始状态为灭
state(); // 调用 turn_off 函数,输出:灯灭了
state = turn_on; // 切换到亮状态
state(); // 调用 turn_on 函数,输出:灯亮了
return 0;
}这种方式使得状态机的状态转移逻辑更加清晰和易于维护。 你可以很容易地添加新的状态或修改状态转移逻辑,而无需修改大量的代码。
函数指针的优势在于它可以提高代码的灵活性和可扩展性。 通过使用函数指针,你可以在运行时动态地改变函数的行为,而无需重新编译代码。 这对于需要处理各种不同情况的程序来说非常有用。
然而,函数指针也有一些局限性。 首先,函数指针的语法比较复杂,容易出错。 其次,函数指针会增加代码的间接性,可能会降低程序的性能。 最后,函数指针会使代码的可读性降低,因为你需要理解函数指针的含义才能理解代码的逻辑。
总的来说,函数指针是一种强大的工具,但需要谨慎使用。 只有在真正需要提高代码的灵活性和可扩展性时才应该使用函数指针。 在其他情况下,使用普通函数可能更加简单和高效。
以上就是c语言中函数指针和普通指针的区别是什么_函数指针和普通指针有什么区别的详细内容,更多请关注php中文网其它相关文章!
C语言怎么学习?C语言怎么入门?C语言在哪学?C语言怎么学才快?不用担心,这里为大家提供了C语言速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号