C语言实例_函数指针与指针函数
一、前言
在C和C++等程序设计语言中,指针函数和函数指针是两个不同的概念,但它们都与指针有关。
1.1 指针函数
指针函数是一个返回值类型为指针的函数。这意味着当你调用这个函数时,它会返回一个指向某种数据类型的指针。通常,这个指针可能指向动态分配的内存区域或某个数据结构。例如:
char* get_string(); // 这是一个指针函数,返回一个指向字符的指针
在这个例子中,get_string()
是一个指针函数,它返回一个指向char
类型数据的指针。
1.2 函数指针
函数指针是一个指针变量,它可以存储函数的地址,从而允许在运行时通过该指针来调用函数。这在需要传递函数作为参数或者需要在运行时决定调用哪个函数的情况下非常有用。例如:
void (*func_ptr)(int); // 这是一个函数指针,指向一个接收int参数且无返回值的函数
在这里,func_ptr
是一个函数指针,可以指向任何接收一个int
参数且没有返回值的函数。
1.3 使用示例
指针函数的使用
#include <stdio.h>
#include <stdlib.h>
char* get_string() {
char* str = malloc(20 * sizeof(char));
sprintf(str, "Hello, World!");
return str;
}
int main() {
char* str = get_string();
printf("%s\n", str);
free(str); // 释放动态分配的内存
return 0;
}
函数指针的使用
#include <stdio.h>
void print_hello(int num) {
printf("Hello %d times!\n", num);
}
void print_goodbye(int num) {
printf("Goodbye %d times!\n", num);
}
int main() {
void (*print_func)(int); // 函数指针声明
int num_times = 5;
print_func = &print_hello; // 函数指针指向print_hello函数
(*print_func)(num_times);
print_func = &print_goodbye; // 函数指针现在指向print_goodbye函数
(*print_func)(num_times);
return 0;
}
在这个例子中,print_func
是一个函数指针,它先指向print_hello
函数,然后指向print_goodbye
函数,并在运行时调用了这两个函数。
二、指针函数代码实例
指针函数在C语言中是一个非常强大的特性,允许函数返回一个指针。指针函数的使用场景多种多样,主要集中在需要返回动态分配的内存地址、创建复杂的数据结构、以及需要返回特殊类型(如文件描述符)的场合。
2.1 使用场景
(1)动态内存分配和管理 指针函数常用于动态分配内存并返回指向这块内存的指针。这是C语言中最常见的使用场景之一,例如使用malloc
, calloc
, realloc
和free
等函数。
(2)构建和操作数据结构 在构建链表、树、图等数据结构时,通常需要返回指向这些结构的节点的指针。指针函数可以返回指向这些节点的指针,使得函数可以在外部修改数据结构。
(3)文件处理 文件操作函数,如fopen
, 返回指向文件结构的指针,这个指针用于后续的读写操作。
(4)字符串处理 字符串操作函数,如strdup
, 返回一个指向新复制的字符串的指针。
(5)系统调用 一些系统调用,如getpid
, gettimeofday
等,返回指向特定系统信息的指针。
2.2 示例代码
示例1:动态内存分配
创建一个函数create_array
,接受一个整数size
作为参数,并返回一个指向包含size
个整数的动态分配数组的指针。
#include <stdio.h>
#include <stdlib.h>
// 创建一个整数数组并返回其指针
int* create_array(int size) {
int* array = (int*)malloc(size * sizeof(int));
if (array == NULL) {
fprintf(stderr, "Memory allocation failed.\n");
exit(1);
}
for (int i = 0; i < size; i++) {
array[i] = i; // 初始化数组元素
}
return array;
}
int main() {
int size = 5;
int* my_array = create_array(size);
// 输出数组元素
for (int i = 0; i < size; i++) {
printf("%d ", my_array[i]);
}
printf("\n");
free(my_array); // 释放内存
return 0;
}
示例2:构建链表节点
创建一个链表节点结构和一个函数create_node
,接受一个整数值并返回指向链表节点的指针。
#include <stdio.h>
#include <stdlib.h>
// 链表节点结构
typedef struct Node {
int data;
struct Node* next;
} Node;
// 创建一个链表节点并返回其指针
Node* create_node(int value) {
Node* new_node = (Node*)malloc(sizeof(Node));
if (new_node == NULL) {
fprintf(stderr, "Memory allocation failed.\n");
exit(1);
}
new_node->data = value;
new_node->next = NULL;
return new_node;
}
int main() {
Node* head = create_node(1); // 创建链表头节点
Node* second = create_node(2); // 创建第二个节点
head->next = second; // 将第二个节点链接到头节点
// 输出链表
Node* current = head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n");
// 释放内存
free(head);
free(second);
return 0;
}
这两个示例展示了如何使用指针函数来动态分配内存和构建数据结构,这些都是C语言中指针函数的典型应用。
三、函数指针代码实例
函数指针在C和C++等编程语言中是一个强大的工具,允许把函数当作数据一样进行传递和操作。函数指针的使用场景非常广泛,尤其在需要灵活性和可扩展性的场合。
3.1 使用场景
(1)回调函数 当需要将函数作为参数传递给另一个函数时,函数指针就变得非常重要。这在事件驱动编程、图形用户界面、库接口等方面非常常见。
(2)策略模式 函数指针可以用于实现策略模式,即在运行时选择算法或行为。例如,在排序算法中,可以根据需要选择升序或降序排序,或者在游戏开发中选择不同的AI策略。
(3)多态 在C语言中,由于缺乏面向对象的直接支持,函数指针可以用来模拟多态性。通过将不同的函数指针赋值给相同的变量,可以在运行时改变对象的行为。
(4)动态加载和链接 动态库中的函数可以通过函数指针在运行时被调用,这允许程序在运行时访问和使用未在编译时链接的代码。
(5)信号处理 在操作系统级别,信号处理函数通常是通过函数指针注册的,这样当特定信号发生时,可以执行相应的函数。
(6)定时器和事件循环 在实时系统和游戏引擎中,定时器和事件循环经常使用函数指针来注册和调度事件处理器。
3.2 示例代码
示例1:使用函数指针作为回调函数
创建一个简单的函数process_data
,接受一个整数和一个函数指针作为参数,然后调用这个函数指针对整数进行处理。
#include <stdio.h>
// 定义函数指针类型
typedef void (*ProcessFunc)(int);
// 数据处理函数
void process_data(int data, ProcessFunc func) {
func(data);
}
// 打印数据
void print_data(int data) {
printf("Data: %d\n", data);
}
// 加一后打印数据
void print_data_plus_one(int data) {
printf("Data + 1: %d\n", data + 1);
}
int main() {
int data = 42;
// 使用函数指针作为回调函数
process_data(data, print_data);
process_data(data, print_data_plus_one);
return 0;
}
示例2:使用函数指针实现策略模式
创建一个排序函数custom_sort
,接受一个数组、数组长度和一个比较函数指针作为参数。比较函数指针用于确定排序顺序。
#include <stdio.h>
// 定义比较函数指针类型
typedef int (*CompareFunc)(int, int);
// 数组排序函数
void custom_sort(int arr[], int n, CompareFunc compare) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (compare(arr[j], arr[j + 1]) > 0) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// 升序比较函数
int ascending_compare(int a, int b) {
return a - b;
}
// 降序比较函数
int descending_compare(int a, int b) {
return b - a;
}
int main() {
int arr[] = {5, 3, 8, 4, 2};
int n = sizeof(arr)/sizeof(arr[0]);
// 使用函数指针实现升序排序
custom_sort(arr, n, ascending_compare);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// 使用函数指针实现降序排序
custom_sort(arr, n, descending_compare);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
这两个示例展示了函数指针在C语言中的实际应用,包括作为回调函数和实现策略模式。
- 点赞
- 收藏
- 关注作者
评论(0)