C语言中的函数机制详解
函数基础与定义
在C语言中,函数是程序的基本组成单元,用于封装可重复使用的代码块。每个函数都有独立的功能,并可通过调用执行。
示例:实现两个整数相加的函数:
#include <stdio.h>
// 函数声明(原型)
int add_numbers(int, int);
int main() {
int a = 15;
int b = 25;
int result;
result = add_numbers(a, b);
printf("Sum: %d\n", result);
return 0;
}
// 函数定义
int add_numbers(int x, int y) {
return x + y;
}
上述代码展示了函数的声明、调用和定义过程。函数必须先声明或定义后才能被调用,除非定义位于主函数之前。
参数传递方式
C语言支持两种主要的参数传递模式:值传递和地址传递。
值传递(按值调用)
实参的副本被传入函数,形参在栈上分配新内存空间。因此,在函数内部修改形参不会影响原始变量。
#include <stdio.h>
void modify_value(int val) {
val = 100; // 修改的是副本
printf("Inside function: %d\n", val);
}
int main() {
int num = 10;
printf("Before call: %d\n", num);
modify_value(num);
printf("After call: %d\n", num); // 值未改变
return 0;
}
地址传递(指针传参)
通过传递变量的地址,使函数能够直接操作原数据。常用于交换变量、修改多个值等场景。
#include <stdio.h>
void swap_values(int *p1, int *p2) {
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main() {
int x = 5, y = 8;
printf("Before swap: x=%d, y=%d\n", x, y);
swap_values(&x, &y);
printf("After swap: x=%d, y=%d\n", x, y);
return 0;
}
数组作为函数参数
当数组作为参数传递时,实际上传递的是首元素的地址,即一个指针。因此函数无法直接获取数组长度,需额外传入大小信息。
使用数组名传参
#include <stdio.h>
int calculate_sum(int arr[], int length) {
int total = 0;
for (int i = 0; i < length; ++i) {
total += arr[i];
}
return total;
}
int main() {
int data[] = {1, 3, 5, 7, 9};
int size = sizeof(data) / sizeof(data[0]);
int sum_result = calculate_sum(data, size);
printf("Total sum: %d\n", sum_result);
return 0;
}
使用指针方式处理字符串
编写一个去除字符串中所有空格的函数:
#include <stdio.h>
void remove_spaces(char *str) {
char *src = str;
char *dst = str;
while (*src != '\0') {
if (*src != ' ') {
*dst++ = *src;
}
src++;
}
*dst = '\0'; // 添加结束符
}
int main() {
char text[] = " hello world ";
printf("Original: [%s]\n", text);
remove_spaces(text);
printf("Cleaned: [%s]\n", text);
return 0;
}
返回指针的函数
这类函数返回一个内存地址,通常指向静态变量、动态分配内存或全局数据,避免返回局部变量地址(会导致野指针)。
正确返回静态缓冲区地址
#include <stdio.h>
#include <string.h>
char* create_greeting(int id) {
static char buffer[50]; // 静态存储周期,函数结束后仍有效
sprintf(buffer, "User-%d", id);
return buffer;
}
int main() {
char *msg1 = create_greeting(101);
char *msg2 = create_greeting(102);
printf("%s\n", msg1); // 输出 User-102(共用同一缓冲区)
printf("%s\n", msg2);
return 0;
}
整型转字符串实现
#include <stdio.h>
char* int_to_string(char *output, int value) {
int remainder;
int index = 0;
int start = 0, end;
// 处理负数
if (value < 0) {
output[index++] = '-';
value = -value;
start = 1;
}
// 提取每位数字
do {
remainder = value % 10;
output[index++] = remainder + '0';
value /= 10;
} while (value > 0);
output[index] = '\0';
// 反转数字部分
end = index - 1;
while (start < end) {
char tmp = output[start];
output[start] = output[end];
output[end] = tmp;
start++;
end--;
}
return output;
}
int main() {
char str_buffer[32];
int num;
printf("Enter an integer: ");
scanf("%d", &num);
int_to_string(str_buffer, num);
puts(str_buffer);
return 0;
}
函数指针的应用
函数指针可以指向某个函数的入口地址,从而实现动态调用、回调机制和多态行为。
基本语法与调用
#include <stdio.h>
int multiply(int a, int b) {
return a * b;
}
int divide(int a, int b) {
return b != 0 ? a / b : 0;
}
int main() {
int u = 20, v = 4;
int result;
// 声明函数指针
int (*func_ptr)(int, int);
func_ptr = multiply;
result = func_ptr(u, v);
printf("Multiply: %d\n", result);
func_ptr = divide;
result = (*func_ptr)(u, v);
printf("Divide: %d\n", result);
return 0;
}
函数指针广泛应用于事件处理、插件架构和算法选择等高级编程场景。