c语言--函数与递归

1.函数又叫方法,是指实现某项功能或完成某项任务的代码块

//函数的主体从大括号开始,从大括号结束
//函数组成
//main函数,是给系统调用的函数
//函数组成: 返回值, 函数名, 传入参数
//如: 实现两个整数相加,返回它们的和

void show(void)
{
    printf("hello world!\n");
}

int add(int x, int y)
{
    return x+y;
}

int main(int argc, const char * argv[])
{
    int val;
    show();
    val = add(3, 5);
    printf("%d\n",val);
    return 0;
}
//函数组成: 函数名 函数接口 函数体 返回值
//函数调用
//带参数的函数

//函数的返回值就是函数运行的结果
//形式参数也叫参变量,实际上就是变量
//实际参数是实际存在的数值
//形参相当于函数中定义的变量,调用函数传递参数的过程相当于定义形参的变量用实参的值来初始化

//我们把在函数内部定义的变量称为局部变量

void print_time1(int hour, int minute)
{
    printf("%02d:%02d\n", hour, minute);
    printf("%p %p\n", &hour, &minute);
}
void print_time2(int hour, int minute)
{
    print_time1(hour, minute);
    printf("%p %p\n", &hour, &minute);
}
int main(int argc, const char *argv[])
{
    int hour, minute;
    hour = 12;
    minute = 43;
    printf("%p %p\n", &hour, &minute);
    print_time2(hour,minute);

    return 0;
}

局部变量就是在函数体内部声明的变量,它只在函数体内部有效,也就是说只能在本函数内部使用它,在本函数外是不能使用的,只有在函数被调用的使用,变量才会在内存上分配空间,调用结束,内存释放;

测试局部变量每次分配内存位置不确定

全局变量是在函数体外部定义的变量(包括main函数),它不属于哪个函数,而是属于源程序,因此全局变量可以为程序中得所有函数调用,它的有效范围从定义开始到源程序结束;

全局变量的生命很长,它在程序的整个执行过程中都占用内存,当程序结束时,该变量的"寿命"才结束,系统这才释放它所占用的内存

全局变量的缺点:值容易被修改

作用域,局部变量的作用域是从变量的定义开始到右大括号结束,全局变量的作用域是从变量的定义开始到源程序的结束

函数的声明及定义

函数的声明就是告诉编译器知道有什么样的函数存在,可以在后面找到它,假如没有声明,那么就有可能会出现找不到函数的错误

库函数的使用: 条用库函数时 , 需要包含库函数的头文件

2.函数的递归调用

一个函数在它的函数体内调用它本身,称之为递归函数

C语言中允许递归调用, 递归调用中,主调函数又是被调函数

为了防止递归无终止进行,必须在函数体内有终止递归调用的条件

常用的办法就是加条件判断语句,满足某种条件后就不在递归调用,逐层返回

数学上有这样的定义 n的阶乘等于n乘以n-1的阶乘,n-1的阶乘等于(n-1)*(n-2)!

这样下去永远也没有完,所以需要定义一个基础条件

基础条件: 0的阶乘为1

n! = n*(n-1)!

0! = 1

因此 3! = 3*2! = 3*2*1!= 3*2*1*0!= 3*2*1 = 6;

正因为有了基础条件,才没有无休止的进行下去

那么我们用程序怎么样去实现呢

一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。用递归思想写出的程序往往十分简洁易懂。

一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

注意:

(1) 递归就是在过程或函数里调用自身;

(2) 在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口,否则将无限进行下去(死锁)。

递归算法一般用于解决三类问题:

(1)数据的定义是按递归定义的。(Fibonacci函数)

(2)问题解法按递归算法实现。(回溯)

(3)数据的结构形式是按递归定义的。(树的遍历,图的搜索)

递归的缺点:

递归算法解题的运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。

int factorial(int n)
{
    if (n==0)
    {
        return 1;
    }
    else
    {
        int recurse = factorial(n-1);
        int result = recurse * n;
        return result;
    }
}
//斐波那契数列
//1 1 2 3 5 8 13 21 34 55 89 144 ....
int fibonacci(int n)
{
    if (n==0||n==1)     {
        return 1;
    }
    else {
        int val = fibonacci(n-1) + fibonacci(n-2);
        return  val;
    }
}

eg.编写递归函数求两个正整数a和b的最大公约数(GCD,Greatest Common Divisor),使用Euclid算法!

//如果a除以b能整除,则最大公约数是b。
//
//否则,最大公约数等于b和a%b的最大公约数。
//
//Euclid算法是很容易证明的,请读者自己证明一下为什么这么算就能算出最大公约数。最后,修改你的程序使之适用于所有整数,而不仅仅是正整数。

int euclid(int a, int b)
{
    if(a%b==0)
    {
        return b;
    }
    else
    {
        return euclid(b, a%b);
    }
}

eg.趣味问题——年龄。有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?用递归算法实现

int age(int n)
{
    if (n==1) {
        return 10;
    }
    else{
        return age(n-1)+2;
    }
}
时间: 2024-10-10 14:48:11

c语言--函数与递归的相关文章

C语言函数的递归调用

一个函数在它的函数体内调用它自身称为递归调用,这种函数称为递归函数.执行递归函数将反复调用其自身,每调用一次就进入新的一层. [示例]用递归计算 n!.阶乘 n! 的计算公式如下: 根据公式编程: long factorial(int n){ long result; if(n==0 || n==1){ result = 1; }else{ result = factorial(n-1) * n; // 递归调用 } return result; } 这是一个典型的递归函数.调用factoria

【学习ios之路:C语言】函数及递归的简单应用

函数定义: 返回值类型 函数名(形参列表){函数体(函数的实现内容)}; 函数定义的四种形式: //函数定义第一种形式: 无参数, 无返回值 void byMilk() { //如果没有参数,小括号必不可少. printf("没钱\n"); } //函数名的命名规范:由多个英文单词组成,除了第一个单词的首字母小写,其余单词首字母大写. //函数定义第二种形式,有返回值,无参数 float salary() { printf("同志们辛苦了\n"); return 0

c语言函数, 函数调用及函数递归

1. 函数的定义: 返回值类型 函数名(形参列表) {函数体(函数的实现内容)}, 注意: 如果没有参数, 小括号也是必不可少的.  函数与函数之间可以嵌套调用(也就是在一个函数内部可以调用另外一个函数), 但是不能嵌套定义(不能在一个函数内部定义另外一个函数) 形参: 形式上的参数, 在函数定义时, 给定的参数叫做形参, 是一个一个的变量, 存储的数据在调用之前完未知 实参: 函数调用时给定的参数叫做实参, 是一个唯一确定的数据. 实参向形参传递的过程是一个拷贝的过程 函数相当于公司的部门,

C语言中的递归

思路 下图描述的是从问题引出到问题变异的思维过程: 概述 本文以数制转换为引,对递归进行分析.主要是从多角度分析递归过程及讨论递归特点和用法. 引子 一次在完成某个程序时,突然想要实现任意进制数相互转换,于是就琢磨,至少涉及以下参数: 源进制数:scr 目标进制:dest_d实现的大致思路: scr --> 数字分解 --> 按权求和 --> dest很明显这个过程是先正序分解,然后逆序求和,所以我就联想到了递归. 递归 1. 递归的含义 递归就是递归函数.递归函数是直接或间接调用自身的

紫书第4章 函数和递归

1  序 系统的整理下第四章的学习笔记.同上次一样,尽量在不依赖书本的情况下自己先把例题做出来.这次有许多道题代码量都比较大,在例题中我都用纯C语言编写,但由于习题的挑战性和复杂度,我最终还是决定在第五章开始前,就用C++来完成习题.不过所有的代码都是能在C++提交下AC的. 在习题中,我都习惯性的构造一个类来求解问题,从我个人角度讲,这会让我的思路清晰不少,希望自己的一些代码风格不会影响读者对解题思路的理解. 其实在第四章前,我就顾虑着是不是真的打算把题目全做了,这些题目代码量这么大,要耗费很

Python基础之内置函数和递归

本文和大家分享的主要是python中内置函数和递归相关内容,一起来看看吧,希望对大家学习python有所帮助. 一.内置函数 下面简单介绍几个: 1.abs() 求绝对值 2.all() 如果 iterable 的所有元素都为真(或者如果可迭代为空),则返回  True 3.any() 如果 iterable 的任何元素为真,则返回  True .如果iterable为空,则返回  False 4.callable() 如果  object 参数出现可调,则返回  True ,否则返回  Fal

C语言函数的一些简单总结

C源程序采用是函数模块式的结构,每一个程序都是由很多个函数组成的,函数是C源程序的基本模块,C语言不仅提供了极为丰富的库函数,他还允许用户自己根据需求创建需要的函数,然后用函数调用的方法来使用该函数,正式这种函数模块化的设计,使得程序的层次结构清晰,便于程序的编写.阅读和调试 main 函数在C语言中称为主函数,它可以调用其它函数,而不允许被其它函数调用.因此,C程序的执行总是从main函数开始,完成对其它函数的调用后再返回到main函数,最后由main函数结束整个程序.一个C源程序必须有,并且

c语言函数的秘密

一:自创函数 C语言提供了大量的库函数(右侧资料下载中有),比如stdio.h提供输出函数,但是还是满足不了我们开发中的一些逻辑,所以这个时候需要自己定义函数,自定义函数的一般形式: 注意: 1.[]包含的内容可以省略,数据类型说明省略,默认是int类型函数:参数省略表示该函数是无参函数,参数不省略表示该函数是有参函数: 2.函数名称遵循标识符命名规范: 3.自定义函数尽量放在main函数之前,如果要放在main函数后面的话,需要在main函数之前先声明自定义函数,声明格式为:[数据类型说明]

不可或缺 Windows Native (6) - C 语言: 函数

[源码下载] 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 函数 示例cFunction.h #ifndef _MYHEAD_FUNCTION_ #define _MYHEAD_FUNCTION_ #ifdef __cplusplus extern "C" #endif // 函数声明 // 像这种在 .h 中声明的函数,如果想被外部文件调用的话,则外部文件不用再声明即可调用 char *demo_cFunction(); long recursion