title: 第九章 函数
author: HardyDragon
tags: C Notes
第九章 函数
-
函数原型即函数声明,函数调用,函数定义即明确指定函数要做什么。
-
有些老编译器识别不了void返回值的函数,需要改为int。
-
如果函数放到其他文件需要导入
-
局部变量和全局变量
-
形参和实参
-
return返回值
-
没有返回值的函数返回类型为void没有参数的函数声明应该使用void关键字。
void print_name(void);
-
递归:需要有终止递归的条件才不会无限循环。递归方案比较简洁,但是效率没有循环高。
// recur.c -- 递归演示
#include <stdio.h>
void up_and_down(int);
int main(int argc, char const *argv[])
{
up_and_down(1);
return 0;
}
void up_and_down(int n)
{
printf("Level %d: 地址 %p\n", n, &n);
if (n < 4)
{
/* code */
up_and_down(n + 1);
}
printf("LEVEL %d : 地址为 %p\n", n, &n);
}
result:
Level 1: 地址 000000000061FE00
Level 2: 地址 000000000061FDD0
Level 3: 地址 000000000061FDA0
Level 4: 地址 000000000061FD70
LEVEL 4 : 地址为 000000000061FD70
LEVEL 3 : 地址为 000000000061FDA0
LEVEL 2 : 地址为 000000000061FDD0
LEVEL 1 : 地址为 000000000061FE00
每级函数调用都有自己的变量,递归使用的空间比较多的原因。递归返回各级函数的结果顺序安装栈的先进后出的顺序。
-
尾递归是最简单的递归形式,即将递归函数放在main函数的末尾,即return之前,相当于循环。
// binary.c -- 以二进制形式打印整数 #include <stdio.h> void to_binary(unsigned long n); int main(int argc, char const *argv[]) { unsigned long number; printf("enter a num (q to quit):\n"); while (scanf("%lu", &number) == 1) { /* code */ printf("二进制数:"); to_binary(number); putchar('\n'); printf("enter a num (q to quit):\n"); } printf("Done!\n"); return 0; } void to_binary(unsigned long n) { int r; r = n % 2; if (n >= 2) { to_binary(n / 2); } putchar(r == 0 ? '0' : '1'); return; }
retuslt:
enter a num (q to quit): 3 二进制数:11 enter a num (q to quit): q Done!
-
自己编写头文件,然后使用#include导入即可。一般是放一些#define 和函数声明。或变量
-
&取地址符,&加在变量前就是相当于给变量加了一个* ,* (取值符)放在变量名前相当于给变量名去掉一个 * ; 打印地址的转换说明符是 %p
-
交换两个变量的值
temp = x; x=y; y=temp;
// swap1.c -- 第一个版本的交换函数,只在局部交换值 #include <stdio.h> void interchange(int u, int v); int main(int argc, char const *argv[]) { int x = 5, y = 10; printf("初始xy的值是x=%d y=%d.\n", x, y); interchange(x, y); printf("交换后的值x=%d,y=%d", x, y); return 0; } void interchange(int u, int v) { int temp; printf("初始xy的值是x=%d y=%d.\n", u, v); temp = u; u = v; v = temp; printf("初始uv的值是x=%d y=%d.\n", u, v); }
result:
初始xy的值是x=5 y=10. 初始xy的值是x=5 y=10. 初始uv的值是x=10 y=5. 交换后的值x=5,y=10
只是在函数内交换了u 和 v的值,但是结果传回main 时并不是。可以尝试return返回,但是return只能返回一个值,要是返回两个需要用到指针?这是函数之间的通信问题。
-
指针值是地址。将指针作为函数参数使用,可以实现通过函数修改变量的实际值。
#include <stdio.h> int main() { int* x; // x pointer int num; printf("给x指针赋值(让指针指向xx) ,x指针的地址:%p:\n",x); scanf("%d",&num); x = # printf("x指向的值:%d\n",*x); return 0; }
result:
给x指针赋值(让指针指向xx) ,x指针的地址:0000000000000010: 16 x指向的值:16
-
利用指针解决函数的通信问题。
//swap3.c -- 使用指针解决交换函数的问题 #include <stdio.h> void interchange(int *x, int *y); int main(int argc, char const *argv[]) { int x = 5, y = 10; printf("初始的x=%d,y=%d.\n", x, y); interchange(&x, &y); printf("交换后x=%d,y=%d", x, y); return 0; } void interchange(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; }
result:
初始的x=5,y=10. 交换后x=10,y=5
-
小结:
注意函数定义和函数声明。
利用指针作为函数的参数解决函数之间的通信问题。利用函数修改指针所指向的值。