文章目录
一、相关术语理解
1.函数是什么
是子程序
,相较于其他代码,具有相对独立性
。
一般会有输入参数
并有返回值
。
2.C语言中的函数
Ι.库函数
(1)常用库函数
·IO函数
·字符串操作函数
·字符操作函数
·内存操作函数
·时间/日期函数
·数学函数
·其他库函数
(2)注意
1.使用库函数,必须包含 #include 对应的头文件。
2.使用文档学习库函数——关注两个点【返回值类型,参数类型】
3.学习库函数的常用途径
①C/C++语言官网【在线】
②MSDN【离线】
Π.自定义函数
程序员根据自己的需求封装的一个具有特定功能的函数。
一般来讲,适用性广、独立性强。
主要考虑三个点函数名
、返回值类型
、函数参数
。
3.函数参数
(1)实际参数
真实传给函数的参数,叫实参。
实参可以是:常量、变量、表达式、函数等。
总而言之,就是具有确定值的变量或常量。
(2)形式参数
形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。
※注意
1.形参实例化之后其实相当于实参的一份临时拷贝。
2.形式参数当函数调用完成之后就自动销毁了
【复习函数栈帧的创建与销毁过程】
4.函数调用
(1)传值调用
实际参数是非地址
。
调用之后,不会对实参产生影响
。
注意:传数组名本质上是在传数组首元素地址,属于传址调用。
(2)传址调用
实际参数是地址
。
调用之后,会对实参产生影响
。
5.函数的嵌套调用和链式访问
(1)嵌套调用
嵌套调用就是某个函数调用另外一个函数。
函数可以嵌套调用,但不可以嵌套定义。
(2)链式访问
链式访问就是一个函数的参数是另外一个函数的返回值。
6.函数的声明和定义
(1)函数声明
1.告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。
2.函数的声明一般出现在函数的使用之前。要满足先声明后使用。
3.函数的声明一般要放在头文件中
(2)函数定义
函数的定义是指函数的具体实现。
7.函数递归
(1)什么是递归
说白了,递归就是一种函数自己调用自己的编程技巧。
(2)递归两个必要条件
两个条件其实对应了递归的两个阶段。
①存在限制条件
,当满足这个限制条件的时候,递归便不再继续。——递去阶段
②每次递归调用之后越来越接近
这个限制条件——执行过程中的变化。——归来阶段
(3)递归与迭代的优缺点
迭代可以暂时简单的理解为循环。
定义 | 优点 | 缺点 | |
---|---|---|---|
递归 | 程序调用自身的编程技巧称为递归 | 1)大问题化为小问题,可以极大的减少代码量; 2)用有限的语句来定义对象的无限集合.; 3)代码更简洁清晰,可读性更好 | 1)递归调用函数,浪费空间; 2)递归太深容易造成堆栈的溢出; |
迭代 | 利用变量的原值推算出变量的一个新值,迭代就是A不停的调用B | 1)迭代效率高,运行时间只因循环次数增加而增加 2)没什么额外开销,空间上也没有什么增加, | 1) 不容易理解; 2) 代码不如递归简洁; 3) 编写复杂问题时困难 |
二者联系:1) 递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换。
2) 能用迭代的不用递归,递归调用函数,浪费空间,并且递归太深容易造成堆栈的溢出./相对/
二、易错实例演示
1.函数的嵌套调用和链式访问
嵌套调用实例
#include <stdio.h>
void new_line()
{
printf("hehe\n");//嵌套调用了printf函数
}
void three_line()
{
int i = 0;
for(i=0; i<3; i++)
{
new_line();//嵌套调用了new_line函数
}
}
int main()
{
three_line();//嵌套调用了three_line函数
return 0;
}
链式访问实例
//实例1
#include <stdio.h>
#include <string.h>
int main()
{
char arr[20] = "hello";
int ret = strlen(strcat(arr,"bit")); //strcat返回拼接后数组名
printf("%d\n", ret);
return 0;
}
//实例2
#include <stdio.h>
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
//结果为4321
//注:printf函数的返回值是打印在屏幕上字符的个数
return 0;
}
2.函数的声明和定义
头文件
test.h****的内容
放置函数的声明
#ifndef __TEST_H__
#define __TEST_H__
//函数的声明
int Add(int x, int y);
#endif //__TEST_H__
源文件
test.c****的内容
放置函数的实现
#include "test.h"
//函数Add的实现
int Add(int x, int y) {
return x+y; }
3.函数递归
1)顺序打印无符号数的每一位
#include <stdio.h>
void print(int n)
{
if(n>9)
{
print(n/10);
}
printf("%d ", n%10);
}
int main()
{
int num = 1234;
print(num);
return 0;
}
2)使用递归并且不创建临时变量实现strlen
#incude <stdio.h>
int Strlen(const char*str)
{
if(*str == '\0')
return 0;
else
return 1+Strlen(str+1);
}
int main()
{
char *p = "abcdef";
int len = Strlen(p);
printf("%d\n", len);
return 0;
}