指针与函数

深入理解指针与函数

指针与函数的结合使用是C语言编程的高级技巧,掌握这一技能对于编写高效、灵活的代码至关重要。东巴文(db-w.cn) 将带你深入探索指针与函数的关系。

💡 东巴文观点:指针作为函数参数可以实现引用传递,指针作为函数返回值可以返回多个值,函数指针可以实现回调机制。

指针作为函数参数

基本概念

#include <stdio.h>

void modifyValue(int *ptr) {
    *ptr = 100;
}

int main() {
    printf("=== 东巴文指针作为函数参数 ===\n\n");
    
    int num = 10;
    
    printf("调用前:num = %d\n", num);
    
    modifyValue(&num);
    
    printf("调用后:num = %d\n", num);
    
    return 0;
}

东巴文说明

  • 指针参数实现了引用传递
  • 函数内可以修改实参的值
  • 避免了值传递的数据复制

交换两个变量

#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    printf("=== 东巴文交换两个变量 ===\n\n");
    
    int num1 = 10, num2 = 20;
    
    printf("交换前:num1 = %d, num2 = %d\n", num1, num2);
    
    swap(&num1, &num2);
    
    printf("交换后:num1 = %d, num2 = %d\n", num1, num2);
    
    return 0;
}

数组作为函数参数

#include <stdio.h>

// 数组作为参数退化为指针
void printArray(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

void modifyArray(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        arr[i] *= 2;
    }
}

int main() {
    printf("=== 东巴文数组作为函数参数 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    printf("原数组:\n");
    printArray(arr, size);
    
    modifyArray(arr, size);
    
    printf("修改后:\n");
    printArray(arr, size);
    
    return 0;
}

字符串作为函数参数

#include <stdio.h>

// 字符串作为参数
void printString(const char *str) {
    printf("%s\n", str);
}

size_t stringLength(const char *str) {
    const char *ptr = str;
    while (*ptr != '\0') {
        ptr++;
    }
    return ptr - str;
}

int main() {
    printf("=== 东巴文字符串作为函数参数 ===\n\n");
    
    char *str = "Hello, 东巴文";
    
    printf("字符串:");
    printString(str);
    
    printf("长度:%zu\n", stringLength(str));
    
    return 0;
}

指针作为函数返回值

返回指针

#include <stdio.h>

// 返回较大值的指针
int *max(int *a, int *b) {
    return (*a > *b) ? a : b;
}

int main() {
    printf("=== 东巴文返回指针 ===\n\n");
    
    int num1 = 10, num2 = 20;
    
    int *result = max(&num1, &num2);
    
    printf("num1 = %d\n", num1);
    printf("num2 = %d\n", num2);
    printf("较大值:%d\n", *result);
    
    return 0;
}

返回数组指针

#include <stdio.h>

// 返回数组中的最大值指针
int *findMax(int *arr, int size) {
    int *max = arr;
    for (int i = 1; i < size; i++) {
        if (arr[i] > *max) {
            max = &arr[i];
        }
    }
    return max;
}

int main() {
    printf("=== 东巴文返回数组指针 ===\n\n");
    
    int arr[] = {30, 10, 50, 20, 40};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    int *max = findMax(arr, size);
    
    printf("数组:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n最大值:%d\n", *max);
    
    return 0;
}

返回字符串指针

#include <stdio.h>

// 返回字符串中的某个字符指针
char *findChar(char *str, char ch) {
    while (*str != '\0') {
        if (*str == ch) {
            return str;
        }
        str++;
    }
    return NULL;
}

int main() {
    printf("=== 东巴文返回字符串指针 ===\n\n");
    
    char str[] = "Hello, 东巴文";
    char ch = '东';
    
    printf("字符串:%s\n", str);
    printf("查找字符:%c\n", ch);
    
    char *result = findChar(str, ch);
    
    if (result != NULL) {
        printf("找到字符:%c\n", *result);
        printf("位置:%ld\n", result - str);
    } else {
        printf("未找到字符\n");
    }
    
    return 0;
}

注意事项

#include <stdio.h>
#include <stdlib.h>

// ❌ 错误:返回局部变量的指针
int *badFunction() {
    int local = 10;
    return &local;  // 错误:返回局部变量的地址
}

// ✅ 正确:返回静态变量的指针
int *goodFunction() {
    static int local = 10;
    return &local;
}

// ✅ 正确:返回动态分配的内存
int *dynamicFunction() {
    int *ptr = (int *)malloc(sizeof(int));
    *ptr = 10;
    return ptr;
}

int main() {
    printf("=== 东巴文返回指针的注意事项 ===\n\n");
    
    // int *ptr1 = badFunction();  // 错误
    int *ptr2 = goodFunction();    // 正确
    int *ptr3 = dynamicFunction(); // 正确
    
    printf("静态变量:%d\n", *ptr2);
    printf("动态内存:%d\n", *ptr3);
    
    // 释放动态内存
    free(ptr3);
    
    return 0;
}

东巴文说明

  • 不能返回局部变量的指针
  • 可以返回静态变量的指针
  • 可以返回动态分配的内存指针
  • 可以返回参数传入的指针

函数指针

函数指针的基本概念

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

int main() {
    printf("=== 东巴文函数指针基本概念 ===\n\n");
    
    // 声明函数指针
    int (*operation)(int, int);
    
    // 指向add函数
    operation = add;
    printf("add(10, 5) = %d\n", operation(10, 5));
    
    // 指向subtract函数
    operation = subtract;
    printf("subtract(10, 5) = %d\n", operation(10, 5));
    
    return 0;
}

东巴文说明

  • 函数指针是指向函数的指针
  • 函数名是函数的入口地址
  • 函数指针可以动态调用不同的函数

函数指针数组

#include <stdio.h>

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return a / b; }

int main() {
    printf("=== 东巴文函数指针数组 ===\n\n");
    
    // 函数指针数组
    int (*operations[])(int, int) = {add, subtract, multiply, divide};
    char *names[] = {"加法", "减法", "乘法", "除法"};
    
    int a = 20, b = 5;
    
    for (int i = 0; i < 4; i++) {
        printf("%s:operations[%d](%d, %d) = %d\n", 
               names[i], i, a, b, operations[i](a, b));
    }
    
    return 0;
}

函数指针作为参数

#include <stdio.h>

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

// 函数指针作为参数
int calculate(int a, int b, int (*operation)(int, int)) {
    return operation(a, b);
}

int main() {
    printf("=== 东巴文函数指针作为参数 ===\n\n");
    
    int a = 10, b = 5;
    
    printf("加法:%d\n", calculate(a, b, add));
    printf("减法:%d\n", calculate(a, b, subtract));
    
    return 0;
}

回调函数

#include <stdio.h>

// 回调函数类型
typedef int (*CompareFunc)(int, int);

// 升序比较
int ascending(int a, int b) {
    return a > b;
}

// 降序比较
int descending(int a, int b) {
    return a < b;
}

// 冒泡排序,使用回调函数
void bubbleSort(int *arr, int size, CompareFunc compare) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - 1 - i; j++) {
            if (compare(arr[j], arr[j + 1])) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    printf("=== 东巴文回调函数 ===\n\n");
    
    int arr1[] = {30, 10, 50, 20, 40};
    int arr2[] = {30, 10, 50, 20, 40};
    int size = sizeof(arr1) / sizeof(arr1[0]);
    
    printf("原数组:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr1[i]);
    }
    printf("\n");
    
    // 升序排序
    bubbleSort(arr1, size, ascending);
    printf("\n升序排序:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr1[i]);
    }
    printf("\n");
    
    // 降序排序
    bubbleSort(arr2, size, descending);
    printf("\n降序排序:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr2[i]);
    }
    printf("\n");
    
    return 0;
}

指针函数与函数指针

概念对比

#include <stdio.h>

// 指针函数:返回指针的函数
int *pointerFunction(int *arr, int size) {
    int *max = arr;
    for (int i = 1; i < size; i++) {
        if (arr[i] > *max) {
            max = &arr[i];
        }
    }
    return max;
}

// 函数指针:指向函数的指针
int normalFunction(int a, int b) {
    return a + b;
}

int main() {
    printf("=== 东巴文指针函数与函数指针 ===\n\n");
    
    // 指针函数
    int arr[] = {10, 20, 30, 40, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    int *max = pointerFunction(arr, size);
    printf("指针函数返回最大值:%d\n", *max);
    
    // 函数指针
    int (*funcPtr)(int, int) = normalFunction;
    int result = funcPtr(10, 20);
    printf("\n函数指针调用结果:%d\n", result);
    
    return 0;
}

东巴文说明

  • 指针函数:返回指针的函数
  • 函数指针:指向函数的指针
  • 注意区分这两种概念

东巴文最佳实践

1. 使用const保护指针参数

#include <stdio.h>

// ✅ 推荐:使用const保护指针参数
void printArray(const int *arr, int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    // ❌ 错误:不能修改const指针指向的值
    // arr[0] = 100;
}

int main() {
    printf("=== 东巴文使用const保护指针参数 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    printArray(arr, size);
    
    return 0;
}

2. 检查NULL指针

#include <stdio.h>

void safeFunction(int *ptr) {
    // ✅ 正确:检查NULL
    if (ptr == NULL) {
        printf("错误:空指针\n");
        return;
    }
    
    *ptr = 100;
}

int main() {
    printf("=== 东巴文检查NULL指针 ===\n\n");
    
    int num = 10;
    
    safeFunction(&num);
    printf("num = %d\n", num);
    
    safeFunction(NULL);
    
    return 0;
}

3. 使用typedef简化函数指针

#include <stdio.h>

// 使用typedef定义函数指针类型
typedef int (*OperationFunc)(int, int);

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

int main() {
    printf("=== 东巴文使用typedef简化函数指针 ===\n\n");
    
    OperationFunc operation;
    
    operation = add;
    printf("加法:%d\n", operation(10, 5));
    
    operation = subtract;
    printf("减法:%d\n", operation(10, 5));
    
    return 0;
}

东巴文验证清单

完成本章学习后,请确认:

  • 理解指针作为函数参数
  • 理解指针作为函数返回值
  • 掌握函数指针
  • 掌握函数指针数组
  • 掌握函数指针作为参数
  • 掌握回调函数
  • 理解指针函数与函数指针的区别
  • 掌握最佳实践

下一步学习

掌握指针与函数后,你可以继续学习:

如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!


东巴文(db-w.cn) - 让编程学习更简单

🎯 东巴文指针与函数提示:指针与函数的结合使用是C语言编程的高级技巧。在 db-w.cn,我们会通过大量实例帮你掌握指针与函数!