每日一个C语言知识:C 函数
函数是一组一起执行一个任务的语句,是C语言程序的基本构建块。每个C程序都至少有一个函数(main函数),你可以定义自己的函数来完成特定的任务。函数的主要优点代码重用:一次定义,多次调用模块化:将复杂问题分解为小问题可维护性:易于调试和修改可读性:使代码更加清晰易懂返回类型 函数名(参数列表) {// 函数体return 表达式;// 如果返回类型不是void// 函数定义// 返回类型:void(
·
C语言函数详解
1. 什么是函数?
函数是一组一起执行一个任务的语句,是C语言程序的基本构建块。每个C程序都至少有一个函数(main函数),你可以定义自己的函数来完成特定的任务。
函数的主要优点:
- 代码重用:一次定义,多次调用
- 模块化:将复杂问题分解为小问题
- 可维护性:易于调试和修改
- 可读性:使代码更加清晰易懂
2. 函数的组成部分
C语言函数包含以下几个部分:
3. 函数的定义
基本语法
返回类型 函数名(参数列表) {
// 函数体
return 表达式; // 如果返回类型不是void
}
示例:简单的函数定义
#include <stdio.h>
// 函数定义
// 返回类型:void(无返回值)
// 函数名:greet
// 参数列表:无参数
void greet() {
printf("Hello, Welcome to C Functions!\n");
}
// 带参数的函数
void printMessage(char message[]) {
printf("消息: %s\n", message);
}
// 带返回值的函数
int add(int a, int b) {
return a + b;
}
// 带多个参数的函数
float calculateAverage(float num1, float num2, float num3) {
return (num1 + num2 + num3) / 3.0;
}
int main() {
printf("=== 函数定义示例 ===\n");
// 调用无参函数
greet();
// 调用带参函数
printMessage("学习C语言函数很有趣!");
// 调用带返回值的函数
int sum = add(5, 3);
printf("5 + 3 = %d\n", sum);
// 调用多参数函数
float average = calculateAverage(10.5, 20.3, 15.2);
printf("平均值: %.2f\n", average);
return 0;
}
4. 函数声明 vs 函数定义
函数声明(函数原型)
告诉编译器函数的名称、返回类型和参数。
函数定义
提供函数的实际实现。
#include <stdio.h>
// 函数声明(函数原型)
int multiply(int a, int b);
void displayResult(int result);
float divide(float dividend, float divisor);
int main() {
printf("=== 函数声明与定义 ===\n");
int x = 6, y = 7;
// 函数调用
int product = multiply(x, y);
displayResult(product);
float quotient = divide(10.0, 3.0);
printf("10.0 / 3.0 = %.2f\n", quotient);
return 0;
}
// 函数定义
int multiply(int a, int b) {
return a * b;
}
void displayResult(int result) {
printf("计算结果: %d\n", result);
}
float divide(float dividend, float divisor) {
if (divisor == 0) {
printf("错误:除数不能为零!\n");
return 0;
}
return dividend / divisor;
}
5. 函数参数
传值调用
函数接收参数的副本,对副本的修改不影响原始数据。
#include <stdio.h>
// 传值调用 - 参数是原始值的副本
void swapByValue(int a, int b) {
int temp = a;
a = b;
b = temp;
printf("函数内 - a = %d, b = %d\n", a, b);
}
// 传址调用 - 参数是地址
void swapByReference(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
printf("函数内 - *a = %d, *b = %d\n", *a, *b);
}
int main() {
int x = 5, y = 10;
printf("=== 函数参数传递 ===\n");
printf("原始值 - x = %d, y = %d\n", x, y);
// 传值调用
swapByValue(x, y);
printf("传值调用后 - x = %d, y = %d\n", x, y);
// 传址调用
swapByReference(&x, &y);
printf("传址调用后 - x = %d, y = %d\n", x, y);
return 0;
}
数组作为函数参数
#include <stdio.h>
// 函数声明
void printArray(int arr[], int size);
int findMax(int arr[], int size);
float calculateAverage(int arr[], int size);
void reverseArray(int arr[], int size);
int main() {
int numbers[] = {12, 45, 23, 67, 34, 89, 56};
int size = sizeof(numbers) / sizeof(numbers[0]);
printf("=== 数组作为函数参数 ===\n");
printf("原始数组: ");
printArray(numbers, size);
printf("最大值: %d\n", findMax(numbers, size));
printf("平均值: %.2f\n", calculateAverage(numbers, size));
reverseArray(numbers, size);
printf("反转后数组: ");
printArray(numbers, size);
return 0;
}
// 打印数组
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// 查找最大值
int findMax(int arr[], int size) {
int max = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
// 计算平均值
float calculateAverage(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return (float)sum / size;
}
// 反转数组
void reverseArray(int arr[], int size) {
for (int i = 0; i < size / 2; i++) {
int temp = arr[i];
arr[i] = arr[size - 1 - i];
arr[size - 1 - i] = temp;
}
}
6. 返回类型
基本数据类型返回
#include <stdio.h>
#include <stdbool.h>
// 返回整型
int getSquare(int num) {
return num * num;
}
// 返回浮点型
float getCircleArea(float radius) {
return 3.14159 * radius * radius;
}
// 返回字符型
char getGrade(int score) {
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
if (score >= 60) return 'D';
return 'F';
}
// 返回布尔型
bool isEven(int num) {
return num % 2 == 0;
}
// 返回字符串(字符指针)
const char* getMessage(int hour) {
if (hour < 12) return "Good Morning!";
if (hour < 18) return "Good Afternoon!";
return "Good Evening!";
}
int main() {
printf("=== 函数返回类型 ===\n");
printf("5的平方: %d\n", getSquare(5));
printf("半径3的圆面积: %.2f\n", getCircleArea(3.0));
printf("分数85的等级: %c\n", getGrade(85));
printf("7是偶数吗? %s\n", isEven(7) ? "是" : "否");
printf("问候: %s\n", getMessage(14));
return 0;
}
返回指针
#include <stdio.h>
// 返回整型指针
int* findMaxElement(int arr[], int size) {
int *max = &arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] > *max) {
max = &arr[i];
}
}
return max;
}
// 返回字符串
const char* getDayOfWeek(int day) {
switch(day) {
case 1: return "Monday";
case 2: return "Tuesday";
case 3: return "Wednesday";
case 4: return "Thursday";
case 5: return "Friday";
case 6: return "Saturday";
case 7: return "Sunday";
default: return "Invalid day";
}
}
int main() {
int numbers[] = {23, 45, 12, 67, 34};
int size = sizeof(numbers) / sizeof(numbers[0]);
printf("=== 返回指针 ===\n");
int *maxPtr = findMaxElement(numbers, size);
printf("数组中的最大值: %d (地址: %p)\n", *maxPtr, maxPtr);
printf("星期3是: %s\n", getDayOfWeek(3));
return 0;
}
7. 递归函数
函数调用自身的过程称为递归。
基本递归示例
#include <stdio.h>
// 计算阶乘(递归)
unsigned long long factorial(int n) {
if (n == 0 || n == 1) {
return 1;
}
return n * factorial(n - 1);
}
// 计算斐波那契数列(递归)
int fibonacci(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}
// 递归打印数字
void printNumbers(int n) {
if (n < 1) return;
printNumbers(n - 1); // 递归调用
printf("%d ", n); // 回溯时打印
}
int main() {
printf("=== 递归函数 ===\n");
// 阶乘计算
int num = 5;
printf("%d! = %llu\n", num, factorial(num));
// 斐波那契数列
printf("斐波那契数列前10项: ");
for (int i = 0; i < 10; i++) {
printf("%d ", fibonacci(i));
}
printf("\n");
// 递归打印
printf("递归打印1-5: ");
printNumbers(5);
printf("\n");
return 0;
}
递归的实际应用:文件系统遍历(模拟)
#include <stdio.h>
// 模拟递归遍历目录结构
void traverseDirectory(int depth, int maxDepth) {
// 基线条件
if (depth > maxDepth) {
return;
}
// 打印当前深度(缩进表示层级)
for (int i = 0; i < depth; i++) {
printf(" "); // 缩进
}
printf("📁 目录层级 %d\n", depth);
// 递归进入子目录(模拟)
traverseDirectory(depth + 1, maxDepth);
// 回溯时处理文件(模拟)
for (int i = 0; i < depth; i++) {
printf(" "); // 缩进
}
printf("📄 文件在层级 %d\n", depth);
}
// 递归计算数字的各位之和
int sumOfDigits(int n) {
if (n == 0) return 0;
return (n % 10) + sumOfDigits(n / 10);
}
int main() {
printf("=== 递归实际应用 ===\n");
printf("模拟目录遍历:\n");
traverseDirectory(0, 3);
int number = 12345;
printf("\n数字 %d 的各位之和: %d\n", number, sumOfDigits(number));
return 0;
}
8. 标准库函数
C语言提供了丰富的标准库函数。
数学函数
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
int main() {
printf("=== 标准库函数示例 ===\n");
// 数学函数
double x = 4.0, y = 2.5;
printf("sqrt(%.1f) = %.2f\n", x, sqrt(x));
printf("pow(%.1f, %.1f) = %.2f\n", x, y, pow(x, y));
printf("sin(%.1f) = %.2f\n", y, sin(y));
printf("ceil(%.1f) = %.1f\n", y, ceil(y));
printf("floor(%.1f) = %.1f\n", y, floor(y));
// 随机数函数
srand(time(NULL)); // 设置随机数种子
printf("随机数: %d\n", rand() % 100);
// 内存管理函数
int *arr = (int*)malloc(5 * sizeof(int));
if (arr != NULL) {
for (int i = 0; i < 5; i++) {
arr[i] = i * 10;
}
printf("动态数组: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr); // 释放内存
}
return 0;
}
字符串处理函数
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
printf("=== 字符串处理函数 ===\n");
char str1[50] = "Hello";
char str2[50] = "World";
char str3[100];
// 字符串长度
printf("str1长度: %lu\n", strlen(str1));
// 字符串复制
strcpy(str3, str1);
printf("复制后str3: %s\n", str3);
// 字符串连接
strcat(str3, " ");
strcat(str3, str2);
printf("连接后str3: %s\n", str3);
// 字符串比较
printf("str1和str2比较: %d\n", strcmp(str1, str2));
// 字符大小写转换
char ch = 'A';
printf("%c 的小写: %c\n", ch, tolower(ch));
printf("%c 的大写: %c\n", 'b', toupper('b'));
return 0;
}
9. 用户定义函数的最佳实践
示例:学生成绩管理系统
#include <stdio.h>
#include <string.h>
#define MAX_STUDENTS 50
#define MAX_NAME_LENGTH 50
// 结构体定义
typedef struct {
char name[MAX_NAME_LENGTH];
int score;
} Student;
// 函数声明
void displayMenu();
void addStudent(Student students[], int *count);
void displayAllStudents(Student students[], int count);
void findStudent(Student students[], int count);
void calculateStatistics(Student students[], int count);
int findStudentIndex(Student students[], int count, const char *name);
int main() {
Student students[MAX_STUDENTS];
int studentCount = 0;
int choice;
printf("=== 学生成绩管理系统 ===\n");
do {
displayMenu();
printf("请选择操作: ");
scanf("%d", &choice);
switch(choice) {
case 1:
addStudent(students, &studentCount);
break;
case 2:
displayAllStudents(students, studentCount);
break;
case 3:
findStudent(students, studentCount);
break;
case 4:
calculateStatistics(students, studentCount);
break;
case 5:
printf("感谢使用,再见!\n");
break;
default:
printf("无效选择,请重新输入!\n");
}
} while(choice != 5);
return 0;
}
// 显示菜单
void displayMenu() {
printf("\n=== 菜单 ===\n");
printf("1. 添加学生\n");
printf("2. 显示所有学生\n");
printf("3. 查找学生\n");
printf("4. 统计信息\n");
printf("5. 退出\n");
}
// 添加学生
void addStudent(Student students[], int *count) {
if (*count >= MAX_STUDENTS) {
printf("错误:学生数量已达到上限!\n");
return;
}
printf("请输入学生姓名: ");
scanf("%s", students[*count].name);
printf("请输入学生分数: ");
scanf("%d", &students[*count].score);
(*count)++;
printf("学生添加成功!\n");
}
// 显示所有学生
void displayAllStudents(Student students[], int count) {
if (count == 0) {
printf("没有学生记录。\n");
return;
}
printf("\n=== 所有学生信息 ===\n");
printf("%-20s %-10s %-10s\n", "姓名", "分数", "等级");
printf("----------------------------------------\n");
for (int i = 0; i < count; i++) {
char grade;
if (students[i].score >= 90) grade = 'A';
else if (students[i].score >= 80) grade = 'B';
else if (students[i].score >= 70) grade = 'C';
else if (students[i].score >= 60) grade = 'D';
else grade = 'F';
printf("%-20s %-10d %-10c\n",
students[i].name, students[i].score, grade);
}
}
// 查找学生
void findStudent(Student students[], int count) {
if (count == 0) {
printf("没有学生记录。\n");
return;
}
char name[MAX_NAME_LENGTH];
printf("请输入要查找的学生姓名: ");
scanf("%s", name);
int index = findStudentIndex(students, count, name);
if (index != -1) {
printf("找到学生: %s, 分数: %d\n",
students[index].name, students[index].score);
} else {
printf("未找到学生: %s\n", name);
}
}
// 查找学生索引
int findStudentIndex(Student students[], int count, const char *name) {
for (int i = 0; i < count; i++) {
if (strcmp(students[i].name, name) == 0) {
return i;
}
}
return -1;
}
// 计算统计信息
void calculateStatistics(Student students[], int count) {
if (count == 0) {
printf("没有学生记录。\n");
return;
}
int sum = 0, max = students[0].score, min = students[0].score;
int excellent = 0, good = 0, pass = 0, fail = 0;
for (int i = 0; i < count; i++) {
sum += students[i].score;
if (students[i].score > max) max = students[i].score;
if (students[i].score < min) min = students[i].score;
if (students[i].score >= 90) excellent++;
else if (students[i].score >= 80) good++;
else if (students[i].score >= 60) pass++;
else fail++;
}
float average = (float)sum / count;
printf("\n=== 统计信息 ===\n");
printf("学生总数: %d\n", count);
printf("平均分: %.2f\n", average);
printf("最高分: %d\n", max);
printf("最低分: %d\n", min);
printf("优秀 (90+): %d (%.1f%%)\n", excellent, (float)excellent/count*100);
printf("良好 (80-89): %d (%.1f%%)\n", good, (float)good/count*100);
printf("及格 (60-79): %d (%.1f%%)\n", pass, (float)pass/count*100);
printf("不及格: %d (%.1f%%)\n", fail, (float)fail/count*100);
}
示例:数学工具库
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
// 函数声明
int gcd(int a, int b);
int lcm(int a, int b);
bool isPrime(int n);
void printPrimesInRange(int start, int end);
double calculateCircleArea(double radius);
double calculateTriangleArea(double base, double height);
int main() {
printf("=== 数学工具库 ===\n");
// 最大公约数和最小公倍数
int a = 48, b = 18;
printf("%d和%d的最大公约数: %d\n", a, b, gcd(a, b));
printf("%d和%d的最小公倍数: %d\n", a, b, lcm(a, b));
// 素数判断
int num = 29;
printf("%d是素数吗? %s\n", num, isPrime(num) ? "是" : "否");
// 打印范围内的素数
printf("1-50之间的素数: ");
printPrimesInRange(1, 50);
printf("\n");
// 几何计算
double radius = 5.0;
printf("半径%.1f的圆面积: %.2f\n", radius, calculateCircleArea(radius));
double base = 6.0, height = 4.0;
printf("底%.1f高%.1f的三角形面积: %.2f\n", base, height, calculateTriangleArea(base, height));
return 0;
}
// 计算最大公约数(欧几里得算法)
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// 计算最小公倍数
int lcm(int a, int b) {
return (a * b) / gcd(a, b);
}
// 判断素数
bool isPrime(int n) {
if (n <= 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
// 打印范围内的素数
void printPrimesInRange(int start, int end) {
for (int i = start; i <= end; i++) {
if (isPrime(i)) {
printf("%d ", i);
}
}
}
// 计算圆面积
double calculateCircleArea(double radius) {
return M_PI * radius * radius;
}
// 计算三角形面积
double calculateTriangleArea(double base, double height) {
return 0.5 * base * height;
}
10. 函数的高级特性
函数指针
#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) {
if (b != 0) return a / b;
return 0;
}
// 使用函数指针作为参数
void calculate(int a, int b, int (*operation)(int, int)) {
int result = operation(a, b);
printf("计算结果: %d\n", result);
}
int main() {
printf("=== 函数指针 ===\n");
// 声明函数指针
int (*funcPtr)(int, int);
int x = 10, y = 5;
// 使用函数指针调用不同的函数
funcPtr = add;
printf("加法: ");
calculate(x, y, funcPtr);
funcPtr = subtract;
printf("减法: ");
calculate(x, y, funcPtr);
funcPtr = multiply;
printf("乘法: ");
calculate(x, y, funcPtr);
funcPtr = divide;
printf("除法: ");
calculate(x, y, funcPtr);
return 0;
}
可变参数函数
#include <stdio.h>
#include <stdarg.h>
// 可变参数函数:计算平均值
double average(int count, ...) {
va_list args;
double sum = 0;
va_start(args, count);
for (int i = 0; i < count; i++) {
sum += va_arg(args, double);
}
va_end(args);
return sum / count;
}
// 可变参数函数:打印格式化消息
void printFormatted(const char *format, ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
int main() {
printf("=== 可变参数函数 ===\n");
// 计算多个数字的平均值
double avg = average(5, 10.5, 20.3, 15.7, 25.1, 18.4);
printf("平均值: %.2f\n", avg);
// 格式化打印
printFormatted("姓名: %s, 年龄: %d, 分数: %.1f\n",
"张三", 20, 95.5);
return 0;
}
更多推荐
所有评论(0)