Lesson 2 | Programming fundamentals using Java |
Objective | Understand the use of Java in the course. |
Java Programming Fundamentals
The programming language that you will be using in this course is Java.
Sun Microsystems (now Oracle) , the developer of the Java programming language, describes Java as a simple, object-oriented,
distributed, interpreted, robust, secure, architecture neutral, portable, high-performance, multithreaded, and dynamic language.
That is quite a collection of adjectives. They are all true, but in this course we will try to stick to the simple
part. In all honesty, you can learn the fundamentals of programming using any number of programming languages including Java, BASIC,
and C. The decision to use Java was based primarily on the free availability of Java development environments and the growing popularity of the language. Because this course is targeting first-time programmers, we will be emphasizing programming concepts that are common to most
high-level programming languages. More specifically, the course emphasis is on structured programming concepts.
Using an object-oriented programming language for a course on structured programming concepts may seem a bit unusual, but this
apparent inconsistency is due to the common misconception that object-oriented programming and structured programming are
mutually exclusive. On the contrary, the structured programming concepts we'll be covering with Java are essentially a small
subset of the concepts used in object-oriented programming with Java. The result of this approach is that by the end of the
course you will definitely be ready to dig deeper into Java, but you will also be well-prepared to learn other high-level
programming languages.
Structured Programming
To analyze data flow, compilers divide the source code into sequences known as basic blocks. A basic block is a sequence of sequential machine
instructions into and out of which there are no branches except at the beginning and end of the basic block. For example, consider the following C code:
x = 2; // Basic Block 1
j = 5;
i = f( &x, j );
j = i * 2 + j;
if( j lt; 10 ) // End of Basic Block 1
{
j = 0; // Basic Block 2
i = i + 10;
x = x + i; // End of Basic Block 2
}
else
{
temp = i; // Basic Block 3
i = j;
j = j + x;
x = temp; // End of Basic Block 3
}
x = x * 2; // Basic Block 4
++i;
--j;
This code snippet contains four basic blocks. Basic block 1 starts with the
beginning of the source code.
A basic block ends at the point where there is a jump into or out of the sequence of instructions.
- Basic block 1 ends at the
beginning of the if statement because the if can transfer control to either of two locations.
- The else clause terminates basic block 2. It also marks the beginning of basic block 3 because there is a jump (from the if’s then clause)
to the first statement following the else clause.
- Basic block 3 ends, not because the code transfers control somewhere else, but because there is a jump from
basic block 2 to the first statement that begins basic block 4 (from the if's then section).
- Basic block 4 ends with a call to the C printf function.
The easiest way to determine where the basic blocks begin and end is to consider the assembly code that the compiler will generate for that code.
Wherever there is a conditional branch/jump, unconditional jump, or call instruction, a basic block will end. Note, however, that the basic block includes
the instruction that transfers control to a new location. A new basic block begins immediately after the instruction that transfers control to a new location. Also, note that the target label of any conditional branch, unconditional jump, or call instruction begins a basic block.
The nice thing about basic blocks is that it is easy for the compiler to track what is happening to variables and other program objects in a basic
block. As the compiler processes each statement, it can (symbolically) track the values that a variable will hold based upon their initial values and the
computations on them within the basic block.
A problem occurs when the paths from two basic blocks join into a single code stream. For example, at the end of basic block 2 in the current example,
the compiler could easily determine that the variable j contains zero because code in the basic block assigns the value zero to j and then makes no other assignments to j. Similarly, at the end of basic block 3, the program knows that j contains the value j0+x (assuming j0 represents the initial value of j upon entry into the basic block). But when the paths merge at the beginning of basic block 4, the compiler probably can’t determine whether j will contain zero or the value j0+x. So, the compiler has to note that j’s value could be either of two different values at this point. While keeping track of two possible values that a variable might contain at a given point is easy for a decent optimizer, it’s not hard to imagine a situation where the compiler would have to keep track of many different possible values. In fact, if you have several if statements that the code executes in a sequential fashion, and each of the paths through these if statements modifies a given variable, then the number of possible values for each variable doubles with each if statement. In other words, the number of possibilities increases exponentially with the number of if statements in a code sequence. At some point, the compiler cannot keep track of all the possible values a variable might contain, so it has to stop keeping track of that information for the given variable. When this happens, there are fewer optimization possibilities that the compiler can consider.
In this module you will be performing tasks on your computer that you may have never done before, such as downloading and installing software and using a command prompt window. For some these tasks will go smoothly, and for others the road may get a bit bumpy. If at any time you run
into difficulty, conduct a search the search bar listed above.
In the next lesson you will create a directory to contain the programs you will be writing in the course.