Spoiler alert! This page contains the solution to the last exercise in the “IFs” lesson! Do not read until you solved that puzzle!
In the last page, you wrote code to print the value of a digit in English language (“one” for 1, “two” for 2, etc, up to “nine”).
The code might have looked like this:
public class HelloWorld {
public static void main(String[] args) {
int i = 5;
if (i == 0) {
System.out.println("zero");
}
if (i == 1) {
System.out.println("one");
}
if (i == 2) {
System.out.println("two");
}
if (i == 3) {
System.out.println("three");
}
if (i == 4) {
System.out.println("four");
}
if (i == 5) {
System.out.println("five");
}
if (i == 6) {
System.out.println("six");
}
if (i == 7) {
System.out.println("seven");
}
if (i == 8) {
System.out.println("eight");
}
if (i == 9) {
System.out.println("nine");
}
}
}
The problem is, this code has general utility – printing a human representation of a digit can be useful in many places of your program – but it’s a lot of repetitive code that would have to be laboriously re-typed everywhere where it’s needed.
To solve this problem, modern programming languages have something called “a function”. A function is a named segment of the program that encapsulates some action so it can be used multiple times.
The function is written in code as follows:
"public static" "return type" name(arguments) {
// function code
}
For the purpose of this language, “public static” is just a magical incantation. We will explain what this spell means in the following lessons, but it will take time. For now, just insert it before function code and don’t think about it.
“return type” defines what a function does. A function can do some calculations and return the result, for example, a number. In this case, return result might be “int”, a number. Or a function can do something else, and there is no return result, in which case the “return type” is void.
// This function computes cube of a number
public static int cube(int i) {
int j = i * i * i;
return j;
}
// This function prints cube of a number
public static void printCube(int i) {
int j = i * i * i;
System.out.println(j);
}
The way you would call these functions would be:
public class HelloWorld {
// This function computes cube of a number
public static int cube(int i) {
int j = i * i * i;
return j;
}
// This function prints cube of a number
public static void printCube(int i) {
int j = i * i * i;
System.out.println(j);
}
public static void main(String[] args) {
int i = cubed(5);
System.out.println(i);
printCube(6);
}
}
Exercise
Put the code above in Eclipse and run it.
The most important concept that needs to be understood about the function is the notion of function arguments. I glossed over them in the examples above; we will take on this concept now.
Large programs are usually written by large teams of programmers, usually at the same time. Each programmer works on a part of the code separate from others. Usually, the program gets broken up into smaller pieces, each one its own group of functions, and one programmer implements such small piece.
Programmers have to coordinate with each other about what each function does, but they prefer to not expose their colleagues to the minute details of how these functions are implemented, for example, the variable names is such a minute detail.
For this reason, a variable in function A can be named the same as a variable in function B. These are, logically, different variables – but the name is the same.
public static void A() {
int i = 5;
// do something with i
}
public static void B() {
int i = 546;
// do something else with i
}
“i” in A and “i” in B are completely different things – they are different memory locations, they participate in different calculations – but because “i” is a common name, even the same programmer can choose to use it in different functions to mean different things.
So when programmer talk about variables, they talk about different “contexts”. Usually, the context of a variable that is used in a function is that function. That variable names a memory location in that function, and that’s it. That same name can be reused to mean a (different) memory location in a different function.
So that’s the context of a scope. Now, back to function arguments. Let’s say we have a simple function that computes a cube of a number:
public static int cube(int i) {
int j = i * i * i;
return j;
}
The way function might be used is as follows:
public static void PrintSomeCubes() {
int i = cube(5);
System.out.println(i);
i = cube(6);
System.out.println(i);
i = cube(7);
System.out.println(i);
}
Take a look at the above. First, as a variable, “i” can be reused several times to store different locations in the same function – PrintSomeCubes. Second, the same name, “i”, names different things inside both cube and PrintSomeCubes function. This is, as we discussed above, allowed, because a person who implemented cube and a person who implemented PrintSomeCubes do not want to discuss variable naming between them.
But most importantly – inside cube function “i” is not just a variable – it is a parameter. It allows cube to run many times with different values of “i”, where what “i” contains is specified not by the person who WROTE cube function, but by the person who USES it.
When cube has been called from PrintSomeCubes, the first time “i” inside cube contained 5. Second time, it contained 6. Third time, it contained 7.
A function can take multiple parameters. For example, this function computes a sum of squares of two numbers:
public static int sumSquares(int i, int j) {
int k = i * i + j * j;
return k;
}
Exercise
Write a program that uses sumSquares above to compute and print the results for the following parameter pairs (0, 0), (0, 1), (3, 4), (6, 7).