II. Fundamentals of Programming
Programming languages are to the computer programmer what written languages are to the writer. Therefore, they must be good to work with. But what makes a powerful programming language? The authors of Java, the programming language with which we will work with throughout this website, claimed and summarized the language's power with these buzzwords:
Simple, object oriented, distributed, robust, secure, architecture neutral, portable, interpreted, high performance, multithreaded, and dynamic
To the beginner of computer programming, these words mean nothing and indeed do not relate to the core part of programming. In its true roots, a powerful programming language has to have at least three elements, which, in the words of Professors Harold Abelson and Gerald Sussman at MIT, are primitive expressions, means of combination, and means of abstraction.
Primitive expressions are the most basic element of a programming language. They represent the stuff we manipulate in a computer program. This "stuff" includes what are called data and procedures.
Means of combination are ways with which we put together primitive expressions to represent more complex data and procedures.
Means of abstraction are ways with which we give names to data and procedures so that we can have a more systematic and organized way of programming. There are also many other advantages to data abstraction that we will soon discover in this website.
Indeed, these three elements are the backbones of a good programming language. Most of the popular languages of today, including Java, fit these criteria. However, we picked Java for this website because it is widely popular and has many characteristics like those mentioned earlier in the "buzzwords" that might prove useful in the future but are not essential to the basis of computer science.
A. Expressions, data types, and variables
When we program in a high-level language, we do not type in binary code. Indeed, programming languages are set-up so that they are more readily comprehensible by us humans. The four basic arithmetic operations (addition, subtraction, multiplication, and division) can be represented with +, - , *, and / in Java. There is also what is called the modulo operator % which divides two numbers and gives the integer remainder.
For example, if we want to add two numbers, 5 and 6, we would just type in the following
in Java and many other programming
languages. The code
In technicality, Java expressions comprises of what are called literals, variables, operators, or a combination of them. Literals are constant values like numbers, operators are things like the adding sign + that perform a certain operation, and variables will be discussed later on in this section.
Statements and comments
In general, when you look at Java code, it'll be lines of code ending with semicolon ';'. Every line of code until the semicolon is usually called a statement, and a semicolon in Java indicates the end of the statement. Theoretically, you can put as much empty spaces as you want between the "words" of a statement, and so the semicolon serves to tell the Java interpreter that the statement has come to an end.
Comments are words in code that are not part of the code. You indicate comments in Java by starting with //. Everything after // on a line of code will be skipped by the Java interpreter.
We said earlier that expressions represent data and procedures. But what exactly do data and procedures mean? Here we will first talk about data. Data is basically the "stuff" we manipulate or work with in a computer program. For example, numbers are a form of data. There are many types of data, and in many programming languages, we classify data into different groups called data types. In Java, there are 8 primitive data types that are included in the language. Later on we'll learn how to create our own data types.
The first four data types are used to store numbers. More specifically, the numbers they store must be integers, which means numbers with no decimal values. For example, the number 1043 is an integer and so is 0 and -23, but 2.3 is not an integer.
Why, then, do we need four different data types for integers? That's because the four different data types have different ranges, or how big they can be. The greater the range of the data they can store, the more memory is consumed by the program. Therefore, usually it is a good programming habit to predict the range of the values of a program and use the appropriate data types to minimize the amount of memory consumed. Here is a table indicating the integer data types with their respective ranges and memory consumption.
Table: Integer Data types
* When using the data type
Similarly, there are two data types to represent "floating-point numbers," or numbers with decimals. They are:
Table: Floating-point Data Types
When you have a floating-point
number, by default Java takes it as a double. Therefore, if you want to use
the float data type, you must explicitly write
The seventh primitive data
Table: Java Escape Sequences For Special Characters
The last primitive data
type in Java is called
The most basic form of data abstraction is creating variables. When we create a variable, we are basically telling the computer to allot a space in memory to hold data later on. The value of the data can change, hence the term variable. Java is what is called a type explicit programming language, so all variables you use must first be declared with its data type early on. You must also indicate the variable name or identifier by which you will reference the allocated space in memory later. The syntax ("grammar" of a programming language) of variable declaration in Java is the following:
The optional "modifiers" will be explained later when we talk about object-oriented programming.
For example, if we wanted to make a variable indicating the age of a person, we could do the following:
Note that the semicolon at the end is required since this is a complete Java statement.
We chose the
This sets the initial value of age to zero. Java will not allow you to use a variable before you give it an initial value. Therefore, many people like to put the declaration and initialization together in one statement.
Another example can be:
Afterwards, if you want to access the variable, you just type in its identifier and you can use it freely like a literal. If you want to modify the variable's value, you can just use the assignment operator (equal sign).
Special Assignment Operators
In addition, there are various "shortcut" assignment operators that you can use in Java. There are the +=, -=, *=, and /= operators, which works in the following manner:
which is equivalent to saying:
There are also the increment
and decrement operators,
In actuality, you can even put the increment/decrement operator in front of the variable, which will have a slightly different meaning. Either way, the variable will still be modified, but the difference can be seen when you use it to further assign another variable's value. For example:
B. Arrays and Strings
Arrays are an extension to variables and its usefulness will be seen later on. But it basically allows you to have a group of variables of the same data type with the same identifier. How, then, do you differentiate between the different variables? Well, that's where the index or key come into play. The index is a number used to reference a particular variable in an array. In Java and many other languages, an index value of 0 indicates the first variable in the array and an index value of 1 indicates the second variable, and so on. An array is declared in the following manner:
The complex notation is due to the fact that Java arrays are what are called "objects," which we'll discuss further in the Object-Oriented Programming section.
For example we can do this:
This creates an array with
10 slots, thus able to fit 10 variables of type
To find out the length of
a string, just use
As you can see, initializing all slots of an array would become difficult when the array size is large. But we can actually automate the process using what are called "loops," which we'll discuss later.
Multi-dimensional arrays, or arrays of arrays, can be implemented in a straightforward manner. For example, if you want a 2D 5-by-5 array, you would write:
Then, to work with the array,
you just do the same as before, except now there are two indices (plural of
index) you have to indicate. For example,
You don't always have to specify the length of the arrays of your array. For example you can have an array of integer arrays of length 5 and length 7. To implement this, you just specify the first number when creating your array. Then you create each member array of the array one by one.
There is a special data
type in Java called
Note that the text in a
string is enclosed with double quotes (") while a
You can put two strings together by using the concatenation operator, which in Java is just the add sign (+).
Just like for arrays, to
find out the length of your string, you can use
Sometimes you might want
to access a particular character in your string. For arrays, you could just
put int the index with brackets , but you can't do this for strings. Instead
you have to use,
To compare and see if two
strings are equal, you can NOT use the == operator. This is due to the way strings
are really implemented in Java. In Java, the string variable doesn't really
hold the characters, it refers to some other place in memory that contains the
characters. Therefore, if you try to test two strings for equality using ==,
you're testing if they refer to the same place in memory, which is frequently
not the case even if the two strings represent the same characters. What you
should use instead is Java's
You can also create arrays of strings in a similar fashion to arrays of integers and other primitive types.
C. Basic I/O (Input/Output)
Text Output in Java
One of the most first things people learn in a new programming language is how to output text to the screen and read characters from the keyboard. The output part is fairly simple in Java. To print something on the screen and a newline afterwards (so that when you output again, it will start on a new line), you simply type in:
Be sure to enclose your text with double quotes "" as they are necessary. Later, when we talk about object-oriented programming, you'll understand the System.out.println part, but for now, just remember the syntax, and be sure to have the capitalization exactly the way it's printed or else it won't work. Note that for some "special" characters, like the ", you can't just type that in your code. Instead, to avoid confusion with other parts of code, you have to type in its Unicode value \u0022 or its escape sequence \".
If you ever want to print out the value of a variable, just attach it outside of the double quotes with a plus sign +, like this:
Be sure not to enclose the variable with double quotes. Doing that will print the variable name "myint" not its value.
If you don't want the newline symbol automatically attached, you can use:
Basic Number Formatting (Optional Section)
Sometimes the number doesn't look good when you print it. It might have too many decimals or something. To format numbers in Java requires the use of classes, which we will discuss in more detail when we talk about Object-Oriented Programming, but for now, just follow these basic principles.
First, if you ever want
to format text you have to put in the line
Now you can set the number of maximum and minimum integer and fraction (decimal) digits you want to display by typing in:
This will set the minimum number of integer digits displayed to 2 and the maximum fractional (decimal) digits displayed to 4. Thus, if your number were 3.333333..., it would be displayed as 03.3333 You can do similar things for maximum integer digits and minimum fraction digits as well.
Actually though, there is
one last step before the outputting. You would use your normal
And that's basaically all there is to simple number formatting.
Input in Java
Basic input from the keyboard in Java is a little more complicated and requires more understanding of classes and object-oriented programming. Therefore, we will not discuss it right now. Now, onto control flow.
D. Control Flow
Up until now we have discussed different types of variables and how to assign values to them. Assigning and modifying values is a main part of programming, but not all of it. If all we had were assignment statements, we would get nearly nowhere. We need more types of statements that allow us to automate processes and control how our program run. These types of statements are called control flow structures. There are primarily two categories of control flow structures in Java, conditional and iterative (loops). Conditional structures are statements that allows the program to run differently depending on the results of tests you put in. Iterative structures, more commonly known as loops, allow you to run statements in a repeated fashion without having to type out the code every time. The name loop is given because of the circular and repeating nature of iterative structures.
Perhaps most basic conditional
structure is the
The "boolean expression" means you must put in something that either returns the boolean values true or false. In basic cases, this would be what is called a comparison statement, which compares two things using special comparison operators. For numbers (integers and floats), you have the following operators:
Table: Comparison Operators for Numbers
So, if we want to test whether the value of a variable we have is greater than 2, we can do the following:
To combine multiple tests in one expression, you can use the "boolean operators." They are && (called AND), || (called OR), and ! (called NOT). If you connect two boolean expressions into one with the AND operator, the new expression will only return true if both original expressions are true. Similarly, the OR operator will return true only if either one or both of the expressions are true. The NOT operator negates the original value of the expression; hence, if it's originally true, the NOT will change the overall expression to false and if it's orignally false, NOT will change it to true.
For example, take a look at the following tests:
The switch statement can possibly be considered a more complex conditional structure. In it, you compare a single variable's value to a number of test values and do things accordingly if there is a match. The syntax is:
The syntax is more or less
self-explanatory, but you have to be extra careful of the
For example, try executing
the following the program, setting
As said before, loops allow
repeated statements to be automated. In Java, there are primarly 3 different
loop structures. The first is the
The first part of the
This program has the integer
Another loop statement in
Java is the
The following is an example
Note the initialization
has to be done outside of the loop. Otherwise,
The last loop control flow
structure in Java is the
The only difference between
the two is that for the
We've said before that to avoid lots of repetitive code, we can use a loop to initialize an array. An example of how may be done is the following:
Jumping Out of Loops
Sometimes you want your
program to quit a loop before it finishes all its cycles. For example, say you
have a loop that searches through large array for a certain number. Once you've
found it, you don't want the program to continue running the loop to the array's
end because that would just take up unnecessary processing time. Thus, in Java
there is a way to quit a loop. Remember the
Doing this makes the loop
But what if you have a nested
loop, or a loop inside of another loop? How do you break out of the whole nested
structure from the inner loop? In this case, you can also you
Here's an example. The loop would generate a 10-by-10 multiplication table, but now it will stop when it reaches 5 times 5.
E. A Working Java Program
Now that we've got the basics down, the question we face is: how do we put them together into a Java program that compiles and runs? We can't simply put down our variable declarations and code, can we? In fact, we always have to put in some more or less generic code in our program for it to run properly. Instead of explaining it, we will just give a working example and then discuss the parts.
So what does this all mean?
The first line
The next statement,
To begin with, we declared
our variables. Then, we initialized the array with a
Lastly, to end our program, we put in all the corresponding close braces (keep in mind that the number of open braces have to equal the number of close braces).
For simple programs, just write all code inside the "main" part. But as we'll discover in the next section, we can put code outside of "main."
F. Programming With Methods
Now we will learn about
splitting up programs into sizeable parts. First we will tell a little history.
In the early days of computer programs, the pioneer programmers would just write
out all code in one big blob with what are called "gotos" to point
from one line of code to another. Because of the unstructured and clumsy nature
of programming this way, that kind of code has since been named "spaghetti
code." To make programming more structured, people came up with what is
called "procedural programming." The fundamental idea behind procedural
programming is that we can split a big program into small parts, called procedures,
which are neatly arranged and named for easy reference later. So, say we have
some account balance program. We might split the program up into different procedures
for depositing, withdrawal, etc. The advantage to procedural programming is
that we can eliminate some of the former clumsiness. Furthermore, different
people can work on different procedures or modules and then at the end combine
all into the complete program. But perhaps most importantly, with procedural
programming, if we want to modify our program later on, we can just take out
the procedure that needs change and work only with that and not touch the other
good code. Most programming languages of today support some form of procedural
So why should we still learn procedural programming, you ask? The reason is that procedural programming is actually part of the groundwork and a subset of OOP and is also very useful. However, one thing you have to keep in mind is that because Java is a completely OOP language, even as we program "procedures" we actually have to mask them with OOP code and terminology.
You will probably hear people use different names for procedures, depending on their programming background, ranging from "procedures" to "functions" to "methods" to "modules."
However, they are not precisely the same, according to the common computer terminology. Procedures are code that do something but do not return any data. Functions are like procedures but return data, usually the result of whatever function it performs. A method is the OOP (hence Java) term for both procedures and functions. Lastly, the word module is a relatively informal term that refers to procedures and functions or sometimes, a file containing many procedures and functions.
To stick with correct Java terminology, from now on we will use the word method to refer to this kind of code.
So How Do You Do It?
Remember the sacred "main" thing we mentioned earlier, where all the code is put inside? Well, it turns out, when you write a method, you DON'T put it inside of "main"! In fact, "main" itself is just another method, albeit a special one. Therefore, it shouldn't surprise you that methods we create will look a lot like "main." The exact syntax is:
For the optional modifiers,
can be a literal but more likely a variable or expression. If your method does
not return anything, then put the word
Some methods have what are called "arguments" or "parameters" (there is a slight difference between the terms though). That means they require some data to be passed to them when you "call" or use the method. For example, say you have a method that calculates the price of something after tax. Then, you might want the method to require the base price and tax rate as parameters so that people with different items and tax rates can all use the method.
With that said, let's write the AfterTax method.
Then, to use the method,
you call it from, usually, another method, like
To sum up, here is an example
of a complete program called Prices that contains and calls the
Arrays as Arguments
What if we want to pass a whole array as an argument? How can we implement that? Actually, it's very simple. All you have to do is when you write in the parameters of your method, put in the data type of your array with brackets  following it to indicate that an array is to be passed to this method. For example, say you want to have a method that'll print out the elements of any integer array. You would write something like this:
When you call the array, you will just call it using the array name (without the brackets).
By Value or By Reference?
Try running the following code.
If you ran the code, you
would see that
Although this is frequently
the case, things aren't always passed by value in Java. If an argument of a
method is an object (e.g. an array), which we will talk more about later, a
reference or pointer to spot of the object in memory is passed. Therefore,
when the object is modified in the method, the original object will also be
modified since it uses the reference to look up where the original object is
in memory and changes it. The following illustrates this behavior, known as
by-reference passing. In this particular example, we have an integer
This ends our discussion of methods. Next up is recursion.
The obvious way to use procedures or, rather, methods is to call the written method from another method in your program. But can a method call itself? At first, this might seem like an illogical thing to do, but with proper usage we can actually implement useful routines using the art of recursion.
The term recursion refers to an algorithm or process that has a method calling itself.
The classic recursion algorithm is the "factorials" algorithm. A factorial of a number (denoted by n! where n is the number) is the product of all integers from 1 to that number. Thus 3! = 3*2*1 = 6. 0! is by definition 1.
Without recursion, we can quite easily implement a factorials method using a loop, and it would look something like this:
Using recursion, we have to take into account the fact that the factorial of a number is just the number times the factorial of the number 1 smaller than it, and the factorial of the number 1 smaller than it is just that smaller number times the factorial of the number 2 smaller than the original number and so forth. Expressed mathematically, n! = n * (n-1)! = n * (n-1) * (n-2)!. Using this method of thought, our recursion factorial method would do the following given the number it's calculating the factorial of:
What is the benefit of recursion? Some people think speed, but actually, in general, a recursive algorithm takes more processing time and memory than its iterative counterpart, if one is possible. The key benefit to recursion then is its simplicity. Although in the factorial example, it is hard to see the recursive code being any simpler than the iterative, when we try to program more complex tasks, it is not always easy or even possible to use an iterative algorithm. Recursive algorithms are generally very straightforward in thought, and this is its advantage.
The topic of scope is often discussed when learning a programming language. What is scope? Scope refers to the study of how and where data can be accessed.
For the most part, the basic
fact to know now is that you cannot have one method access the variables of
another variable at the same level of a hierarchy. For example, if your class
only has two methods,
And that's it for our discussion of the Fundamentals of Programming in Java. Now let's head on to Object-Oriented Programming.