Lab 1: C++ Overview & Comparison to Java

Complete the following lab by Wednesday, January 20, at 4:00. The parts marked *** are to be handed in. Some of these will be written answers to questions and others will be programs. Tar the files in your lab directory and send them to me ingram@roanoke.edu.

Getting Started: Create a directory for this lab. You can either download the example programs to your directory from the Web as you go through this (go to the course web page at http://cs.roanoke.edu/Spring2010/CPSC270A to get this web page) OR just copy them all to your directory using cp as follows (assuming you are in your directory for this lab):

      cp ~cpsc/public_html/Spring2010/CPSC270A/lab1/*.java .
      cp ~cpsc/public_html/Spring2010/CPSC270A/lab1/*.cc .
    

Basic Structure

Input/Output

C++ input and output is done using objects and operators in the C++ library. For standard I/O the functions are in the iostream library files. C++ also has a language mechanism for grouping declarations of identifiers. This mechanism is called a namespace. An identifier declared within a namespace can be directly accessed by statements within the namespace. Other statements must indicate what namespace is being used. Identifiers in the iostream library are declared in the std namespace. Basic I/O in a C++ program is done as follows:

Compiling and Linking

Compilation in C++ results in an executable file (unlike Java where the result is bytecode which must then be interpreted). The compile command is g++. There are options that can be included: Exercise: The file hello.cc contains good ole "Hello World!" in C++. Examine the program then compile it in the two stages and create an executable named hello. Run the program.

Data Types and Basic Syntax

  • C++ uses the same identifiers for basic data types: int, float, double, long, short.

  • The syntax of basic programming constructs such as assignment statements, expressions, if statements, switch statements, and loops (for, while, and do) is the same in C++ and Java. However ...

  • Booleans in C++ are very different! In C++ zero means false and any non-zero value means true. This can get you into trouble! Consider the following:
          if (n = 0)
            ...
    
    What would happen in Java if you had this in your program? How would it be interpreted in C++?

    Exercise: See if you were correct by examining the behavior of JavaIf.java and CPlusIf.cc.

    1. Examine the code for each - same program, different languages.
    2. Compile and run the Java program (javac JavaIf.java then java JavaIf). What happened? Why?
    3. *** Compile the C++ program. Run it. Try different input values (including 0) and see what it does. What is happening? Why is it happening? Describe what happens when the code is executed and why that gives the observed behavior.

    Type bool: Even though zero means false and any nonzero value means true in C++, most implementations of C++ have added type bool which includes identifiers true and false. This type should be used in programs rather than using integers. However be aware that true is actually stored as 1 and false is 0.

    The boolean operators in C++ are the same as in Java: &&, ||, !

    Constants in C++

    There are two ways to define constants in C++. As in Java, the convention is to use all caps for the constant identifiers.

    Arrays in C++

    The following declares list to be an array of 10 integers.
          const int MAX_SIZE = 10;
    
          int list[MAX_SIZE];
    
    This declaration allocates space for 10 ints. The space is allocated at compile-time and cannot be changed while the program is running. One consequence of this is that the following is not legal in standard C++:
    
         int size;
         cin >> size;
         int list[size];         // NOT LEGAL - size was not known at compile-time
    
    
    Later we will see a way to allocate space at run-time - dynamic rather than static allocation.

    C++ allows the programmer to be careless with array subscripts. For this (and other reasons) it is generally best to use the vector class (later!) than the built-in arrays. HOWEVER, there is a lot of code written with arrays so a computer science major should be familiar with them and their idiosyncracies (hazards!).

    Exercise: The programs JavaArrays.java and CPlusArrays.cc use arrays.

    1. Examine each program to see what it does.
    2. Compile and run JavaArrays.java. Try at least two different scenarios for input - in one have the number of elements to print be less than or equal to the number generated; in the other have the number of elements to print larger than the number generated.
    3. Compile and run CPlusArrays.cc. As above, try different combinations of input.
    4. Run the CPlusArrays.cc with 20 (or more) for the number of elements to fill and the same the number of elements to print. You may (you should but it doesn't always happen!) get a segmentation fault because the code only allocated 10 spaces for the array. If you didn't get a segmentation fault keep using larger numbers until you get one. A segmentation fault occurs in C++ when your program tries to access memory that has not been allocated to it.
    5. ***CPlusArrays2.cc is the same as the program above except it has 4 additional variables of type int declared (two before the array declaration and two after). These variables are assigned values in the program (look at the code to see what these are). Compile and run the program with 10 for the number of integers to generate and 20 the number to print. What do you notice? What is going on?

    Functions and Parameters

    Good programming dictates that we divide our program into logical tasks and use functions (or methods) to carry out each task. The syntax for a function definition in C++ is similar to that in Java in that there is a header and a body. The following is the header for a function that finds and returns the sum of the elements in an integer array a.
    
         int sum (int size, int a[])
    

    IMPORTANT FACTS ABOUT ARRAYS AS PARAMETERS:

    1. The formal parameter list for the function does NOT give the size of the array.
    2. Unlike Java, there is no way to determine the size of the array from the array itself (no a.size), so the size is typically a parameter to the function.
    3. The value of an array is a constant reference to the first element in the array. Just as in Java the parameters above are passed by value but since the value of the array parameter is a reference the function can change the actual values in the array. That is, a[3] = 17 would change the value of the fourth element in the array.

    In C++, unlike Java, the compiler must have encountered the header (signature) of a function before it encounters a call to that function. When the function is in the same file as the call there are two ways to handle the requirement.

    Final Exercises:

    1. ***Write a C++ program that implements the Euclidean algorithm given in the book (so use a loop not recursion). Add a counter to count the number of times the loop executes. Print the GCD and the number of times the loop executes (the number of divisions).
    2. ***Write a C++ program to implement the modified middle school algorithm (we did in class) for finding the GCD. You should implement the Sieve of Eratosthenes as a function. Instead of returning an array of primes that is allocated in the function (there are problems with this given what you know so far) that array should be a parameter. Use the following header for the sieve function:
          // Finds all primes less than or equal to n.
          // PRE:  n is a positive integer > 1
          // POST: prime is an array containing all primes less than or
          //       equal to n; numPrimes is the number of primes in the array
          void sieve (int n, int[] prime, int& numPrimes)
      
      We will discuss the & in the next lab - it means that numPrimes is passed by reference so the function can actually change it. The call to the function would just put your variable name with no &. An alternative would be to return the number of primes; however, many people frown upon a function that both changes some of its parameters (such as the array in this case) AND returns something.

      Note that you should declare a constant for the maximum size of n so you can allocate large enough arrays. Make the max at least 500. Your main function can check to make sure the input for n is valid.