文章目录
使用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); } }
递归对于初学者是个障碍,但我们越是困难,越是要战胜它,最终发现递归之美
任何实物都是双刃剑,递归也不例外
优点:某些让人头疼问题使用递归可以很简单很方便的解决
缺点:一些递归算法会快速消耗计算机的内存资源,并且递归不方便阅读和维护
效率优先的程序,对于递归实现的方案要慎重考虑
&运算符
指针是C语言最重要(也是最复杂)的概念之一,用于储存变量的地址。
scanf 函数就使用地址作为参数
如果主调函数不使用return返回的值,则必须通过地址修改主调函数中的值
一元运算符&(我通常叫它取地址符)给出变量的存储地址。
#include<stdio.h> int main() { int a; scanf("%d",&a); printf("%d and %p",a,&a); return 0; }
%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; }
编写程序时,暂时可以认为变量有两个属性:变量名和值
经过计算机编译连接之后……
认为变量也有两个属性:地址和值,地址时变量在计算机内部的表示,就好像指纹识别一样,可以这样理解
许多语言,地址都归计算机管理,对程序员不可见。在C中,我们可以通过&访问地址,*获取地址上的值,当然这些只是基础的操作,使用&,*和指针可以操作地址和地址上的内容(🐂)
小结
函数可以作为大型程序的构建块,如果想用C写出高效灵活的程序,就必须理解函数,模块化编程,把大化小,解决小,小事化了。同时使用函数来组织模块,锻炼思维,方便调试维护和添删……要理解函数参数和返回值的原理,函数形参和局部变量属于函数私有,
函数无法直接访问其他函数中的变量,这种限制访问同时也保护了数据的完整性,当确实需要访问时,可以把指针(地址)作为函数的参数,对地址进行操作,打破限制🆗仔细品