一.函数定义的一般形式

1.无参函数定义的一般形式

定义无参函数的一般形式为:

类型标识符 函数名()

{

声明部分

语句部分

}

2.有参函数定义的一般形式

定义有参函数的一般形式为:

类型标识符函数名(形式参数表列)

{

声明部分

语句部分

}

函数头:
  (1)类型标识符 --- int/short/long ...
                  返回值类型 //说明函数返回的结果的数据类型  
                  注意:
                     1.返回值结果 和 设计的 类型标识符 可能不一致 
                       此时,返回值结果 会被 转换成 类型标识符 指定的类型 
                     2.如果返回值类型省略不写
                       默认 int类型 
                     3.如果不需要带出返回值 
                       void --- 空类型 
                       对应的 return 后面不能有值 
                       return; 
  (2)函数名    --- 标识符 
                  体现函数功能的
                  见名知意 
                  注意:
                    1.形参 与 实参 
                      类型匹配
                      个数相同 
                    2.形参
                      int a,b,c; //普通的定义变量的书写方式 
                      int a,int b,int c //形参变量,每个变量都必须明确的指定类型 
                    3.如果函数功能,不需要传入数据 --- 形参一般设计为 void 
                    
                    void menu(void)
                    {
                       printf("------mp3----\n");
                    }
  (3)形式参数  --- 本质是是变量 
                 作用 --用来接受 实际的参数 
                 语法:
                 类型 形参变量名1, 类型 形参变量名2, 类型 形参变量名3,...

例如定义一个求和函数:

 int add(int a,int b)
 {
    int sum;
    sum = a + b;
    return sum;
 }

二.函数参数和函数的值

1 形式参数和实际参数

关于形参与实参的说明:

(1) 在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。

(2) 实参可以是常量、变量或表达式。

(3) 在被定义的函数中,必须指定形参的类型。

(4) 实参与形参的类型应相同或赋值兼容。

(5) 在 C语言中,实参向形参的数据传递是“值传递“,单向传递,只由实参传给形参,而 不能由形参传回来给实参。

2 函数的返回值

通常,希望通过函数调用使主调函数能得到一个确定的值,这就是函数的返回值。

(1) 函数的返回值是通过函数中的 return语句获得的。 return 语句将被调用函数中 的一个确定值带回主调函数中去。

(2) 函数值的类型。既然函数有返回值,这个值当然应属于某一个确定的类型,应当 在定义函数时指定函数值的类型。

(3) 在定义函数时指定的函数类型一般应该和 return 语句中的表达式类型一致。如果函数值的类型和 return 语句中表达式的值不一致,则以函数类型为准。对数值 型数据,可以自动进行类型转换。即函数类型决定返回值的类型。

三.函数的调用

函数名(实参表列);

如果是调用无参函数,则“实参表列”可以没有,但括号不能省略。如果实参表列包含多个实参,则各参数间用逗号隔开。实参与形参的个数应相等,类型应匹配。 实参与形参按顺序对应,一一传递数据。但应说明,如果实参表列包括多个实参,对实参 求值的顺序并不是确定的,有的系统按自左至右顺序求实参的值,有的系统则按自右至左顺序。

练习:
   实现一个函数
   找出两个整数的最大值 

实现一个函数,
   判断年份是否闰年 

实现一个函数
   打印100以内所有的素数 

四.函数的嵌套调用


   
C语言不能嵌套定义函数,但可以嵌套调用函数,也就是说,在调用一个函数的过程 中,又调用另一个函数。

特殊的嵌套调用 --- 自己调用到自己 

表示的是两层嵌套(包括main 函数共 3层函数),其执行过程是:

(1) 执行 main 函数的开头部分;

(2) 遇函数调用语句,调用函数a,流程转去 a 函数;

(3) 执行 a 函数的开头部分;

(4) 遇函数调用语句,调用函数 b,流程转去函数 b;

(5) 执行 b 函数,如果再无其他嵌套的函数,则完成 b 函数的全部操作;

(6) 返回到 a 函数中调用 b 函数的位置;

(7) 继续执行 a 函数中尚未执行的部分,直到 a 函数结束;

(8) 返回 main 函数中调用 a 函数的位置;

(9) 继续执行 main 函数的剩余部分直到结束。

函数为什么能实现嵌套调用? --- 函数的本质 
函数能够实现层层的嵌套调用 。本质是 因为有栈这个空间存在 。

五.函数的递归调用

   递归:
       1.本质上是个循环 
       2.这种循环 一定会结束 
         因为栈的空间有限 
       3.递归的效率并不高 
         因为有些问题的解决,
         使用递归将变得非常简单 

Hanoi(汉诺)塔问题。这是一个古典的数学问题,是一个用递归方法解题的 典型例子。问题是这样的:古代有一个梵塔,塔内有 3 个座 A、B、c,开始时 A座上有 64 个盘子,盘子大小不等,大的在下,小的在上(见图 8-13)。有一个老和尚想把这64 个盘子 • 174• www.TopSage.com www.TopSage.com 从 A座移到 C座,但每次只允许移动一个盘,且在移动过程中在 3 个座上都始终保持大 盘在下,小盘在上。在移动过程中可以利用 B座,要求编程序输出移动的步骤。

六.数组名作函数参数

数组:
  整型一维
  字符型一维
  整型二维
  字符型二维 
  
int a[10] = {1,2,3,4,5};

a     // --- 整个数组
a[i]  // --- 某个元素 


a[i] //作实参  --- 数组元素做函数实参 --- 和普通变量做函数实参没区别 
printElement(int data)
{

}

a  // --- 整个数组做函数参数 
printArray(int data[10])
{
}
 

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐