跟日记本一起学JAVA!相信你可以的,加油~
本课闯关内容:1.照猫画虎(0/6)
2.基础知识(0/4...)
———————————————————————————————————————————
那我们今天主要学习的是函数,这并不像我们通常说数学意义上的函数,期待吧🌚,我好久没发了。
咱们输入代码经常会出现一些代码的重复,代码量太大了例如:你使用for循环时,你要输入好几个for循环,并且这几个for循环你还要输入好几次,你就傻愣愣的硬输入那么多,这就是在Java中称作代码的冗余,嗯~,,,,这时就需要Java中的函数。
存在的问题:
- 代码冗余,代码量太大
- 维护性差,复制容易,修改难如何解决此问题????
- 对反复的代码只写一次,并对它起个名字
- 想使用次功能代码时,只需要通过名字执行对应的功能即可。
基础知识1:
一、函数的概念【理解】
- 概念:执行特定功能代码组成的一个整体,可以通过名字(就是你给函数它起一个名字)反复使用。
- 使用函数流程: 定义函数: 函数的声明 : 约定函数实现功能 -->名字 函数的实现:实现对应的函数约定的功能。-->将特点功能代码给出 函数的调用:通过函数名让函数执行对应的功能代码。(你一引用它的名字它就听话的起它的作用)
重点!!!!!: 函数的定义位置:定义在类以内,与main函数并列的位置。(class不就是类吗看下面第一个照猫画虎代码,里面写着1->不可以,4->可以等等...就是这些,我们一般写在5的位置)
二.函数的定义:【重点】
语法 (就是公式):public static 返回值类型 函数名(数据类型 变量名,数据类型 变量2){
// 函数的功能代码->函数的实现(函数体)
}
三.函数的声明:public static 返回值类型 函数名(数据类型 变量名, 数据类型 变量名2)
函数的返回值类型、函数名、形参列表称为函数的三要素。
1.函数名: 望文生义,遵循驼峰命名法(第一个单词的首字母小写,其余单词首字母大写)
2.参数(也叫函数的参数):调用者调用函数的时,传递的数据成为参数。
形式参数: 在函数声明的时候 ()中定义的参数(就是个变量,没有具体的值)称为形式参数,简称形参。(
就是这里面的,加粗字段里的括号
public static 返回值类型 函数名(数据类型 变量名,数据类型 变量名2){
// 函数的功能代码->函数的实现(函数体)
}
(1)使用:形式参数它相当于 函数的内容的局部变量,在函数内部可以直接通过参数名直接使用(只能在当前那里块函数内部使用)
(2)形式参数的定义 :函数声明 (数据类型 参数名,数据类型 参数名) -> 可以定义n个(你想定义几个就定义几个)
实参:实参给形参赋值,实参必须和形参 的个数、顺序、类型一致。(在函数调用时的括号里写的具体的东西,就是给形参赋值)
3.返回值类型 :约定了函数返回给调用者的结果类型
(1)返回值结果为 void ,则代表函数没有结果返回,但是可以 return ; 结束当前函数的调用。
(2)返回值类型为 8种基本数据或是对象类型,代表函数必须有 return XXX; 语句 return 返回的结果必须和约定的返回值类型结果一致。
(3)return 的作用:
1.将函数的结果 返回给调用者
2.结束当前函数 (return 语句后面不允许在定义任何的语句)
(4)注意事项:如果 return 语句定义在分支结构中,必须保证每一个分支都有return 语句。
有一些情况下,必须有返回值,自己探索。(例如:你让一人去取钱)
函数的实现:{}
照猫画虎1:
package demo;
//函数1->不可以
public class Test1{
//4->可以
public static void main(String[] args){
//每行之间利用30个 = 隔开
//代码的冗余(重复的代码写多次)->代码维护麻烦
/*
重复的代码写一遍 -> 起名字
*/
System.out.println("好好学习");
printLine();//函数的调用
System.out.println("天天向上");
printLine();
System.out.println("good good study");
printLine();
System.out.println("day day up");
printLine();
//3->不可以
}
//5->可以,函数的位置,必须是类以内,其他函数的外面
//函数的定义,先定义再用
public static void printLine(){
//函数的功能
for(int i=1;i<=30;i++){
System.out.print("+");
}
System.out.println();//换行
}
}
//2->不可以
输出:
好好学习
++++++++++++++++++++++++++++++
天天向上
++++++++++++++++++++++++++++++
good good study
++++++++++++++++++++++++++++++
day day up
++++++++++++++++++++++++++++++
基础知识2:
!!!先写定义在写调用。
二、函数的调用:【重点】
- 函数的调用(没带参数的调用):
语法:函数名(); // 可以被调用 n 次 - 带参数的调用:
语法:函数名(数值,数值2);
调用者传递的数值被称为实际参数,简称为实参。
实参的作用:实参给形参赋值,实参必须和形参 的个数、顺序、类型一致。 - 带有返回值的函数调用:
数据类型 变量 = 函数名(实参); // 数据类型 需要和返回值的数据类型一致(没有返回值直接调用就行)
带有返回值的函数调用之后,对结果可以不进行任何处理 // 应用场景几乎没有
带有返回值的函数调用之后,直接参与打印或是运算
System.out.println();(这个语句是换行)
照猫画虎2:
package demo;
public class Test2{
public static void main(String[] args){
//实际参数:个数,顺序,类型必须和形参一致
printLine('=',60);//函数调用(数据)->实际参数,简称实参,实参给形参赋值
System.out.println("好好学习");
printLine('+',30);//函数的调用,+,30
System.out.println("天天向上");
printLine('-',35);//-,35
System.out.println("good good study");
printLine('*',40);//*,40
System.out.println("day day up");
printLine('~',45);//~,45
}
//函数的定义:函数的声明,函数的实现
public static void printLine(char x,int n){//函数的声明---->(数据类型 变量名)->形式参数,简称形参
//函数的功能->函数的实现
for(int i=1;i<=n;i++){
System.out.print(x);
}
System.out.println();//换行
}
}
输出:
============================================================
好好学习
++++++++++++++++++++++++++++++
天天向上
-----------------------------------
good good study
****************************************
day day up
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
照猫画虎2中的printLine,就是我给这个函数起的名字。
printLine(char x,int n)里的char x,int n就是我定的形参,前面是char类型,后面是int类型。
我要对此函数调用,我可以写
printLine('=',60);
前面的'='就是char类型,后面的60就是int类型,因为你一开始定义这个函数时的形参就是前面是char类型,后面是int类型。
在照猫画虎1中函数为printLine(),括号里什么都没有,那么在上面调用时括号里就啥也没写。
就是我在定义时的括号里写的什么形参,你调用时的函数里的括号就要写那样的形参!!!
照猫画虎3:
package demo;
public class Test3{
public static void main(String[] args){
// 调用add函数
add(100);
add(50);
}
// 定义函数add,接收一个int类型的参数n,将0~n之间的数据和计算,并打印
public static void add(int n){
int sum = 0;
for(int i=0;i<=n;i++){
sum+=i;
}
System.out.println("sum="+sum);
}
}
输出:
sum=5050
sum=1275
照猫画虎4:
package demo;
public class Test4{
public static void main(String[] args){
// 调用add函数,并传递(8,9),接收两个数据加和,并判断和的奇偶数
int r=add(8,90);
System.out.println("r="+r);
if(r%2==0){
System.out.println("偶数");
}else{
System.out.println("奇数");
}
System.out.println( add(8,20) );
}
// 定义函数 add,接收两个 int类型数据,计算两个数据的加和,并返回
public static int add(int a,int b){
int sum=0;
sum=a+b;
//System.out.println("sum="+sum);
return sum;
}
}
输出:
r=98
偶数
28
照猫画虎4定义的为两个int类型加和,那么定义的返回值就要为int类型,后面返回的sum就为int类型,你把sum改成2,3...都行,因为2,3都是整型int类型。
那么8.9可以吗?
不行!!!这不是整型,是小数。
这里的r是名字,这里的名字是任意的,你写sum也行,与下面的sum不冲突。
基础知识3:
1.函数的嵌套调用:被调函数的内部,又调用了其他的函数。
2.函数的执行原理:程序执行过程中,遇到函数的调用,则程序跳到被调用的函数内部执行,被调用函数执行完之后,如果有返回值带着返回值返回到调用位置,没有返回值,直接返回到被调用的位置,程序继续往下执行。
照猫画虎5:
package demo;
public class Test5{
public static void main(String[] args){//
System.out.println("---main..start..1");//
ma();
System.out.println("---main..end..2");//
}
public static void ma(){
System.out.println("---main..start..3");//
mb();//嵌套函数
System.out.println("---main..end..4");//
}
public static void mb(){
System.out.println("---main..start..5");//
System.out.println("---main..end..6");//
}
}
输出:
---main..start..1
---main..start..3
---main..start..5
---main..end..6
---main..end..4
---main..end..2
和那个for循环的嵌套类似,好好看一看上面的顺序。
基础知识4:
递归调用【理解】 (自己调用自己)
自己调用自己
(就是在你自己的函数之中在写一遍你自己的函数的调用语句,例如,把照猫画虎5改一改:
package demo;
public class Test5{
public static void main(String[] args){//
System.out.println("---main..start..1");//
ma();
System.out.println("---main..end..2");//
}
public static void ma(){
System.out.println("---main..start..3");//
mb();//嵌套函数
System.out.println("---main..end..4");//
}
public static void mb(){
System.out.println("---main..start..5");//
mb();
System.out.println("---main..end..6");//
}
}
改了mb函数内的东西,在mb函数中又加了一个mb(),这不就是自己调用自己嘛
)
哇~无穷无尽,最终内存耗尽,出错,怎么解决呢
- 概念:一个函数的内部调用了自身函数,这种现象称为递归调用。
- 实际开发中,需要给递归设置合理的出口,避免无穷递归。
照猫画虎6:
package demo;
public class Test6{
public static void main(String[] args){//
System.out.println(jiecheng(0));
}
//函数的计算: 计算n的阶乘
public static int jiecheng(int n){
if(n==1 || n==0)return 1;//出口
return n*jiecheng(n-1);//n*(n-1)的阶乘
}
}
输出:
1
这里的jiecheng是函数的名字,阶乘公式为n*(n-1)
在你没学函数之前,你写阶乘可能会这样写:
(这一部分不要在意
class TestFunction{
public static void main(String[] args){
System.out.println(jiecheng_5(5));
}
)
主要内容:
public static int jiecheng_5(int n){
return n* jieCheng_4(n-1);
}
public static int jiecheng_4(int n){
return n* jieCheng_3(n-1);
}
public static int jiecheng_3(int n){
return n*jieCheng_2(n-1);
}
public static int jiecheng_2(int n){
return n*jieCheng_1(n-1);
}
public static int jiecheng_1(int n){
return 1;
}
这不就是代码的冗余嘛,主要内容的代码之间有共同点,这不就用到函数了嘛。
现在的代码:
public static int jiecheng(int n){
if(n==1 || n==0)return 1;//出口
return n*jiecheng(n-1);
}
出口,就是让它不能一直调用,给它一个返回点,那么当n=0,1时,就停止调用了。
跟我一步步学,慢慢走。
未完待续。。。