函数递归与指针基础

简介: 函数递归与指针基础

文章目录


使用return从函数中返回值


函数类型


递归


&运算符


初识指针


间接运算符:*


声明指针


使用指针在函数间通信


小结


使用return从函数中返回值



前面学习了从主调函数传递给被调函数,反过来,函数的返回值也可以从被调函数传回主调函数,使用关键字return,举个栗子:


#include<stdio.h>
int min(int a,int b);
int main(void)
{
    printf("%d",min(2,5));
}
int min(int a,int b){
    return (a<b)?a:b;
}


返回值不一定是变量的值,也可以是表达式的值,上面代码返回的就是


使用return语句的另一个作用是,终止函数并把控制返回给主调函数的下一条语句

return;这条语句会导致函数终止,并把控制返回主调函数。因为return语句后面没有任何表达式,所以没有返回值,只有在void形式中才会用到


函数类型



声明函数时必须声明函数的类型。带返回值得函数类型应该与其返回值得类型相同,没有返回值得函数应用void类型声明


递归


又来了,哈哈,C允许函数调用它自己,这种调用的过程称为递归


简单量可以假设有一条递归链条,函数a1调用了函数a2,a2调用了a3,a3有调用了a4,当a4结束时,返回值传给a3,a3结束时,返回值传回a2,a2结束时,传回到a1,递归就是这,只不过在递归中调用的就是本身,即 a1,a2,a3,a4是同一个函数


递归和循环很相似,递归有时可用循环来代替,循环有时也能用递归来实现


此外,递归函数必须包含能让递归调用停止的语句。通常使用 if 或其他的测试条件在函数形参等于某值时终止递归


一个使用递归求阶乘的栗子:


#include<stdio.h>
int sun(int a);
int main(){
    int a,b;
    printf("请输入整数\n");
    scanf("%d",&a);
    b=sun(a);
    printf("a的阶乘是 %d",b);
    return 0;
}
int sun(int a)
{
int sum;
if(a==0||a==1){
    sum=1;
}
else{
    sum=a*sun(a-1);
}
return sum;
}


这是for循环实现的


#include<stdio.h>
int main()
{
    int a,b=1;
    printf("请输入整数\n");
    scanf("%d",&a);
    if(a==0||a==1)
    {
        printf("%d",b);
    }
    else
    {
        for(int c=1;c<=a;c++){
            b=c*b;
        }
        printf("%d",b);
    }
}

20210712223102176.png


递归对于初学者是个障碍,但我们越是困难,越是要战胜它,最终发现递归之美


任何实物都是双刃剑,递归也不例外


优点:某些让人头疼问题使用递归可以很简单很方便的解决


缺点:一些递归算法会快速消耗计算机的内存资源,并且递归不方便阅读和维护

效率优先的程序,对于递归实现的方案要慎重考虑


&运算符


指针是C语言最重要(也是最复杂)的概念之一,用于储存变量的地址。


scanf 函数就使用地址作为参数


如果主调函数不使用return返回的值,则必须通过地址修改主调函数中的值


一元运算符&(我通常叫它取地址符)给出变量的存储地址。


#include<stdio.h>
int main()
{
    int a;
    scanf("%d",&a);
    printf("%d and %p",a,&a);
    return 0;
}

45.png


%p是输出地址的转换说明(我的💻是64位的,64/4=16,看到地址是一个十六位的十六进制补码)


初识指针


从根本看,指针是一个值为内存地址的变量(或数据对象)int类型变量的值是整数,指针类型变量的值是地址


a=&b;//把b的地址(常量)赋值給变量a
a=&s;//现在a指向s,而不是b


要创建指针变量,先要声明指针变量的类型。(int char……)


间接运算符:*
int b=3;
a=&b;//把b的地址给变量a
c=*a;//找出a所指向的值3
//相当于下面的语句
c=b;
//这间接运算符,名副其实,小三🙄


声明指针



int *a;
float *b,*c;
char *d;


*和指针名之间的空格可有可无,通常在声明时使用空格,在解引用变量时省略


指针实际上是一种新类型,不是整数类型。ANSI C专门为指针提供了%p格式的转换说明


使用指针在函数间通信



指针的世界就好比二次元的女主,这样形容是不是有意思起来了


#include<stdio.h>
void change(int *a,int *b);
int main()
{
int x,y;
x=5;
y=2;
printf("x = %d , y = %d\n",x,y);
change(&x,&y);
printf("x = %d , y = %d",x,y);
return 0;
}
void change(int *a,int *b)
{
int c;
c=*a;
*a=*b;
*b=c;
}

47.png


编写程序时,暂时可以认为变量有两个属性:变量名和值

经过计算机编译连接之后……

认为变量也有两个属性:地址和值,地址时变量在计算机内部的表示,就好像指纹识别一样,可以这样理解


许多语言,地址都归计算机管理,对程序员不可见。在C中,我们可以通过&访问地址,*获取地址上的值,当然这些只是基础的操作,使用&,*和指针可以操作地址和地址上的内容(🐂)


小结


函数可以作为大型程序的构建块,如果想用C写出高效灵活的程序,就必须理解函数,模块化编程,把大化小,解决小,小事化了。同时使用函数来组织模块,锻炼思维,方便调试维护和添删……要理解函数参数和返回值的原理,函数形参和局部变量属于函数私有,


函数无法直接访问其他函数中的变量,这种限制访问同时也保护了数据的完整性,当确实需要访问时,可以把指针(地址)作为函数的参数,对地址进行操作,打破限制🆗仔细品





相关文章
|
20天前
|
搜索推荐 C语言 C++
【C指针(五)】6种转移表实现整合longjmp()/setjmp()函数和qsort函数详解分析&&模拟实现3
【C指针(五)】6种转移表实现整合longjmp()/setjmp()函数和qsort函数详解分析&&模拟实现
|
28天前
|
安全 C语言 C++
字符指针做函数参数
字符指针做函数参数
9 1
|
1月前
|
安全 C语言
字符指针作函数参数的深入探索
在C语言编程中,字符指针是一个重要的概念,尤其在处理字符串和文本数据时。当我们将字符指针作为函数参数时,可以实现多种灵活和高效的操作。本文将深入探讨字符指针作为函数参数的应用,并通过代码示例加以说明。
13 1
|
1月前
|
存储 Shell C语言
指针数组组main函数的形参
指针数组组main函数的形参
10 0
|
1月前
|
C语言 C++
指针变量作为函数参数
指针变量作为函数参数
8 1
|
1月前
|
存储 Serverless 编译器
怎样定义和使用指向函数的指针变量
怎样定义和使用指向函数的指针变量
8 0
|
1月前
|
C++
用指向指针函数作函数参数
用指向指针函数作函数参数
8 1
|
1月前
|
存储 C语言 C++
什么是函数的指针
什么是函数的指针
8 0
|
1月前
|
存储 C语言
c语言函数指针和指针函数的区别,以及回调函数的使用。
c语言函数指针和指针函数的区别,以及回调函数的使用。
9 0
|
1月前
|
存储 程序员 C语言
18.C语言:指针数组作main函数的形参示例
18.C语言:指针数组作main函数的形参示例
15 0