IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C语言基础】函数和递归 -> 正文阅读

[C++知识库]【C语言基础】函数和递归

目录

前言

一、函数的基本用法

二、递归



前言

????????函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数?main()?。函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。

? ? ? ? 函数的参数:分为形参和实参。具体的用法在程序中体现。不过可以这样理解,形参实例化之后其实相当于实参的一份临时拷贝。

? ? ? ? 函数的声明和定义:函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。函数的声明一般要放在头文件中的。

? ? ? ? 函数递归:程序调用自身的编程技巧称为递归,通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。递归的两个必要条件。具体用法在编程中体现。

1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。

2.每次递归调用之后越来越接近这个限制条件。


一、函数的基本用法

1.写一个函数,作用是交换输入的两个整数。

#include <stdio.h>

void change1(int x,int y){
    int tem=0;
    tem=x;
    x=y;
    y=tem;
}
void change2(int* x,int* y){                     //此处的*为解引用操作,表示根据指针地址找到对应内存空间
    int tem=0;
    tem=*x;
    *x=*y;
    *y=tem;
}
int main()
{
    int a=10;
    int b=20;
    change2(&a,&b);
    printf("%d,%d\n",a,b);
    return 0;
}
/*
实参a,b和形参x,y没有任何关系(唯一的联系就是形参x,y创建的时候通过实参a,b初始化)
所以调用函数change的时候交换的是x,y。需要交换的a,b并没有交换。
解决问题的办法就是让函数内部就能访问到a,b
*/

2.写一个函数实现冒泡排序

#include <stdio.h>

void bubbleSort(int arr[],int size){
    int tmp=0;
    for(int count=0;count<size;count++){
        for(int i=0;i<size-1-count;i++){
            if(arr[i]>arr[i+1]){
                tmp=arr[i];
                arr[i]=arr[i+1];
                arr[i+1]=tmp;
            }
        }

    }
}
int main()
{
    int arr[]={2,5,9,4,3,7,23,4,11,45,76,2,1};
    bubbleSort(arr,sizeof (arr)/sizeof (arr[0]));
    for(int i=0;i<sizeof (arr)/sizeof (arr[0]);i++){
        printf("%d\n",arr[i]);
    }
    return 0;
}


二、递归

1.递归求一个整数的阶乘

#include <stdio.h>
int fac(int n){
    if(n==1||n==0){
        return 1;
    }else{
        return n*fac(n-1);
    }
}
int main(){
    int a=5;
    printf("%d\n",fac(a));
    return 0;
}

2.递归和非递归实现斐波那契数列

#include <stdio.h>
int fib1(int n){
    if(n==1||n==2){
        return 1;
    }
    else{
        return fib1(n-1)+fib1(n-2);
    }
}
int fib2(int n){
    if(n==1||n==2){
        return 1;
    }
    int last1=1;
    int last2=1;
    int cur=0;
    for(int i=3;i<=n;i++){
        cur=last1+last2;
        last2=last1;
        last1=cur;
    }
    return cur;
}
int main()
{
    printf("%d\n",fib1(10));
    printf("%d\n",fib2(10));
    return 0;
}

注:递归实现斐波那契数列比较容易想到,但是我们可以发现递归实现斐波那契数列会存在大量的重复的计算,于是我们使用循环实现斐波那契数列,这样重复的计算会少很多。程序的运行速度一般来说和是否递归和循环没有太大关系,主要是看重复运行的次数。我们们需要灵活合理的使用递归以及循环。

3.顺序打印一个数的每一位

#include <stdio.h>
void printNum(int num){
    if(num>=10){
        printNum(num/10);
    }
    printf("%d\n",num%10);
}
int main()
{
    int a=2131345;
    printNum(a);
    return 0;
}

4.计算一个数的每一位之和(例:输入2131345输出19)

#include <stdio.h>
int digitSum(int n){
    if(n<10){
        return n%10;
    }else{
        return n%10+digitSum(n/10);
    }
}
int main()
{
    printf("%d\n",digitSum(1792));
    return 0;
}

5.递归和非递归实现求字符串的长度

#include <stdio.h>
int myStrLen(char* str){
    int len=0;
    while(str[len]!='\0'){
        len++;
    }
    return len;
}
int myStrLen2(char* str){
    if(str[0]=='\0'){
        return 0;
    }else{
        return myStrLen2(str+1)+1;
    }
}
int main(){
    printf("%d\n",myStrLen("qwerty"));
    printf("%d\n",myStrLen2("qwerty"));
    return 0;
}

6.编写一个函数,递归实现将字符串中的字符反向排列(不是逆序打印)

思路:假如第一次传入abcdef,交换首尾得到fbcdea,传入bcde,再交换首尾.....直到字符串长度小于2。我们会发现,正确的把参数传入下次函数调用变得很复杂。于是我们换一种思路。

? ? ? ? 同样第一次传入abcdef,将首字符的值用中间变量保存,然后将首字符改为f,尾字符改为'\0'。将str+1传入到下次调用的时候。(此时字符串长度-1,因为'\0'提前了)这样每次中间变量都会将当前首字符的值保存,直到传入的字符串的长度小于2的时候,我们结束递归,当前为{'d','\0'}我们将中间变量保存的值c赋给'd'后面的字符'\0',然后回归到上次调用,继续将中间变量的值赋给后面的'\0'......这样我们就得到了反转之后的字符串。

#include <stdio.h>
#include <string.h>
void reverse_string(char* str){
    //保存字符串的首字符
    char begin=*str;
    //首字符变为尾字符,尾字符变为'\0'
    *str=*(str+strlen(str)-1);
    *(str+strlen(str)-1)='\0';
    //判断递归
    if(strlen(str+1)>=2){
        reverse_string(str+1);
    }
    //'\0'变为首字符(此时的strlen比之前小1)
    *(str+strlen(str))=begin;
}
int main()
{
    char str[] = "abcdef";
    printf("%s\n",str);
    reverse_string(str);
    printf("%s\n",str);
    return 0;
}

?建议通过画图的方式方便自己进一步来理解。

递归,我们不能将‘递’和‘归’割裂开,更应当思考‘递’和‘归’过程中我们应当怎么操作来达到目标。往往我们会将‘归’的过程给忽视,但是只有两部分一起思考才能达到最好的效果。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-16 19:28:07  更:2021-10-16 19:29:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:04:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码