目录
函数调用
1、函数调用的一般形式
2、函数调用的方式
(1)函数语句:把函数调用作为一个语句,这时不要求函数带回值, 要求函数完成一定的操作。
(2)函数表达式:函数出现在一个表达式中,这种表达式称为函数表达式。这时要求函数带回一 个确定的值以参加表达式的运算。
(3)函数参数:函数调用作为一个函数的实参。函数调用作为函数的参数,实质上也是函数表达 式形式调用的一种,因为函数的参数本来就要求是表达式形式。例如: m=max(a,max(b,c));
3、对被调用函数的声明和函数原型
在一个函数中调用另一个函数(即被调用函数)需要具备的条件如下。
(1) 首先被调用的函数必须是已经存在的函数(是库函数或用户自己定义的函数)。但光有这一条件还不够。
(2) 如果使用库函数,还应该在本文件开头用 #include 命令将调用有关库函数时所需用到的信息”包含”到本文件中来。
(3) 如果使用用户自己定义的函数,而该函数的位置在调用它的函数(即主调函数)的后面(在同一个文件中),应该在主调函数中对被调用的函数作声明。
4、函数调用的本质
实际是利用的栈的结构 ---->先用后出 ----> 保证了函数可以层层嵌套调用
栈:数据结构 ---(表示数组组织形式) 栈:局部变量 ------ 空间自动申请,自动释放
特点:先进后出(First In Last Out)// FILO
C语言角度的栈:
①本质上是一块内存空间
②只是按照栈这种数据结构来处理和使用
*拓展了解:
C语言程序把内存划分为了5个区域:栈、堆、字符串常量区、静态区(全局区)、代码区
栈:主要用来存放,自动变量或函数调用的数据
堆:空间大,堆上的空间需要手动申请,手动释放
字符串常量区:只读,不可修改
静态区(全局区):全局变量和静态变量
代码区:只读
#include<stdio.h>
int main(void)
{
unsigned char buf[1024*1024*8]; //栈空间被占满
printf("hello world!\n"); //无法输出和实现函数调用
return 0;
}
5、函数的嵌套的使用
(1)特殊的嵌套调用 -----递归
直接递归:
void func1(void)
{
printf("-------func1--------\n");
func1();
}
间接递归:
1 #include<stdio.h>
2
3 void func1(void); //函数声明
4
5 void func2(void)
6 {
7 printf("-------func2--------\n");
8 func1(); //函数调用
9 }
10
11 void func1(void)
12 {
13 printf("-------func1--------\n");
14 func2();
15 }
16
17 int main(void)
18 {
19 func1();
20 func2();
21
22 return 0;
23 }
递归代码实现思路:
①递推关系:怎么从问题 n 到问题 n-1
②递推结束条件:n = 1;
使用递归函数求1~100的累加代码:
sum(100)
|--sum(99) + 100
|--sum(98)+99
|--sum(97)+98
...
|--sum(3)+4
|--sum(2)+3
|--sum(1) + 2
1
#include<stdio.h>
int sum(int n)
{
if(n == 1)
{
return 1;
}else
{
return sum(n-1) + n;
}
}
int main(void)
{
int ret;
printf("Input a num:");
scanf("%d",&ret);
printf("sum = %d\n",sum(ret));
return 0;
}
6、数组作为函数参数
(1)一维整型数组做函数参数
实参 --数组名,数组长度
#include<stdio.h>
void printArray(int a[],int len)//数组做形参定义形式需是数组类型
{
int i = 0;
for(i = 0;i < len;++i)
{
printf("a[%d] = %d\n",i,a[i]);
}
}
int main()
{
int a[] = {1,2,3,4,5};
int len = sizeof(a)/sizeof(a[0]); //求数组长度
printArray(a,len);//函数调用
return 0;
}