<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\documentclass[onecolumn,letterpaper,11pt]{article}

%===================================================================
% Include common packages, environments, counters etc
\input{common_latex/common_latex_packages}
\input{common_latex/common_latex_lab_format}
\input{common_latex/common_latex_definitions}
%===================================================================

\begin{document}
\wikidoc{file=Lab.CPPFunctions}
\wikidoc{auth=mikerb@mit.edu}

%===================================================================
% Build the Cover Page in an environment style easy for wiki parsing
\begin{labcover}
\labtitle{C++ Lab 03 - C++ Functions}
\vspace{0.1in}
\labcourse{2.680 Unmanned Marine Vehicle Autonomy, Sensing and Communications}
\vspace{0.2in}
\labpng{0.775}{figures/tsl.png}
\vspace{0.3in}
\labdate{IAP 2024}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@mit.edu}
\labauth{Department of Mechanical Engineering}
\labauth{MIT, Cambridge MA 02139}
\vspace{0.2in}
\labtoc{small}
\end{labcover}

%======================================================================
% Add a blank page so first body page is on the right when doubleside
\blankpage

%======================================================================
% Begin the body of the text

%======================================================================
\section{Lab Three Overview and Objectives}
%======================================================================

This lab addresses 

\begin{labinfo}
\begin{packed_itemize}[2]
\item Simple C/C++ functions
\item Parameter Passing and Return Values
\item Default Parameters
\item Pass by Reference vs. Pass by Value
\item Forward Declared Functions and Functions in Separate Files
\end{packed_itemize}
\end{labinfo}

%=======================================================================
\section{Simple C/C++ Functions}
%=======================================================================

C and C++ handle functions in pretty much the same way. In C++ however, it is
more common to associate functions with classes/objects, which we haven't touched
yet. The core ideas of function declarations, return types and parameter passing
are the same in either case. Here are few good pages to get started:

\begin{packed_itemize}
\item \urlx{http://www.cplusplus.com/doc/tutorial/functions}: \newline
  Up to and including the section {\em The return value of main}.
\item \urlx{http://www.tutorialspoint.com/cplusplus/cpp_functions.htm}
\item \urlx{http://www.learncpp.com/cpp-tutorial/14-a-first-look-at-functions}
\end{packed_itemize}
\vspace{0.05in}

%=======================================================================
\refstepcounter{exercise}
\label{ex_hello}
\subsection{Exercise \ref{ex_hello}: The Simplest of Simple Functions}

Write a "Hello World!" program that simply invokes a function to do
the dirty work of outputting the message.  Call your file
\var{function\_hello.cpp} and build it to the executable
\var{function\_hello}.  When your program runs, it should be invocable
from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./function_hello
 Hello World!
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_hello}.  
%-------------------------------------------+



%=======================================================================
\refstepcounter{exercise}
\label{ex_hellocmd}
\subsection{Exercise \ref{ex_hellocmd}: A Function with Parameters and Return Value}

This exercise is similar to the first one in that we'll write a "Hello
World!" program that invokes a function to do the dirty work of
outputting the message. But this exercise, get your message from the
command line and pass it as a string to the function outputting the
message. Your function should also return a Boolean (type \var{bool})
indicating if the message was greater than 10 characters long or not.
The \var{main()} routine should use this result to comment on the
length of the message.

\pskip
\noindent
Call your file \var{function\_hellocmd.cpp} and build it to the
executable \var{function\_hellocmd}.  When your program runs, it
should be invocable from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./function_hellocmd 'Hello Again World!!!'
 Hello Again World!!!
 That was a long message.

 $ ./function_hellocmd 'Hey!'
 Hey!
 That was a short message.
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_hellocmd}.  
%-------------------------------------------+

\vspace{0.1in}
\noindent
{\bf Comments on Exercise 2:}

\begin{packed_itemize}[4]

\item Note that the two quote characters are needed around the message
  provided on the command line. Arguments passed on the command line
  are delimited by white space, so in order for \var{"Hello"} and
  \var{"World!"} to be considered one single argument, it must be
  surrounded by quotes, \var{'Hello World!!!'}.

\item The \var{'!'} character is also a special character to the
  command line shell. If you are running the \cmd{bash} shell, the single
  quote as above is enough to ensure the \var{'!'} character is treated
  literally. If you're using the \cmd{tcsh} or \cmd{csh} shells, you will
  need to take the further step of putting a back-slash in front as in:

\begin{consoleverb}
    $ ./function_hellocmd 'Hello Again World\!\!\!'
\end{consoleverb}
\end{packed_itemize}


%=======================================================================
\section{C++ Functions with Default Parameters}
%=======================================================================

In C++ there is the option to define a function with one or more
default parameters. For example you could invoke a function to post a
message with an optional prefix and suffix provided, and invoke in in
a few different ways:

\begin{fileverb}
  postMessage("Hello there!", "Good Evening", "Good bye");
  postMessage("Hello there!", "Good Evening");
  postMessage("Hello there!");
\end{fileverb}

\noindent
Default function parameters in C++ are described here:

\vspace{0.05in}
\begin{packed_itemize}
\item The section titled {\em Default values in parameters} in: \newline
  \urlx{http://www.cplusplus.com/doc/tutorial/functions}:
\item The section titled {\em Default Values for Parameters} in: \newline
  \urlx{http://www.tutorialspoint.com/cplusplus/cpp_functions.htm}
\end{packed_itemize}
\vspace{0.1in}

\noindent
In practice I've found that the main utility of default parameters is
that one can modify a previously written function implementation that
now takes a new parameter without worrying about breaking existing
code that invokes the original function without the new parameter.

%=======================================================================
\refstepcounter{exercise}
\label{ex_hellodef}
\subsection{Exercise \ref{ex_hellodef}: A Function with Default Parameters}

In this exercise, extend your previous program to have a message
handling function with a default message of \var{"Hello there. How are
  things?"}.


\pskip
\noindent
Call your file \var{function\_hellodef.cpp} and build it to the
executable \var{function\_hellodef}.  When your program runs, it
should be invocable from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./function_hellodef 
 Hello there. How are things?
 That was a long message.

 $ ./function_hellodef 'Hey!'
 Hey!
 That was a short message.
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_hellodef}.  
%-------------------------------------------+

%=======================================================================
\section{Pass by Reference vs. Pass By Value}
%=======================================================================

Parameters in C/C++ functions as described so far have passed a {\em
  copy} of the parameter to the function. You can modify the value of
that parameter within the function and it will have no bearing on the
local value of that variable in the code that invoked it. This is
called {\em pass by value}. An alternative is {\em pass by reference}
where modifications made on the variable within the function persist for
the local value of that variable in the code that invoked it. This is an 
important concept that transcends C/C++, so if it is new to you, please
read one or more of the tutorial pages links below and we'll do a couple
short exercises.

\vspace{0.05in}
\begin{packed_itemize}
\item The section titled {\em Arguments passed by value and by reference} in: \newline
  \urlx{http://www.cplusplus.com/doc/tutorial/functions}
\item Or the following few pages from \urlx{learncpp.com}: \newline
  \urlx{http://www.learncpp.com/cpp-tutorial/71-function-parameters-and-arguments} \newline
  \urlx{http://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value} \newline
  \urlx{http://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value}
\end{packed_itemize}
\vspace{0.1in}

%=======================================================================
\refstepcounter{exercise}
\label{ex_hellocap}
\subsection{Exercise \ref{ex_hellocap}: Using Pass By Reference to Have a Function Return Two Values}

Functions in both C and C++ return at most one value. While true that
the return value could be an object containing multiple values, often
a simple second return value is all that is desired, without the need
to define a new structure or class to hold two values. So a common use
of pass-by-reference parameters is to create a function that "returns"
a value by altering a provided parameter.

\pskip
\noindent
In this exercise, modify the previous version of your Hello World function
to not only return a Boolean indicating whether the message was longer
than ten characters, but also a Boolean indicating whether the message
began with a capital letter. 

\pskip
\noindent
Call your file \var{function\_hellocap.cpp} and build it
to the executable \var{function\_hellocap}.  When your program runs,
it should be invocable from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./function_hellocap 
 Hello there. How are things?
 That was a long message.
 The message was properly capitalized.

 $ ./function_hellocap 'hey!'
 hey!
 That was a short message.
 The message was not properly capitalized.
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_hellocap}.  
%-------------------------------------------+

\vspace{0.1in}
\noindent
{\bf Comments on Exercise \ref{ex_hellocap}:}

\begin{packed_itemize}[4]

\item Don't forget that if you have a function parameter with a
  default value, it must be the last parameter. If you have N
  parameters with default values, they have to be the last N
  parameters.

\item In this exercise (and solution provided), the check is made if
  the first character in the message is a capital letter. Can you
  improve on this to make sure that a message \var{" Hello"}, with
  leading white space, is reported as being capitalized?
\end{packed_itemize}


%=======================================================================
\section{Forward Declared Functions and Functions in Separate Files}
%=======================================================================

In all our examples so far in this lab, the function invoked by the
\var{main()} routine was defined prior to defining \var{main()}. If
the order were switched, the C++ compiler would give you an error
message. For example if you switched the order of \var{main()} and
\var{message()} in the solution to exercise 1 (try it), you would get
an error message along the lines of:

\vspace{0.1in}
\begin{consoleverb}
function_hello.cpp:14:3: error: use of undeclared identifier 'message'
  message();
  ^
1 error generated.
\end{consoleverb}
\vspace{0.1in}

\noindent
When the compiler gets to the invocation of the \var{message()}
function, it simply knows nothing about this method and cannot discern
this from a simple typo, so the compilation stops.  There is a way
around this by declaring the function prior to using it. Read about
this topic discussed here:

\vspace{0.05in}
\begin{packed_itemize}
\item The section titled {\em Declaring functions} in: \newline
  \urlx{http://www.cplusplus.com/doc/tutorial/functions}:
\end{packed_itemize}
\vspace{0.1in}


%=======================================================================
\refstepcounter{exercise}
\label{ex_sepdef}
\subsection{Exercise \ref{ex_sepdef}: Using a Forward-declared Function in a Separate File}

In this exercise, modify the solution to the previous
pass-by-reference exercise to move the function implementation into a
separate file, leaving only the \var{main()} function in its own file
with the function simply declared before the \var{main()} function.

\pskip
\noindent
Call your files \var{function\_sepdef.h}, \var{function\_sepdef.cpp}
and \var{function\_main.cpp} and build it to the executable
\var{function\_sepdef}. Note that both source code (\var{.cpp}) files
must now be provided on the command line:

\vspace{0.1in}
\begin{consoleverb}
 $ g++ -o function_sepdef function_sepdef.cpp function_main.cpp
\end{consoleverb}
\vspace{0.1in}

\noindent
As before, when your program runs, it should be invocable from the
command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./function_sepdef 
 Hello there. How are things?
 That was a long message.
 The message was properly capitalized.

 $ ./function_sepdef 'hey!'
 Hey!
 That was a short message.
 The message was not properly capitalized.
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_sepdef}.  
%-------------------------------------------+



%===================================================================
\newpage
\section{Solutions to Exercises}
%===================================================================

%===================================================================
\subsection{Solution to Exercise \ref{ex_hello}}
\label{sol_ex_hello}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  function_hello.cpp  (Third C++ Lab Exercise 1)               */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/function_hello.cpp       */
/*  BUILD: g++ -o function_hello function_hello.cpp                     */
/*  RUN:   ./function_hello                                             */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;

using namespace std;

void message()
{
  cout &lt;&lt; "Hello World!" &lt;&lt; endl;
}

int main()
{
  message();
  return(0);
}
\end{fileverb}

%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_hellocmd}}
\label{sol_ex_hellocmd}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  function_hellocmd.cpp  (Third C++ Lab Exercise 2)            */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/function_hellocmd.cpp    */
/*  BUILD: g++ -o function_hellocmd function_hellocmd.cpp               */
/*  RUN:   ./function_hellocmd 'Hello World!'                           */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;

using namespace std;

bool message(string msg)
{
  cout &lt;&lt; msg &lt;&lt; endl;

  if(msg.length() &gt; 10)
    return(true);
  return(false);
}

int main(int argc, char **argv)
{
  if(argc != 2) {
    cout &lt;&lt; "Usage: hellocmd MESSAGE" &lt;&lt; endl;
    return(1);
  }

  bool msg_is_long = message(argv[1]);
  if(msg_is_long)
    cout &lt;&lt; "That was a long message." &lt;&lt; endl;
  else
    cout &lt;&lt; "That was a short message." &lt;&lt; endl;

  return(0);
}
\end{fileverb}


%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_hellodef}}
\label{sol_ex_hellodef}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  function_hellodef.cpp  (Third C++ Lab Exercise 3)            */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/function_hellodef.cpp    */
/*  BUILD: g++ -o function_hellodef function_hellodef.cpp               */
/*  RUN:   ./function_hellodef 'Hello World!'                           */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;

using namespace std;

bool message(string msg="Hello there. How are things?")
{
  cout &lt;&lt; msg &lt;&lt; endl;

  if(msg.length() &gt; 10)
    return(true);
  return(false);
}

int main(int argc, char **argv)
{
  if(argc &gt; 2) {
    cout &lt;&lt; "Usage: hellodef MESSAGE" &lt;&lt; endl;
    return(1);
  }

  bool msg_is_long;
  if(argc == 2)
    msg_is_long = message(argv[1]);
  else
    msg_is_long = message();

  if(msg_is_long)
    cout &lt;&lt; "That was a long message." &lt;&lt; endl;
  else
    cout &lt;&lt; "That was a short message." &lt;&lt; endl;

  return(0);
}
\end{fileverb}


%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_hellocap}}
\label{sol_ex_hellocap}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  function_hellocap.cpp  (Third C++ Lab Exercise 4)            */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/function_hellocap.cpp    */
/*  BUILD: g++ -o function_hellocap function_hellocap.cpp               */
/*  RUN:   ./function_hellocap 'Hello World!'                           */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;
using namespace std;

bool message(bool&amp; capitalized, string msg="Hello there. How are things?")
{
  cout &lt;&lt; msg &lt;&lt; endl;

  bool long_msg	= false;
  if(msg.length() &gt; 10)
    long_msg = true;

  capitalized = false;
  // Recall that a character in a string is represented by an ASCII
  // integer. 'A' is 65 and 'Z' is 90.                       
  if((msg.length() &gt; 0) &amp;&amp; (msg[0] &gt;= 65) &amp;&amp; (msg[0] &lt;= 90))
    capitalized = true;

  return(long_msg);
}

int main(int argc, char **argv)
{
  if(argc &gt; 2) {
    cout &lt;&lt; "Usage: function_hellocap MESSAGE" &lt;&lt; endl;
    return(1);
  }

  bool capitalized;
  bool msg_is_long;
  if(argc == 2)
    msg_is_long = message(capitalized, argv[1]);
  else
    msg_is_long = message(capitalized);

  if(msg_is_long)
    cout &lt;&lt; "That was a long message." &lt;&lt; endl;
  else
    cout &lt;&lt; "That was a short message." &lt;&lt; endl;

  if(capitalized)
    cout &lt;&lt; "The message was properly capitalized." &lt;&lt; endl;
  else
    cout &lt;&lt; "The message was not properly capitalized." &lt;&lt; endl;

  return(0);
}
\end{fileverb}

\vspace{0.1in}
\noindent
{\bf Comments on the Solution to Exercise \ref{ex_hellocap}:}

\begin{packed_itemize}
\item When a Boolean expression is evaluated, C++ will only evaluate
  as much as it needs to. For example, in the below expression:

\vspace{0.1in}   
\begin{fileverb}
  if( (1 &gt; 2) &amp;&amp; (my_string == "pears"))
\end{fileverb}
\vspace{0.1in}   

\noindent
The string comparison will never be made since the first condition failed
and that is enough to know the whole conjunction will fail. Likewise in 

\vspace{0.1in}   
\begin{fileverb}
  if( (2 &gt; 1) || (my_string == "pears"))
\end{fileverb}
\vspace{0.1in}   

\noindent
the success of the first term ensures the entire disjunction is successful, 
so the string comparison is again not made. 

\vspace{0.1in}
\noindent
In our example, we can safely assume we will not be accessing the string at
an index out of bounds with expression \var{msg[0]} since the first term 
in that conjunction ensures we have a non-empty string before evaluating 
\var{msg[0]}.

\end{packed_itemize}

%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_sepdef}}
\label{sol_ex_sepdef}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  function_main.cpp  (Third C++ Lab Exercise 5)                */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/function_main.cpp        */
/*  BUILD: g++ -o function_sepdef function_sepdef.cpp function_main.cpp */
/*  RUN:   ./function_sepdef 'Hello World!'                             */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;
#include "function_sepdef.h"

using namespace std;

int main(int argc, char **argv)
{
  if(argc &gt; 2) {
    cout &lt;&lt; "Usage: function_sepdef MESSAGE" &lt;&lt; endl;
    return(1);
  }

  bool capitalized;
  bool msg_is_long;
  if(argc == 2)
    msg_is_long = message(capitalized, argv[1]);
  else
    msg_is_long = message(capitalized);

  if(msg_is_long)
    cout &lt;&lt; "That was a long message." &lt;&lt; endl;
  else
    cout &lt;&lt; "That was a short message." &lt;&lt; endl;

  if(capitalized)
    cout &lt;&lt; "The message was properly capitalized." &lt;&lt; endl;
  else
    cout &lt;&lt; "The message was not properly capitalized." &lt;&lt; endl;

  return(0);
}
\end{fileverb}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  function_sepdef.h    (Third C++ Lab Exercise 5)              */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/function_sepdef.cpp      */
/*  BUILD: g++ -o function_sepdef function_sepdef.cpp function_main.cpp */
/*  RUN:   ./function_sepdef 'Hello World!'                             */
/*----------------------------------------------------------------------*/

#ifndef SEPDEF_MESSAGE
#define SEPDEF_MESSAGE

#include &lt;string&gt;

bool message(bool&amp; capitalized, std::string msg="Hello there. How are things?");

#endif
\end{fileverb}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  function_sepdef.cpp  (Third C++ Lab Exercise 5)              */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/function_sepdef.cpp      */
/*  BUILD: g++ -o function_sepdef function_sepdef.cpp function_main.cpp */
/*  RUN:   ./function_sepdef 'Hello World!'                             */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;
#include "function_sepdef.h"

using namespace std;

bool message(bool&amp; capitalized, string msg)
{
  cout &lt;&lt; msg &lt;&lt; endl;

  bool long_msg = false;
  if(msg.length() &gt; 10)
    long_msg = true;

  capitalized = false;

  // Recall that a character in a string is represented by an ASCII 
  // integer. 'A' is 65 and 'Z' is 90.
  if((msg.length() &gt; 0) &amp;&amp; (msg[0] &gt;= 65) &amp;&amp; (msg[0] &lt;= 90))
    capitalized = true;

  return(long_msg);
}
\end{fileverb}

%---------------------------------------------------------
\vspace{0.15in}
\noindent
{\bf Comments on the Solution to Exercise \ref{ex_sepdef}:}

\begin{packed_itemize}[3]
\item This may be our first example of creating a file such as
  \var{function\_sepdef.h} that we include from one of our other
  files. In this case the file is included from both
  \var{function\_sepdef.cpp} and \var{function\_main.cpp}. 

\item The three pre-processor lines in \var{function\_sepdef.h} are there to 
  prevent an infinite cycle of includes, e.g., file A includes file B which 
  include file A and so on.

\item It may be a good time to dig into the topic of the C/C++
  pre-processor, at the links below. The pre-processor runs prior to
  the compiler. So it gets first dibs at defining things or blocking
  out code altogether. My favorite trick is the use of the \var{\#if 0}
  to temporarily comment out or disable a whole bunch of code. It's 
  much quicker than using comments. here's an example:

\vspace{0.1in}   
\begin{fileverb}
 #if 0
  // Some code we want the compiler to ignore
  if(argc &gt; 2) {
    cout &lt;&lt; "Usage: function_sepdef MESSAGE" &lt;&lt; endl;
    return(1);
  }
 #endif 
\end{fileverb}
\vspace{0.1in}   

\end{packed_itemize}

%---------------------------------------------------------
\vspace{0.15in}
\noindent
{\bf Further readingon the C preprocessor:}

\begin{packed_itemize}[3]
\item \urlx{http://www.learncpp.com/cpp-tutorial/110-a-first-look-at-the-preprocessor}
\item \urlx{http://www.cplusplus.com/doc/tutorial/preprocessor}
\item \urlx{http://www.cprogramming.com/tutorial/cpreprocessor.html}
\end{packed_itemize}




\end{document}

</pre></body></html>