C语言进阶之函数①

目录

函数定义:

1.类型标识符

2.函数名 

3.形式参数

4.函数体代码

5.补充:返回结果的类型。

函数调用:

递归

数组作为函数参数


函数定义:

类型标识符 函数名 (形式参数)
{
    函数体代码
}

函数定义的位置:
1.main函数之前。
2.main函数之后,如果是在main之后,需要在使用(函数调用)前,作函数声明。函数头+分号 就是函数声明 。  

1.类型标识符

 就是数据类型 ,表示函数要带出的结果的 类型 。但是要注意数组类型 不能做 函数返回结果的类型 。

2.函数名 

就是标识符 ,命名规则符合 标识符命名规则 。

3.形式参数

表示该函数需要用到的数据 ,为了表明将来使用时,需要用到的实际参数,该怎么写。
     注意:
       a.形参变量,必须都明确指定类型,不能写成 int a,b 。
       b.实参 和 形参对应关系 有以下三点:类型匹配、个数相同、 顺序一一对应的 。          
       c.函数传参  --- 传递的是 实际参数的数值,也就是值传递 。
       d.如果不需要接收实际参数,形参一般设计为void ,表示空类型。

4.函数体代码

 就是 实现函数具体功能的那部分代码 。 

5.补充:返回结果的类型。


     a.如果函数不需要带出什么结果,此时返回结果的类型说明符 一般设计为void 
       如果类型为void,一般不写return 。如果要写,就只写一个return ;
     b.如果 返回结果的类型 与 类型说明符不一致,那么以 类似说明符 为准。最终结果的类型,都会转为类型说明符表示的类型。 
     c.类型说明符,如果不写,默认是 int 类型。

以下是简单的定义示例:求出两个数的和

int add (int num1, int num2)
{
    sum = num1 + num2;
    
    return sum;
}

函数调用:

语法: 函数名(实际参数) //表示使用该功能

eg:add(1,2);

函数调用的关系:main函数是调用者,是整个程序的入口,函数不支持嵌套定义,但是可以嵌套调用。

那么函数是如果进行嵌套调用的呢?

isLeapYear()

{

        ......

}

getMonthDays()
{
   isLeapYear();
}            //函数的嵌套调用 

int main(void) 
{
   printf("%d\n",getMonthDays()); 
   return 0;
}

在上述例子中,main函数调用了getMonthDays()这个函数,而getMonthDays()又调用了isLeapYear()这个函数,这就是函数的嵌套调用。函数名是函数的入口地址,可以通过函数名读取函数所在的地址空间。在main函数中,当运行到调用函数部分的代码时,程序会先保存现场,在调用完函数后再回到main函数时能从之前离开的地方开始执行,叫恢复现场。

其中通过栈(First In Last Out)这个数据结构来保存现场,栈的特点是先入后出,所以保证函数可以进行层层嵌套。

C语言角度的栈,不仅可以存函数,还可以保存局部变量,它的空间是自动申请,自动释放的。本质上是一块内存空间,只是按照 栈 这种数据结构 来处理和使用。linux系统下,栈的默认大小是8兆,可以修改。

C语言程序把内存划分了5个区域 :

(1)栈  :主要    用来存放, 自动变量 或 函数调用的数据。 
(2)堆 : 空间大  堆上的空间 ,需要手动申请,手动释放。 
(3)字符串常量区 : 例如存 "hello" ,只读,不能修改。
(4)静态区(全局区) :全局变量 和 静态变量  
(5)代码区 :指挥数据如何运行的,只读。

递归

递归是一种特殊的函数调用,即自己调用自己。可以分为直接调用和间接调用。它类似循环,可以说这是一种特殊的循环。

递归思路:
   要求问题n , 依赖于问题n-1的解决 。

下面举例说明:

用函数递归实现1到100的累加。

递归代码实现思路:
1.递推关系 
  怎么从 问题 n 到 问题n-1

  sum(100) => sum(99)+100
  sum(99)  => sum(98)+99
  一般情况:sum(n) = sum(n-1)+n;
2.递推结束条件 
  n = 1

3.代码

int sum(int n)
  {
       if(n == 1)
       {
           return 1;
       }
       else
      {
          return sum(n-1) + n;
      }
   }

数组作为函数参数

一维整型数组 做函数 参数 :


      形参  -- 写成数组形式  还需要 数组长度,才能在函数中操作数组。 
      实参  -- 数组名,数组长度

     eg:
       printArrray(int a[],int len) //形参 
       //printArrray (int *a,int len) ---编译器最终理解的形式,因此调用的结果是对应到数组的地址,因此可以在函数中操作数组。 
       //调用
       printArray(a,len); 

int a[10];
数组名 代表类型 ---int[10] 这种数组类型 
数组名 代表的值 ---首元素的地址 //(数组所占内存空间的首地址) 

以下是对一个数组进行选择排序,并封装成函数。传递的参数是一个数组形式和数组长度

void selectionSort(int a[],int len)
  {
      int i, j;
     for(i=0; i<len-1; ++i)
     {
         for(j=i+1; j<len; ++j)
         {
             if(a[i] > a[j])
              {
                 int t = a[j];
                a[j] = a[i];
                a[i] = t;
             }
         }
     }
}
  • 22
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值