11---
22chapter : 1
33cpp_standard :
4- - 11
4+ - 11
55description : 理解 C 函数的声明定义调用机制、值传递本质、指针参数、返回值策略和递归原理,为 C++ 引用传递和函数重载打好基础
66difficulty : beginner
77order : 7
88platform : host
99prerequisites :
10- - 指针与数组、const 和空指针
10+ - 指针与数组、const 和空指针
1111reading_time_minutes : 10
1212tags :
13- - host
14- - cpp-modern
15- - beginner
16- - 入门
17- - 基础
13+ - host
14+ - cpp-modern
15+ - beginner
16+ - 入门
17+ - 基础
1818title : 函数基础与参数传递
1919---
20+
2021# 函数基础与参数传递
2122
2223到现在为止我们写的代码都塞在 ` main ` 函数里。但现实世界的程序不会这样——一个项目动辄几万行代码,如果全挤在一个函数里,那基本没法维护。函数就是 C 语言模块化编程的基本单元:把一段逻辑封装起来,给它起个名字,需要的时候调用就行。
@@ -35,7 +36,7 @@ title: 函数基础与参数传递
3536
3637我们接下来的所有实验都在这个环境下进行:
3738
38- - 平台:Linux x86 \_ 64 (WSL2 也可以)
39+ - 平台:Linux x86_64 (WSL2 也可以)
3940- 编译器:GCC 13+ 或 Clang 17+
4041- 编译选项:` -Wall -Wextra -std=c17 `
4142
@@ -324,6 +325,40 @@ typedef enum { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR } LogLevel;
324325void log_message(LogLevel level, const char* format, ...);
325326```
326327
328+ ### 练习 1 参考答案
329+
330+ ```c
331+ void log_message(LogLevel level, const char* format, ...) {
332+ const char* level_str;
333+ switch (level) {
334+ case LOG_DEBUG:
335+ level_str = "DEBUG";
336+ break;
337+ case LOG_INFO:
338+ level_str = "INFO";
339+ break;
340+ case LOG_WARN:
341+ level_str = "WARN";
342+ break;
343+ case LOG_ERROR:
344+ level_str = "ERROR";
345+ break;
346+ default:
347+ level_str = "UNKNOWN";
348+ break;
349+ }
350+ printf("%s\n", level_str);
351+
352+ va_list log;
353+ va_start(log, format);
354+
355+ vprintf(format, log);
356+ printf("\n");
357+
358+ va_end(log);
359+ }
360+ ```
361+
327362### 练习 2:递归与迭代——二分查找
328363
329364分别用递归和迭代实现二分查找,比较两者的性能和可读性:
@@ -333,6 +368,49 @@ int binary_search_recursive(const int* arr, size_t len, int target);
333368int binary_search_iterative(const int* arr, size_t len, int target);
334369```
335370
371+ ### 练习 2 参考答案
372+
373+ ```c
374+ int binary_search_recursive(const int* arr, size_t len, int target) {
375+ if (len < 1) {
376+ printf("%d is not found in index\n", target);
377+ return -1;
378+ }
379+ size_t mid = (len - 1) / 2;
380+
381+ if (arr[mid] == target) {return mid;}
382+ if (arr[mid] < target) {
383+ int res = binary_search_recursive(arr + mid + 1, len - mid - 1, target);
384+ return (res == -1) ? -1 : (res + mid + 1);
385+ }
386+ if (arr[mid] > target) {return binary_search_recursive(arr, mid , target);}
387+ return -1;
388+ }
389+
390+ int binary_search_iterative(const int* arr, size_t len, int target) {
391+ if (len < 1) {
392+ printf("%d is not found in index\n", target);
393+ return -1;
394+ }
395+ size_t low = 0;
396+ size_t high = len - 1;
397+ size_t mid = low + (high - low) / 2;
398+ while (low <= high) {
399+ if (arr[mid] == target) {return mid;}
400+
401+ if (arr[mid] < target) {
402+ low = mid + 1;
403+ }
404+ else if (arr[mid] > target) {
405+ high = mid - 1;
406+ }
407+ mid = low + (high - low) / 2;
408+ }
409+ printf("%d is not found in index\n", target);
410+ return -1;
411+ }
412+ ```
413+
336414### 练习 3:多返回值实战
337415
338416实现一个函数,同时计算数组的最大值和最小值:
@@ -346,6 +424,25 @@ int binary_search_iterative(const int* arr, size_t len, int target);
346424void find_min_max (const int* data, size_t len, int* min_out, int* max_out);
347425```
348426
427+ ### 练习 3 参考答案
428+
429+ ```c
430+ void find_min_max(const int* data, size_t len, int* min_out, int* max_out) {
431+ if (data == NULL || min_out == NULL || max_out == NULL || len < 1) {
432+ return;
433+ }
434+ *min_out = *max_out = data[0];
435+ for (size_t i = 1; i < len; i++) {
436+ if (data[i] < *min_out) {
437+ *min_out = data[i];
438+ }
439+ if (data[i] > *max_out) {
440+ *max_out = data[i];
441+ }
442+ }
443+ }
444+ ```
445+
349446## 参考资源
350447
351448- [ cppreference: 函数声明] ( https://en.cppreference.com/w/c/language/function_declaration )
0 commit comments