C语言指针与函数 #
一、指针作为函数参数 #
1.1 基本用法 #
c
#include <stdio.h>
void modify(int* p) {
*p = 100;
}
int main() {
int a = 10;
printf("修改前: %d\n", a);
modify(&a);
printf("修改后: %d\n", a);
return 0;
}
输出:
text
修改前: 10
修改后: 100
1.2 交换两个数 #
c
#include <stdio.h>
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 10, y = 20;
printf("交换前: x=%d, y=%d\n", x, y);
swap(&x, &y);
printf("交换后: x=%d, y=%d\n", x, y);
return 0;
}
1.3 为什么需要指针参数 #
C语言是值传递,指针参数可以:
- 修改调用者的变量
- 避免复制大数据
- 返回多个值
1.4 返回多个值 #
c
#include <stdio.h>
void min_max(int arr[], int size, int* min, int* max) {
*min = arr[0];
*max = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] < *min) *min = arr[i];
if (arr[i] > *max) *max = arr[i];
}
}
int main() {
int arr[] = {3, 1, 4, 1, 5, 9, 2, 6};
int min_val, max_val;
min_max(arr, 8, &min_val, &max_val);
printf("最小值: %d, 最大值: %d\n", min_val, max_val);
return 0;
}
二、数组作为函数参数 #
2.1 一维数组 #
c
#include <stdio.h>
int sum(int arr[], int size) {
int total = 0;
for (int i = 0; i < size; i++) {
total += arr[i];
}
return total;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
printf("总和: %d\n", sum(arr, 5));
return 0;
}
等价写法:
c
int sum(int* arr, int size);
2.2 指针范围参数 #
c
#include <stdio.h>
int sum(int* start, int* end) {
int total = 0;
while (start < end) {
total += *start++;
}
return total;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
printf("总和: %d\n", sum(arr, arr + 5));
return 0;
}
2.3 二维数组 #
c
#include <stdio.h>
void print_matrix(int rows, int cols, int mat[rows][cols]) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%2d ", mat[i][j]);
}
printf("\n");
}
}
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
print_matrix(3, 4, matrix);
return 0;
}
2.4 使用行指针 #
c
#include <stdio.h>
void print_matrix(int (*mat)[4], int rows) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 4; j++) {
printf("%2d ", mat[i][j]);
}
printf("\n");
}
}
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
print_matrix(matrix, 3);
return 0;
}
三、返回指针的函数 #
3.1 基本用法 #
c
#include <stdio.h>
int* find_max(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() {
int arr[] = {3, 1, 4, 1, 5, 9, 2, 6};
int* max = find_max(arr, 8);
printf("最大值: %d\n", *max);
return 0;
}
3.2 返回动态分配内存 #
c
#include <stdio.h>
#include <stdlib.h>
int* create_array(int size) {
int* arr = (int*)malloc(size * sizeof(int));
if (arr == NULL) {
return NULL;
}
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
}
return arr;
}
int main() {
int* arr = create_array(5);
if (arr != NULL) {
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
}
return 0;
}
3.3 不要返回局部变量地址 #
c
int* bad_func() {
int local = 10;
return &local;
}
错误:函数返回后,局部变量被销毁。
3.4 返回静态变量地址 #
c
#include <stdio.h>
int* get_counter() {
static int count = 0;
count++;
return &count;
}
int main() {
printf("%d\n", *get_counter());
printf("%d\n", *get_counter());
printf("%d\n", *get_counter());
return 0;
}
四、函数指针 #
4.1 声明函数指针 #
c
int (*func_ptr)(int, int);
这是一个指向 int (int, int) 类型函数的指针。
4.2 使用函数指针 #
c
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int main() {
int (*op)(int, int);
op = add;
printf("10 + 5 = %d\n", op(10, 5));
op = subtract;
printf("10 - 5 = %d\n", op(10, 5));
return 0;
}
4.3 函数指针数组 #
c
#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() {
int (*operations[])(int, int) = {add, subtract, multiply, divide};
char* names[] = {"加", "减", "乘", "除"};
int a = 20, b = 5;
for (int i = 0; i < 4; i++) {
printf("%d %s %d = %d\n", a, names[i], b, operations[i](a, b));
}
return 0;
}
4.4 回调函数 #
c
#include <stdio.h>
#include <stdlib.h>
int compare_asc(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int compare_desc(const void* a, const void* b) {
return (*(int*)b - *(int*)a);
}
void print_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr[] = {3, 1, 4, 1, 5, 9, 2, 6};
int size = sizeof(arr) / sizeof(arr[0]);
qsort(arr, size, sizeof(int), compare_asc);
printf("升序: ");
print_array(arr, size);
qsort(arr, size, sizeof(int), compare_desc);
printf("降序: ");
print_array(arr, size);
return 0;
}
4.5 高阶函数 #
c
#include <stdio.h>
void process_array(int arr[], int size, int (*processor)(int)) {
for (int i = 0; i < size; i++) {
arr[i] = processor(arr[i]);
}
}
int double_it(int x) { return x * 2; }
int square_it(int x) { return x * x; }
void print_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr1[] = {1, 2, 3, 4, 5};
int arr2[] = {1, 2, 3, 4, 5};
int size = 5;
process_array(arr1, size, double_it);
printf("翻倍: ");
print_array(arr1, size);
process_array(arr2, size, square_it);
printf("平方: ");
print_array(arr2, size);
return 0;
}
五、const与指针参数 #
5.1 保护数据不被修改 #
c
#include <stdio.h>
int sum(const int* arr, int size) {
int total = 0;
for (int i = 0; i < size; i++) {
total += arr[i];
}
return total;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
printf("总和: %d\n", sum(arr, 5));
return 0;
}
5.2 字符串参数 #
c
#include <stdio.h>
#include <string.h>
size_t safe_strlen(const char* str) {
return strlen(str);
}
int main() {
const char* msg = "Hello";
printf("长度: %zu\n", safe_strlen(msg));
return 0;
}
六、实战应用 #
6.1 通用排序 #
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[20];
int age;
} Person;
int compare_by_age(const void* a, const void* b) {
return ((Person*)a)->age - ((Person*)b)->age;
}
int compare_by_name(const void* a, const void* b) {
return strcmp(((Person*)a)->name, ((Person*)b)->name);
}
int main() {
Person people[] = {
{"Alice", 25},
{"Bob", 20},
{"Charlie", 30}
};
int size = 3;
qsort(people, size, sizeof(Person), compare_by_age);
printf("按年龄排序:\n");
for (int i = 0; i < size; i++) {
printf("%s: %d\n", people[i].name, people[i].age);
}
qsort(people, size, sizeof(Person), compare_by_name);
printf("\n按姓名排序:\n");
for (int i = 0; i < size; i++) {
printf("%s: %d\n", people[i].name, people[i].age);
}
return 0;
}
6.2 策略模式 #
c
#include <stdio.h>
typedef int (*Strategy)(int, int);
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 calculate(int a, int b, Strategy strategy) {
return strategy(a, b);
}
int main() {
printf("10 + 5 = %d\n", calculate(10, 5, add));
printf("10 - 5 = %d\n", calculate(10, 5, subtract));
printf("10 * 5 = %d\n", calculate(10, 5, multiply));
return 0;
}
七、总结 #
指针参数 #
| 用途 | 说明 |
|---|---|
| 修改调用者变量 | 传递地址 |
| 避免复制大数据 | 传递指针 |
| 返回多个值 | 指针参数 |
返回指针 #
- 可以返回动态分配的内存
- 可以返回静态变量地址
- 不能返回局部变量地址
函数指针 #
c
int (*func_ptr)(int, int);
用于回调函数、策略模式等。
const保护 #
c
void func(const int* p);
防止函数修改数据。
下一步,让我们学习函数指针!
最后更新:2026-03-26