Appearance
函数
函数是 C 语言程序的基本组成单元,用于实现代码的模块化和复用。
函数基础
函数定义
c
#include <stdio.h>
// 无返回值函数
void greet() {
printf("Hello, World!\n");
}
// 有返回值函数
int add(int a, int b) {
return a + b;
}
// 带参数的函数
void print_sum(int a, int b) {
printf("Sum: %d\n", a + b);
}
int main() {
greet();
int result = add(5, 3);
printf("5 + 3 = %d\n", result);
print_sum(10, 20);
return 0;
}函数声明
c
#include <stdio.h>
// 函数声明(原型)
int max(int a, int b);
void print_message(const char *msg);
int main() {
printf("Max: %d\n", max(10, 20));
print_message("Hello");
return 0;
}
// 函数定义
int max(int a, int b) {
return (a > b) ? a : b;
}
void print_message(const char *msg) {
printf("Message: %s\n", msg);
}参数传递
值传递
c
#include <stdio.h>
void modify_value(int x) {
x = 100; // 修改的是副本
printf("函数内 x = %d\n", x);
}
int main() {
int a = 10;
printf("调用前 a = %d\n", a);
modify_value(a);
printf("调用后 a = %d\n", a); // a 没有改变
return 0;
}指针传递
c
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void modify_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2;
}
}
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);
int arr[] = {1, 2, 3, 4, 5};
modify_array(arr, 5);
printf("数组: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}数组作为参数
c
#include <stdio.h>
// 数组参数退化为指针
int sum_array(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
// 等价写法
int sum_array2(int *arr, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
// 二维数组作为参数
void print_matrix(int rows, int cols, int matrix[][cols]) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
printf("Sum: %d\n", sum_array(arr, 5));
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
print_matrix(2, 3, matrix);
return 0;
}返回值
基本返回值
c
#include <stdio.h>
// 返回整数
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
// 返回浮点数
double average(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return (double)sum / size;
}
// 返回指针
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() {
printf("5! = %d\n", factorial(5));
int arr[] = {1, 2, 3, 4, 5};
printf("Average: %.2f\n", average(arr, 5));
int *max = find_max(arr, 5);
printf("Max: %d\n", *max);
return 0;
}多返回值
c
#include <stdio.h>
// 通过指针参数返回多个值
void minmax(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];
}
}
// 通过结构体返回多个值
typedef struct {
int min;
int max;
double avg;
} Stats;
Stats get_stats(int arr[], int size) {
Stats stats;
stats.min = arr[0];
stats.max = arr[0];
int sum = arr[0];
for (int i = 1; i < size; i++) {
sum += arr[i];
if (arr[i] < stats.min) stats.min = arr[i];
if (arr[i] > stats.max) stats.max = arr[i];
}
stats.avg = (double)sum / size;
return stats;
}
int main() {
int arr[] = {5, 2, 8, 1, 9, 3};
int min, max;
minmax(arr, 6, &min, &max);
printf("Min: %d, Max: %d\n", min, max);
Stats stats = get_stats(arr, 6);
printf("Min: %d, Max: %d, Avg: %.2f\n", stats.min, stats.max, stats.avg);
return 0;
}递归函数
基本递归
c
#include <stdio.h>
// 阶乘
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
// 斐波那契数列
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
// 求和
int sum(int n) {
if (n <= 0) return 0;
return n + sum(n - 1);
}
// 最大公约数
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
int main() {
printf("5! = %d\n", factorial(5));
printf("fib(10) = %d\n", fibonacci(10));
printf("sum(100) = %d\n", sum(100));
printf("gcd(48, 18) = %d\n", gcd(48, 18));
return 0;
}递归与迭代
c
#include <stdio.h>
// 递归版本
int fib_recursive(int n) {
if (n <= 1) return n;
return fib_recursive(n - 1) + fib_recursive(n - 2);
}
// 迭代版本(更高效)
int fib_iterative(int n) {
if (n <= 1) return n;
int a = 0, b = 1;
for (int i = 2; i <= n; i++) {
int temp = a + b;
a = b;
b = temp;
}
return b;
}
// 尾递归
int factorial_tail(int n, int acc) {
if (n <= 1) return acc;
return factorial_tail(n - 1, n * acc);
}
int factorial(int n) {
return factorial_tail(n, 1);
}
int main() {
printf("递归 fib(20): %d\n", fib_recursive(20));
printf("迭代 fib(20): %d\n", fib_iterative(20));
printf("尾递归 5!: %d\n", factorial(5));
return 0;
}变长参数函数
stdarg.h
c
#include <stdio.h>
#include <stdarg.h>
// 可变参数求和
int sum(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++) {
total += va_arg(args, int);
}
va_end(args);
return total;
}
// 可变参数求平均值
double average(int count, ...) {
if (count == 0) return 0.0;
va_list args;
va_start(args, count);
double total = 0.0;
for (int i = 0; i < count; i++) {
total += va_arg(args, int);
}
va_end(args);
return total / count;
}
// 可变参数打印
void print_values(const char *types, ...) {
va_list args;
va_start(args, types);
for (int i = 0; types[i] != '\0'; i++) {
switch (types[i]) {
case 'i':
printf("int: %d\n", va_arg(args, int));
break;
case 'f':
printf("double: %f\n", va_arg(args, double));
break;
case 's':
printf("string: %s\n", va_arg(args, char*));
break;
}
}
va_end(args);
}
int main() {
printf("Sum: %d\n", sum(5, 1, 2, 3, 4, 5));
printf("Average: %.2f\n", average(4, 10, 20, 30, 40));
print_values("ifs", 42, 3.14, "Hello");
return 0;
}内联函数
c
#include <stdio.h>
// 内联函数建议编译器内联展开
inline int square(int x) {
return x * x;
}
inline int max(int a, int b) {
return (a > b) ? a : b;
}
int main() {
printf("square(5) = %d\n", square(5));
printf("max(10, 20) = %d\n", max(10, 20));
return 0;
}函数指针
基本用法
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 main() {
// 声明函数指针
int (*operation)(int, int);
// 指向 add 函数
operation = add;
printf("add(5, 3) = %d\n", operation(5, 3));
// 指向 subtract 函数
operation = subtract;
printf("subtract(5, 3) = %d\n", operation(5, 3));
// 函数指针数组
int (*operations[])(int, int) = {add, subtract, multiply};
char *names[] = {"加", "减", "乘"};
for (int i = 0; i < 3; i++) {
printf("%s: %d\n", names[i], operations[i](10, 5));
}
return 0;
}回调函数
c
#include <stdio.h>
#include <stdlib.h>
// 回调函数类型
typedef int (*CompareFunc)(const void*, const void*);
// 使用回调函数的排序
void bubble_sort(int arr[], int size, CompareFunc compare) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - 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(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int descending(const void *a, const void *b) {
return (*(int*)b - *(int*)a);
}
// 处理数组元素
void process_array(int arr[], int size, void (*process)(int*)) {
for (int i = 0; i < size; i++) {
process(&arr[i]);
}
}
void double_value(int *n) { *n *= 2; }
void print_value(int *n) { printf("%d ", *n); }
int main() {
int arr[] = {5, 2, 8, 1, 9, 3};
int size = sizeof(arr) / sizeof(arr[0]);
printf("原数组: ");
process_array(arr, size, print_value);
printf("\n");
// 升序排序
bubble_sort(arr, size, ascending);
printf("升序: ");
process_array(arr, size, print_value);
printf("\n");
// 降序排序
bubble_sort(arr, size, descending);
printf("降序: ");
process_array(arr, size, print_value);
printf("\n");
// 使用 qsort
qsort(arr, size, sizeof(int), ascending);
printf("qsort: ");
process_array(arr, size, print_value);
printf("\n");
return 0;
}作用域与生命周期
变量作用域
c
#include <stdio.h>
int global = 100; // 全局变量
void func() {
int local = 200; // 局部变量
printf("局部变量: %d\n", local);
printf("全局变量: %d\n", global);
}
int main() {
int local = 300; // main 的局部变量
{
int block = 400; // 块级变量
printf("块级变量: %d\n", block);
}
// block 在这里不可访问
func();
printf("main 局部变量: %d\n", local);
return 0;
}静态变量
c
#include <stdio.h>
void counter() {
static int count = 0; // 静态局部变量
count++;
printf("调用次数: %d\n", count);
}
// 静态全局变量(文件作用域)
static int file_scope = 0;
int main() {
counter(); // 调用次数: 1
counter(); // 调用次数: 2
counter(); // 调用次数: 3
return 0;
}寄存器变量
c
#include <stdio.h>
int main() {
register int i; // 建议存储在寄存器中
for (i = 0; i < 1000000; i++) {
// 频繁使用的变量
}
// 不能对寄存器变量取地址
// int *p = &i; // 错误
return 0;
}实践示例
数学函数库
c
#include <stdio.h>
#include <math.h>
// 自定义数学函数
double my_pow(double base, int exponent) {
if (exponent == 0) return 1;
if (exponent < 0) return 1.0 / my_pow(base, -exponent);
double result = 1;
for (int i = 0; i < exponent; i++) {
result *= base;
}
return result;
}
int my_abs(int x) {
return (x < 0) ? -x : x;
}
double my_sqrt(double x) {
if (x < 0) return -1; // 错误
double guess = x / 2;
double epsilon = 0.00001;
while (my_abs(guess * guess - x) > epsilon) {
guess = (guess + x / guess) / 2;
}
return guess;
}
int main() {
printf("pow(2, 10) = %.0f\n", my_pow(2, 10));
printf("abs(-5) = %d\n", my_abs(-5));
printf("sqrt(16) = %.5f\n", my_sqrt(16));
return 0;
}字符串处理函数
c
#include <stdio.h>
#include <string.h>
// 字符串处理工具
void string_demo() {
char str[100] = "Hello, World!";
// 长度
printf("长度: %zu\n", strlen(str));
// 复制
char copy[100];
strcpy(copy, str);
printf("复制: %s\n", copy);
// 连接
strcat(copy, " Welcome!");
printf("连接: %s\n", copy);
// 比较
printf("比较: %d\n", strcmp("apple", "banana"));
// 查找
char *pos = strchr(str, 'W');
printf("找到 'W': %s\n", pos);
pos = strstr(str, "World");
printf("找到 \"World\": %s\n", pos);
// 分割
char str2[] = "one,two,three";
char *token = strtok(str2, ",");
while (token != NULL) {
printf("Token: %s\n", token);
token = strtok(NULL, ",");
}
}
int main() {
string_demo();
return 0;
}命令行参数处理
c
#include <stdio.h>
#include <string.h>
void print_help(const char *program_name) {
printf("Usage: %s [options]\n", program_name);
printf("Options:\n");
printf(" -h, --help 显示帮助信息\n");
printf(" -v, --version 显示版本\n");
printf(" -n, --name 设置名称\n");
}
int main(int argc, char *argv[]) {
printf("程序名: %s\n", argv[0]);
printf("参数个数: %d\n", argc - 1);
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
print_help(argv[0]);
return 0;
}
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
printf("Version 1.0.0\n");
return 0;
}
else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--name") == 0) {
if (i + 1 < argc) {
printf("名称: %s\n", argv[++i]);
} else {
printf("错误: -n 需要参数\n");
}
}
else {
printf("未知参数: %s\n", argv[i]);
}
}
return 0;
}