2.1 SIMPLE PROGRAMS: SUMMING AN ARRAY OF INTEGERS


2.1 SIMPLE PROGRAMS: SUMMING AN ARRAY OF INTEGERS

Let's say you want to add 10 integers that are stored in an array. A C program for doing this would look like

 
/* AddArray1.c */ #include <stdio.h> int addArray (int [], int); main() { int data[] = {4,3,2,1,0,5,6,7,8,9}; /* (A) */ int size = sizeof (data) /sizeof (data [0]); /* (B) */ printf("sum is %d/n", addArray( data, size )); /* (C) */ return 0; } int addArray( int a[] , int n ) { /* (D) */ int sum = 0; int i; for(i=0; i<n; i++ ) sum += a[i] ; /* (E) */ return sum; }

Line (A) of main declares an integer array data and initializes it as shown. Line (B) figures out the size of the array. The function addArray is called in line (C) to sum up all the integers in the array.

If there is anything noteworthy about this program at all, it lies in the fact that an array name in C (and also in C++) is treated like a pointer in some contexts. Whereas data is an array name when supplied as an argument to the operator sizeof in line (B), it is a pointer to the first element of the array when supplied as an argument to the function addArray in line (C).

Contrast this with the fact that the array name a in the called function addArray in line (D) is merely a pointer, in the sense that sizeof(a) computed anywhere inside the function addArray will return 4 for the four bytes it takes to store a memory address on many modern machines. On the other hand, sizeof ( data ) in line (B) will return 40 for the 40 bytes that it takes to store the 10 integers of the array data, assuming that your machine allocates 4 bytes for an int.[1]

So when main calls addArray in line (C), the memory address that is the value of data when treated as a pointer is assigned to the parameter a in line (D) and that the array itself is not copied. Subsequently, the function addArray visits each element of the array in line (E) through the memory address assigned to a and adds the element to the sum.

A more explicitly pointer version of the addArray function is shown in the following program that does the same thing:

 
/* AddArray2.c */ #include <stdio.h> int addArray( int*, int ); main() { int data[] = {4,3,2,1,0,5,6,7,8,9}; int size = sizeof(data)/sizeof(data[0]); printf("Pointer Version: sum is %d\n", addArray( data, size )); return 0; } int addArray( int* a, int n ) { int sum = 0; int i; for(i=0; i<n; i++ ) sum += *a++; return sum; }

The two programs shown above are essentially identical because, as mentioned already, declaring a function parameter to be an array (the first program) is the same as declaring it to be a pointer (the second program).

Now let's consider a C++ program for doing the same thing:

 
//AddArray.cc #include <iostream> //(A) using namespace std; //(B) int addArray( int*, int ); int main() { int data[] = {4,3,2,1,0,5,6,7,8,9}; int size = sizeof(data)/sizeof(data[0]); cout << "C++ version: sum is " //(C) << addArray( data, size ) << endl; } return 0; } int addArray( int* a, int n) { int sum = 0; int i; for(i=0; i<n; i++ ) sum += *a++; return sum; }

This program shows this book's first use of an "object" in C++. The object is cout in line (C). This is an output stream object whose name is usually pronounced "c-out" as an abbreviation for "console out." This object knows how to send information to the standard output stream, which would generally be directed to the window of the terminal screen in which you are running your program. All objects in OO programming belong to some object class. The output stream object cout belongs to the class basic_ostream that is defined in the library header file iostream included in the program in line (A).

The header iostream is one of the many header files that constitute the C++ Standard Library.[2] This library is a culmination of the effort of the International Standards Organization (ISO) and the American National Standards Institute (ANSI) for the standardization of the C++ language. A significant portion of the C++ Standard Library includes what is informally referred to as the Standard Template Library (STL). STL consists of container classes for holding collections of objects and classes that play supporting roles for using the container classes. The Standard Library also includes the header file string that we will be using very frequently in this book for representing and processing C++ strings. Other header files in the C++ Standard Library contain classes for memory management (new and memory); representing exceptions (exception and stdexcept); representing complex numbers (complex); run-time type identification (typinfo;) and so on.

Although this point will become clearer after we have presented the idea of a namespace in Chapter 3, the directive

    using namespace std; 

in line (B) of the program takes account of the fact that all the identifiers (meaning the names of classes, functions, objects, etc.) used in the C++ Standard Library are defined within a special namespace known as the standard namespace and designated std. If we did not invoke this directive, we would need to call the output stream object by using the syntax std:: cout.

The symbol ‘<<’ in line (C) is called the output operator or the insertion operator. This operator, defined originally as the left bitwise shift operator, has been overloaded in C++ for inserting data into output stream objects when used in the manner shown here.[3] The ‘<<’ operator does formatted insertions into an output stream object. What that means is that if the operator is asked to insert an int into an output stream object, it will translate the four bytes of the int into its printable character representation and then insert the character bytes into the output stream object.

You can comment code in C++ the way you do it in C, that's by using the delimiters /* . */. You can also comment individual lines, or the trailing part of a line, by //. The compiler will not see on that line any characters past //.

Note that, as indicated by the commented out statement at the beginning of the program, Unix-like platforms require the name of a file containing the C++ source code to end in the suffix .cc. One can also use the suffix .C or the suffix .cpp. To compile this program, you'd say

    g++ filename 

The compiler will deposit an executable file called a. out or a.exe in your directory. This assumes that you are using the GNU C++ compiler. This compiler comes prepackaged with Unix and Linux distributions, although, if needed, you could download the latest version from the Free Software Foundation (http://www.gnu.org). If you are using a PC and you do not have access to a pre-loaded C++ compiler, you can download the GNU compiler (and other very useful Unix-emulation utilities for Windows) from the site http://sourceware.cygnus.com/cygwin/. For Solaris platforms, you should also be able to use the CC compiler via the invocation

    CC filename 

where, again, the name of the file must end in either ’.C’ or ’.cc’ or ’.cpp’. As with g++, the compiler will deposit an executable file called a.out or a.exe in your directory.

For another point of difference—a difference regarding style—between the C programs we showed at the beginning of this section and the C++ program above is in the header of main. The main in both C and C++ programs returns a status code, which is 0 if the program terminates normally and a nonzero integer to indicate abnormal termination. By tradition, the return type of main in C programs is left unmentioned—it being int by default. On the other hand, C++ requires a program to explicitly mention the return type int of main.

Now let's see how one would write a Java program for doing the same thing:

 
//AddArray.java public class AddArray { //(A) public static void main( String[] args ) //(B) { int[] data = { 0, 1, 2, 3, 4, 5, 9, 8, 7, 6 }; //(C) System.out.println( "The sum is: " //(D) + addArray(data) ); } public static int addArray( int[] a ) { //(E) int sum = 0; for ( int i=0; i < a.length; i++ ) sum += a[i]; return sum; } }

As shown in the commented out line at the beginning of the program, this source code resides in a file called

    AddArray.java 

The program begins with a class declaration:

     public class AddArray {        ....        .... 

In Java, functions can exist only inside classes. So even though using a class for the simple task for which we are writing the program seems rather excessive, there is no choice.

Note that the name of the file before the suffix java is the same as the class name, AddArray. Ordinarily, this is necessary only if a class is declared to be public. A file containing Java classes is allowed to have no more than one public class. If no classes in a file are public, the file can be given any name, but, of course, it must end in the suffix .java. To compile this file, you invoke the Java compiler by

    javac AddArray.java 

The compiler outputs what's known as the bytecode for the class and, in this case, deposits it in a file called

    AddArray.class 

This bytecode is machine-independent, unlike the executables for C or C++ programs, and can be run by another program called the Java Virtual Machine (JVM). A JVM will execute the program either in the interpreted mode or by first converting the bytecode into a machine-dependent executable using a second round of what is known as just-in-time (JIT) compilation and then executing the binaries thus obtained. The latter is the default mode and results in a tenfold increase in execution speed over the interpreted mode. For the bytecode file named AddArray. class, a Java Virtual Machine is invoked by

    java AddArray 

Before you can compile and run a Java program, you may have to tell the system how to find the classes you created with your program. The default is your current directory. But if you wanted to compile a class that was stored in some other directory, you have to tell both javac and java tools how to locate the class. The preferred way to do this is by using the -classpath option when invoking the javac compiler or the java application launcher. The -classpath option is also needed even if you are trying to compile a Java program in the directory in which it resides if your program uses other Java classes, your own or written by a third party, that reside in other directories.[4]

Suppose your program uses third-party classes that are stored in directories directory_1 and directory_2,[5] you'd want to invoke javac and java with the following syntax on Unix and Linux platforms:

    javac  -classpath .:directory_1:directory_2 sourceCode.java    java   -classpath .:directory_1:directory_2 className 

and on Windows platforms by[6]

    javac  -classpath .;directory_1; directory_2 source.java    java   -classpath .;directory_1; directory_2 className 

where the symbol ’.’ is used to designate the current directory where presumably the main application resides. Note that the delimiter between the directories for Unix and Linux platforms is the character ’:’ and for the Windows platform the character ’;’. The third-party classes, or, for that matter, even your previously programmed classes may come packaged in the form of an archive called the JAR archive.[7] If that's the case, you'd need to specify the pathname to such archives in your classpath specification, as for example in

    javac -classpath .:/path_to_archive/archive.jar your_program.java    java -classpath .:/path_to_archive/archive.jar your_class_name 

If the classpath strings become too long, you can create shell files containing the above invocations on Unix and Linux platforms. On Windows platforms, the same is accomplished by using batch files. On Unix and Linux platforms, it is also possible to set up aliases for the compiler and the application launcher that include the classpath string.

On Unix and Linux platforms and on some of the older Windows platforms, instead of using the classpath option as shown above, it is also possible to set the CLASSPATH environment variable. For example, if you are using either the csh or the tcsh shells, you can define a classpath by, say, including the following in a .cshrc file,

    setenv CLASSPATH .:directory_1:directory_2:.... 

which would create the same classpath setting as our earlier examples. If, on the other hand, you are using either sh, ksh, or bash, you can achieve the same effect by including the following strings in your .profile file:

    CLASSPATH=.:directory_1:directory_2:....    export CLASSPATH 

If desired, you can "unset" the value of the environmental variable by invoking unsetenv CLASSPATH in csh and tcsh and by invoking unset CLASSPATH in sh and ksh.

Even if you use the CLASSPATH environment variable, you may still have to use the -classpath option as shown previously to customize the classpath for a particular application. The classpath as set by the -classpath option overrides the classpath as set by the environmental variable. Note again the importance of including the character ’.’ in the CLASSPATH environment variable since, as was the case with the -classpath option, setting the environment variable overrides the default.

Getting to the program itself, the code that is inside the class definition is very much like the C or the C++ code we showed earlier. We have the function main() in line (B) and the method[8] addArray() inside the class definition in line (E). In Java, any class can include main(). When a class includes main(), the class becomes executable as an application. Since main() does not return anything in Java, its return type is declared as void. The significance of the labels public and static in the header for main will be explained in Chapter 3. In the body of main, we declare the identifier data as an array of ints and initialize it at the same time, very much like we did for C and C++.

The invocation System.out.println( ) in line (D) is a call to the println() method that is defined for the output stream object out. More precisely, out is a field of type OutputStream defined in the class System. System is a class that comes with the java. lang package.[9] This package is loaded in automatically by the Java compiler. println() is a method defined for the class OutputStream. One could also use the method print() via the invocation System. out.print( ) if it is not necessary to display the output in a separate line of text. The println and the print methods are as defined for the PrintStream class. The argument to these methods must either be a string or a type that Java would know how to convert into a string for display. In our example, the second part of the argument, of type int, gets converted into a string automatically.

The rest of the program consists of the method addArray() in line (E), which is very much like the C++ function of the same name in the earlier program, except for the manner in which the size of the array is determined inside the function. For both C and C++, the size of the array had to be passed explicitly to the function. But in Java, that is not necessary. Arrays in Java are objects that have data members[10] associated with them. The data member that is associated with an array object is length. When we access this data member through the call data.length, we can determine the length of the array data.

Also note from the above examples that C++ and Java have exactly the same way of commenting code. You can either use the C-style comment delimiters /* . */ or //. However, the latter can only be used for comments on a single line, because the compiler will not see any characters past //.

With regard to comments in Java programs, a special tool called javadoc can automatically generate documentation for your program using text that is delimited by /** and */. This tool generates HTML files that can be viewed with a browser.

[1]It is important to bear in mind that while an array name can "decay" into a pointer, it is not a pointer. The extent to which an array name decays into a pointer depends, among other things, on whether an array name is the name of a parameter of a callable function. So, whereas the array name data in main will act like a pointer in some contexts only, the array name a in the function addArray of the program AddArray1. c will act like a pointer in practically all contexts.

[2]The C++ Standard Library consists of these header files: algorithm, bitset, complex, deque, exception, fstream, functional, iomanip, ios, iosfwd, iostream, istream, iterator, limits, list, locale, map, memory, new, numeric, ostream, queue, set, sstream, stack, stdexcept, streambuf, string, typeinfo, utility, valarray, vector. Of these, the following are informally referred to as the Standard Template Library (STL): algorithm, bitset, deque, functional, iterator, list, map, queue, set, stack, valarray and vector.

[3]Operator overloading, discussed in detail in Chapter 12, allows the same operator to be used in different ways. The operands determine as to which meaning of such an operator applies in a given context.

[4]You do not need to specify the classpath for the classes that come with the Java platform. Both the compiler and the application launcher can locate those automatically.

[5]By directory name here is meant the pathname to the directory.

[6]If you are using a Cygnus emulation of Unix on Windows, you may need to place the classpath string between double quotes.

[7]A JAR file in Java is an archive file, just like a Unix tar (tape archive) file. Jar files are created and manipulated by using the Java jar tool. To create a JAR archive of all your classes, including the sources, in your current directory, you'd say

    jar cvf archiveName.jar *.class *.java 

To list the contents of a JAR file, you'd say

    jar tvf archiveName.jar 

and to unpack a jar archive, you'd say

    jar xvf archiveName.jar 

If you don't want to unpack the entire archive, but would like to extract a single class, you'd say

    jar xf archiveName.jar className.java 

or

    jar xf archiveName.jar className.class 

as the case may be.

[8]All Java functions (and some C++ functions) are known as methods. The distinction between method and function in OO programming is explained in Chapter 9.

[9]The notion of a package in Java is explained in the next chapter.

[10]The concept of a data member of a class type object is introduced in Section 3.1.




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net