当前位置: 首页 > web >正文

C/C++复习--C语言中的函数详细


一、函数的基本概念

函数是C语言中封装代码的基本单元,类似于数学中的函数。
作用

  1. 提高代码复用性
  2. 模块化编程,增强可维护性
  3. 隐藏实现细节

分类

  • 库函数:由C标准库提供(如printf, strcpy
  • 自定义函数:程序员根据需求自行设计

二、库函数与自定义函数
1. 库函数示例:strcpymemset
#include <stdio.h>
#include <string.h>int main() {char dest[20];char src[] = "Hello, World!";strcpy(dest, src);  // 字符串拷贝printf("Copied string: %s\n", dest);int arr[5];memset(arr, 0, sizeof(arr));  // 内存初始化为0printf("First element: %d\n", arr[0]);return 0;
}
  • 关键点
    • 使用库函数需包含对应头文件(如#include <string.h>
    • strcpy(dest, src):将src内容复制到dest
    • memset(ptr, value, num):将ptr指向的内存的前num字节设置为value
2. 自定义函数示例:交换两个整数
#include <stdio.h>// 传值调用(无法交换)
void Swap1(int x, int y) {int tmp = x;x = y;y = tmp;
}// 传址调用(正确版本)
void Swap2(int *px, int *py) {int tmp = *px;*px = *py;*py = tmp;
}int main() {int a = 10, b = 20;Swap1(a, b);  // 无效printf("Swap1: a=%d, b=%d\n", a, b);Swap2(&a, &b);  // 有效printf("Swap2: a=%d, b=%d\n", a, b);return 0;
}
  • 关键点
    • 形参是实参的临时拷贝,修改形参不影响实参(Swap1无效)。
    • 传址调用通过指针直接操作内存,实现数据交换(Swap2有效)。

三、函数参数传递
1. 传值调用 vs. 传址调用
类型特点适用场景
传值调用形参是实参的拷贝不需要修改原始数据
传址调用通过指针直接操作内存需要修改原始数据
2. 示例:数组作为参数
#include <stdio.h>// 数组作为参数时,实际传递的是首元素地址
void PrintArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");
}int main() {int arr[] = {1, 2, 3, 4, 5};PrintArray(arr, 5);  // 输出:1 2 3 4 5return 0;
}

四、递归函数
1. 递归示例:计算阶乘
#include <stdio.h>int Factorial(int n) {if (n <= 1) return 1;       // 递归终止条件else return n * Factorial(n - 1);  // 递归调用
}int main() {int n = 5;printf("%d! = %d\n", n, Factorial(n));  // 输出:120return 0;
}
  • 关键点
    • 递归必须有终止条件,否则会导致栈溢出。
    • 递归深度较大时效率低下,可改用迭代优化。
2. 递归与迭代对比:斐波那契数列
// 递归实现(效率低)
int Fib(int n) {if (n <= 2) return 1;return Fib(n - 1) + Fib(n - 2);
}// 迭代实现(效率高)
int FibIter(int n) {int a = 1, b = 1, c = 1;while (n > 2) {c = a + b;a = b;b = c;n--;}return c;
}

五、函数分文件编写
1. 头文件声明:math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H// 函数声明
int Add(int x, int y);
double Power(double base, int exponent);#endif
2. 源文件实现:math_utils.c
#include "math_utils.h"int Add(int x, int y) {return x + y;
}double Power(double base, int exponent) {double result = 1.0;for (int i = 0; i < exponent; i++) {result *= base;}return result;
}

六、经典问题实战
1. 判断素数
#include <stdio.h>
#include <math.h>int IsPrime(int n) {if (n <= 1) return 0;for (int i = 2; i <= sqrt(n); i++) {if (n % i == 0) return 0;}return 1;
}int main() {int num = 17;printf("%d is %s\n", num, IsPrime(num) ? "prime" : "not prime");return 0;
}
2. 二分查找
#include <stdio.h>int BinarySearch(int arr[], int size, int target) {int left = 0, right = size - 1;while (left <= right) {int mid = left + (right - left) / 2;if (arr[mid] < target) left = mid + 1;else if (arr[mid] > target) right = mid - 1;else return mid;}return -1;
}int main() {int arr[] = {1, 2, 3, 4, 5};int target = 3;int index = BinarySearch(arr, 5, target);printf("Index: %d\n", index);  // 输出:2return 0;
}
http://www.xdnf.cn/news/5301.html

相关文章:

  • 强化学习系列:深度强化学习和DQN
  • 短剧平台流量突围!端原生片源授权成破局关键
  • 暗物质卯引力挂载技术
  • 【Bluedroid】蓝牙 HID 设备服务注册流程源码解析:从初始化到 SDP 记录构建
  • Docker基础入门
  • C++学习之模板初阶学习
  • 金丝雀/灰度/蓝绿发布的详解
  • 【免费工具】图吧工具箱2025.02正式版
  • 【比赛真题解析】篮球迷
  • 链表头插法的优化补充、尾插法完结!
  • 【数据结构与算法】——图(一)
  • anaconda部分基本指令
  • JavaWeb基础
  • Docker容器网络连接失败与镜像拉取异常全解析
  • 【RT-Thread Studio】nor flash配置Fal分区
  • “睿思 BI” 系统介绍
  • 2025年大模型RAG技术的实践总结
  • 2025-05-10-渗透测试:MS14-068漏洞利用、复现黄金票据(随笔)
  • 如何修改进程优先级?
  • 【漫话机器学习系列】250.异或函数(XOR Function)
  • Java游戏服务器开发流水账(4)游戏的数据持久化
  • Google Earth Pro(谷歌地球)2025大陆版安装教程
  • C# WinForm DataGridView 非常频繁地更新或重新绘制慢问题及解决
  • Docker、Docker-compose、K8s、Docker swarm之间的区别
  • 渠道销售简历模板范文
  • 【金仓数据库征文】从生产车间到数据中枢:金仓数据库助力MES系统国产化升级之路
  • ev_loop_fork函数
  • TGRS | FSVLM: 用于遥感农田分割的视觉语言模型
  • bash shell中readarray和mapfile的用法
  • json格式不合法情况下,如何尽量保证数据可用性