Skip to the content of the web site.

Functions

In the introduction, we already demonstrated how functions are written in C++ versus Python.

One major difference is that in C++, it is best practice, and actually the only practice in industry, to declare all of your functions in a file at the top. A function declaration includes the type of what will be returned (the return type), the name of the function, and the types and names of the parameters.

Then, later in the file, each function will be given a definition, that is, a body of statements that are to be executed when that function is called.

Again, to demonstrate professionalism, a function has parameters, and when another programmer calls that function, that programmer provides arguments. The parameters take on the values of those arguments. Inexperienced programmers will conflate the concepts of parameters and arguments.

In C++, you can give two functions the same name as long as the types of the parameters are different. In this case, the compiler will look at the types of the arguments and the types of the parameters of the function declaration and determine which is the most appropriate to call. For example:

// Pre-processor include statements
#include <cmath>

  ///////////////////////////
 // Function declarations //
///////////////////////////

int sqrt( int n );
double sqrt( double x );

  //////////////////////////
 // Function definitions //
//////////////////////////

// The variable name doesn't matter, but 'n' is more
// natural for a variable name that is an integer.
unsigned int sqrt( unsigned int n ) {
    unsigned int s{(n + 1)/2};

    if ( (s*s > n) || ((s + 1)*(s + 1) <= n ) {
        s = (s + n/s)/2;
    }

    return s;
}

// Again, the variable name doesn't matter, but 'x' is more
// natural for a variable that is a floating-point number.
double sqrt( double x ) {
    if ( x < 0 ) {
        return std::nan( "" );
    }

    unsigned int s{x/2.0};
    unsigned int s_old{};

    do {
        s_old = s;
        s = (s + x/s)/2.0;
    } while ( s_old != s );

    return s;
}

As you can see, the technique for computing an integer square root is subtly different from the technique for computing a floating-point square root.


Creating a library

If you are writing a number of functions you are using again and again, you may want to put them all in a file separate from the code you are writing. For example, you could put all the functions into a header file called tools.hpp. In this case, your file tools.hpp should look something like this:

#pragma once

// Pre-processor include statements
#include <cmath>
// include any other libraries you need

  ///////////////////////////
 // Function declarations //
///////////////////////////

// Declare all of your functions in your library
int sqrt( int n );
double sqrt( double x );

  //////////////////////////
 // Function definitions //
//////////////////////////

// Define all of your functions in your library

int sqrt( int n ) {
    // Function body for the integer square root
}

double sqrt( double x ) {
    // Function body for the floating-point square root
}

The #pragma once prevents this header file from being loaded twice.

Now, if you wanted to use this in some code you wrote, you would include this file:

#include <iostream>
#include "tools.hpp"

int main();

int main() {
    std::cout << sqrt( 583 ) << std::endl;
    std::cout << sqrt( 583.0 ) << std::endl;

    return 0;
}

A relative path could also be given:

#include <iostream>
#include "../tools/tools.hpp"

int main();

int main() {
    std::cout << sqrt( 583 ) << std::endl;
    std::cout << sqrt( 583.0 ) << std::endl;

    return 0;
}

Similarly, an absolute path could also be given:

#include <iostream>
#include "C:/Users/dwharder/C++/tools/tools.hpp"

int main();

int main() {
    std::cout << sqrt( 583 ) << std::endl;
    std::cout << sqrt( 583.0 ) << std::endl;

    return 0;
}

The pre-processor fixes the issues with the slashes and the backslashes.