Please send questions to st10@humboldt.edu .

CIS 130 - Week 9, Wednesday

*   a program doesn't HAVE to get all of its information
    via its parameters;
    and it doesn't have to have all of its effects
    via its return statement;

    ...it might also interactively input information
       while it is running;
       and it might interactively output information
       (for example, it might write to the screen)

    ...it could also read from or write to files,
       read from or write to devices, etc.

*   C++ provides a number of libraries of tools
    for input/output;

    we're going to discuss C++'s most common
    means for interactive input/output,
    using its iostream library

    (one of the C++ standard libraries)

*   you can USE functions, constants, objects, etc.
    from a C++ standard library by
    putting #include, a PRECOMPILER DIRECTIVE,
    at the beginning of your C++ source code (.cpp)
    file --
    surrounding the name of library with angle brackets,
    and follow all your #include's with:
    
using namespace std;

#include <iostream>
using namespace std;

    *   three #include notes: first, what do we mean by a precompiler
        directive? We means something the compiler takes care of or
	does BEFORE the actual translation of your program begins;

        *   #include, then, does just that -- literally includes something
	    into your code before it is translated/compiled;

    *   second, you #include standard libraries to get the headers
        and declarations you need to be able to use the things
	in those libraries in your program --

	...when you call a function you have written, you need to
	#include its header file, also --

	...but when it's a file YOU have written, you surround its
	.h file name with double quotes:

	#include "circ_area.h"

    *   third: so, have all of your #include's for library or
        libraries, and for functions your function is using,
	and don't forget to follow your set of #include's with:

	using namespace std;
        
*   iostream library provides tools for stream input/outout
    (stream: data as a stream of characters...)

    *   it provides two objects:

        cin - for keyboard input
        cout - for screen output (for standard output)

    *   these are NOT the same as using parameters,
        or returning a value --
	they enable us to have SIDE-EFFECTS in a program;

    *   cin reads from the keyboard and it "grabs" the value typed;
        cout writes something to the screen

*   for example:

double get_info;

/*  cout prints the value of each expression after a << into
    the screen "stream", if you will;
    endl means, print a newline in the stream */

cout << "What is the information?" << endl;

/* cin causes the program to stop and wait for the user
   to type something --
   when he/she types something, and then white space (blank, tab,
       newline), then cin tries to convert what was typed
       into the type of the variable after its >>,
       and then assigns that value to that variable */

cin >> get_info;

*   a first example:
    let's write a function get_word
    that expects nothing,
    but interactively asks the user to type in a word,
    and then it returns that word ended with three exclamation points

*   hey, how can you write the contract for that?
    C++ has a special term - void
    void means, no type!

    We'll use void as the "parameter" type when a function has
    NO parameters;
    AND, we'll use void as the return type when a function
    does not return anything

// contract: get_word: void -> string

/* purpose: expects nothing,
            but	interactively asks the user to type in a word,
            and	then it	returns that word ended with three exclamation points
*/

*   when a C++ function doesn't expect any parameters, you STILL
    have to put the empty parentheses after its name when you
    write its header, and when you call it;
    (you CAN write void inside those parentheses in the header if
    you wish...)

header:

string get_word()

examples:
get_word() == "howdy!!!"
get_word()

body:

*   with interactive input/output (and with mutation),
    we are now often going to have a SEQUENCE of actions
    we want to do, and the order of those MATTERS;

*   you should consider writing out (say in pseudo-english)
    the steps you want to take, in the order you want to
    take them, and get that straight, and THEN convert
    it to C++

    ...that's called writing PSEUDOCODE

1. declare a variable to hold the word
2. ask the user to type in a word
3. read in the word
4. return the word with 3 exclamation points at the end

*   top down design - when you start with high-level pseudocode
    steps, and then figure out pseudocode for steps that
    need it, and so on;
    (like outlining a paper, going from roman numeral main parts
    to the subparts A, B, C within a roman numeral,
    and the sub-subparts 1, 2, 3 within a letter subpart)

{
    string word;
    
    cout << "Please type in a word, and then return: " << endl;
    cin >> word;

    return word + "!!!";
}

*   you can have a function that doesn't return anything
    -- it just has side effects!
    (it may write something to the screen,
    write something to a file, show images or make sounds
    or move a robot arm...)

*   it's easy to write a function that just prints to the
    screen without returning something in C++ --
    BUT our tools don't work and play well with such
    functions...
    ...we'll need to know the "whole C++ program" picture;

*  note that the return type for a function that doesn't
   return anything is void
   ...and since it doesn't return anything,
      such a function call doesn't have a value;

      (just side effects!)
      
      ...you call it like a statement, then --
      by itself, with argument still in parentheses,
      followed by a semicolon

*   I'd like to write a function greeting that
    expects a name, and returns nothing, BUT it
    has the side effect of printing a cheery greeting
    to that name to the screen

// contract: greeting: string -> void

/* purpose:
    expects a name, and returns nothing, BUT it
    has the side effect of printing a cheery greeting
    to that name to the screen
*/

void greeting(string name)

examples:
    greeting("Sarah");
    should cause the following to be printed to the screen:
Hi, Sarah, how are you doing?

*   NOTE that any expression with a value can go in cout's
    output stream --
    the VALUE of that expression will be printed to the screen 

    (NOTE - don't put a void function call into a cout stream!!!)

{
    cout << "Hi, " << name 
         << ", how are you doing?" << endl;
}
    

*   BUT: the C++ tools on nrs-labs don't work-and-play well
    with void functions!
    *   they cout the result of calling your function, you
        see, and a void function call doesn't have a value,
	it just has a side-effect...
       
*   SO: NOW it's time to talk about "complete" C++ programs;   

*   every C++ *program* is made up of one or more functions,
    and exactly one of those functions has the name main

    *   here is a basic template for a C++ main function:
        (this will soon be available from the public course
	web page, as main_template.txt)

/*-----
 Contract: main: void -> int

 Purpose: <describe what this main does>
          OR testing program for function blah

 Examples: describe, in natural language, what the
           effect of running this program should be
 
 by:
 last modified:
-----*/

#include <iostream>
#include "x.h" /* put the header file for each function you
                  wrote that this main calls in double quotes
                  in a #include statement */
using namespace std;

int main()
{
    ...

    return EXIT_SUCCESS;
}

*   COURSE STYLE STANDARD: you are expected to return EXIT_SUCCESS,
    (a named constant you get access to by #include'ing the iostream
    library), in all of your main functions!
    *   (it is a constant, whose value varies between different
        operating systems, indicating successful completion of
	a program)

*   C++ tradition: you call your program the name of the
    file that its main function is in, 

    and you arrange for
    the resulting executable command running your program
    to have the name of the file your main function is in
    MINUS the suffix;

    ...a C++ program whose main function's source code is
    in a file looky_here.cpp would have its executable,
    ready-and-able-to-run version in a file named looky_here

*   how do you GET the ready-and-able-to-run version of your
    C++ program? You compile and link it using the g++ 
    Gnu C++ compiler;

*   how do you call the g++ Gnu C++ compiler?

    *   IF you want, you can use the compile_helper tool 
        (which you can copy over to your
        bin directory using:

cp ~st10/bin/compile_helper ~/bin

        ...to help you "build" the g++ call;

    *   or, follow these guidelines:

        To compile a C++ program whose main function is in looky_here.cpp
        and which makes use (overall) of the functions a, b, and c
	whose source code is in the files a.cpp, b.cpp, and c.cpp,
	you'd use the command:

	g++ -o looky_here looky_here.cpp a.cpp b.cpp c.cpp

        *   IMPORTANT NOTES!!!!!
            *   the part above:

	        -o looky_here

		is saying, "Put the executable, linked, ready-to-run
		result -- the output -- into a file named
		looky_here 

		DO NOT PUT YOUR .cpp file after the -o!! It will
		cheerfully NUKE (overwrite) your source code file
		if you do!!!

            *   Remember to include the .cpp files for EVERY function
	        involved in this program -- whether called by the
		main function or any of the functions called by
		the main function, etc.

            *   there are ways to just compile/translate one function
	        without linking it, and ways to build what is called
		a makefile to more easily compile a large program with
		many files -- that is, this is just the beginning.
		But it is enough to get us started...