一、函数的概念
1、什么是函数
方法 / 函数
就是定义在类
中的具体的特定功能的一段独立小程序,并能被多次使用。
站在代码复用的角度来考虑,之前的打印矩阵问题。
问题:要画矩阵,需要不断使用该for嵌套代码。造成代码复用性很差。
解决:定义一个功能用于画矩阵,每次只要使用该功能即可。这样提高复用性。
定义一个功能:
1.应该是一个封闭的区间。那就需要使用大括号将其封装。
2.需要给这个区间起名字,以后通过这个名字来调用这个区间
3.这个区间需要有参与运算的数据。
4.需要定义该功能的结果类型。
public static void draw(int row,int col){
for (int x = 0; x < row; x++){
for (int y = 0; y < col; y++){
System.out.print("*");
}
System.out.println();
}
//return;
}
2、函数定义的格式
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,...)
{
执行语句;
return 返回值;//return关键字是用于结束该功能。并将后面的具结果返回给调用者。
//必须有return语句。
}
注意:函数的返回值类型如果是void时,return语句可以省略不写;void表示的是没有返回值的情况。
3、如何定义函数
函数就是一个功能,功能就需要两部分:1.函数运行完的结果是什么;
2.函数运行时有无未知参数。
定义函数时,时刻把握如下两个明确,基本就可以完成函数的定义:
函数的定义:
这个功能的结果是什么?其实就是明确返回值类型。
这个功能需要未知内容是什么?其实就是明确参数列表。
4、定义函数举例
需求:需要一个方法,进行加法运算,获取两个整数的和。
1.功能的结果是什么呢?是一个和,和是整数,返回值的类型是int
。
2.功能的未知内容有吗?有,加数和被加数。都是int
类型,这就是参数列表。
public static int add(int a,int b)
{
return a+b;
}
5、函数的执行过程
class MethodDemo{
public static void main(String[] args) {
int sum = getSum(3,4);
System.out.println(sum);
}
// 定义功能求和
public static int getSum(int a ,int b){
return a + b;
}
}
6、函数的内存加载
class MethodDemo01{
public static void main(String[] args) {
int a = 3;
int b = 4;
int sum = getSum(a,b);
System.out.println("sum="+sum);
}
public static int getSum(int a,int b){
return a + b;
}
}
说明:
1.首先会加载main方法加载进栈内存中,并执行main方法中的代码,分别给a变量开辟空间并存放3,给b变量开辟空间存放4.
2.当程序执行到 int sum = getSum(a,b)时;会将getSum函数加载到栈内存中,同样在getSum所属的栈区域中开辟a和b变量空间,接收main方法中的getSum(a,b)传递的值。
3.然后执行getSum函数中的代码,当getSum函数执行结束后,函数会出栈(弹栈)。
4.程序回到main方法的调用语句int sum = getSum(a,b);处,并将getSum方法执行完成返回的结果赋值给sum变量,程序继续往下执行,打印sum的值。
二、函数的重载(名同参不同)
1、重载的引入
java为我们提供了重载
这个功能,使用重载就可以解决某个功能不同场合的泛用性,一个函数的多个版本。
两个数相加,需要一个函数名字getSum,三个数相加需要一个函数名字getSum2,如果有100个数相加,是不就需要getSum100了?那是不是在调用函数的时候还需要去记住哪个函数名对应多少个参数?这很显然是不可能的了,这个时候就要用重载
。
2、重载的概念
在同一个类中,允许存在一个以上的同名函数,只要它们的参数或者参数类型不同即可,这时就形成了重载。重载和返回值类型无关。
3、重载的举例
完成任意乘法表打印
class MethodDemo03{
public static void main(String[] args) {
printCFB();
}
// 打印标准九九乘法表。
public static void printCFB(){
printCFB(9);
}
// 打印任意乘法表
public static void printCFB(int num){
for (int i = 1; i <= num; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i + "*" + j +"="+ i * j +"\t");
}
System.out.println();
}
}
}
4、重载的练习
以 void show(int a,float b,char c){}
为原函数,判断以下哪些函数重载了;
函数 | 判断结果 |
---|---|
int show(int x,float y,char z) | 没有重载,这个函数不允许和给定函数存在于同一个类中。因为会产生调用的不确定性。 |
void show(float b,int a,char c) | 重载了,参数类型不同。 |
void show(int c,float a,char b) | 没有重载,和给定函数一样。不允许存在。 |
void show(int a,int b,int c) | 重载了,因为类型不同。 |
double show() | 重载了,因为个数不同。 |
5、函数命名规范
在定义函数时,函数名不能使用关键字
,第一个单词的首字母小写,采用驼峰式;由有实际意义的动词或者动词短语。如:getSum.
class Demo07{
// 方法{}里的内容为方法体
public static int computer(int a,int b){
return a + b;
}
public static int computer(int a,int b,int c){
return a + b + c;
}
public static double computer(double a,double b){
return a / b;
}
// public static double computer(double num01,double num02){
// return 0;
// } //函数的参数是一种形式参数
// public static int computer(double a,double b){
// return (int)a / b;
// }
public static void main(String[] args) {
computer(2.3,1.7); //JVM不知道调用结果的,如果重载跟返回值有关,调用时就会产生歧义
computer(1.0,2.0); //参数名也是不会认为参数列表的属性,名称只是形式,所以参数列表里的参数名全是形式参数
}
}
形式参数和实际参数的区别
形式参数:就是在定义函数或过程的时候命名的参数。通俗讲就是一个记号。2 实际参数:就是在执行时,调用函数或过程时,传递给函数或过程的参数。通俗讲就是实际值。3 参数嘛,就是一个可变量,它随着使用者的不同而发生变化。举个例子,在中学的时候学过sin(x)函数,这里的x就是形式参数,当你需要求1的正弦值时,你会使用sin(1),这里的1就是实际参数。4 形参和实参间的关系:两者是在调用的时候进行结合的,通常实参会将取值传递给形参,形参去之后进行函数过程运算,然后可能将某些值经过参数或函数符号返回给调用者。
延伸学习
一、操作符优先级
操作符的优先级还有组合规则确定了操作符计算的顺序。
优先级相同的操作符相邻,则结合规则决定它们的执行顺序。除了赋值运算符意外,其它所有二元操作符都是左结合
的。
二、调试
调试是在程序中找到和修改错误的过程。
逻辑错误称为bug,查找和改正错误的过程称为调试(debugging)。调试的一般步骤采用各种方法缩小程序bug的所在范围,可以手动跟踪也可以插入打印语句。
一个调试功能大多数包含:
- 一次执行一条语句:调试器允许一次执行一条从而看到每句的问题。
- 跟踪进入一个具体方法:如果一个方法正在执行,可以让调试器进入这个方法内部,一次执行一条语句。或者让整个调试器跳过这个方法全部执行。
- 设置断点:你可以在一条特定的语句上面设置断点。当遇到一个断点,你的程序将要停止。需要查看什么语句的执行,就把断点设置在什么地方。
- 显示调用堆栈:宏观观察变量的内存占用。
- 显示变量:显示内存中变量的名称和内容。