Subprograms

Fundamentals on Computing for Robotics, Graphics and Computer Vision

Darío Suárez - Adolfo Muñoz

Subprograms

A subprogram is a part of your program that implements an independent algorithm that can be used from different places within the rest of the program

Problem

Develop a program that, given a number n of lines, draws a triangle with asterisks ('*').
Example for n=5:

            *
           ***
          *****
         *******
        *********
        

Problem

Develop a program that, given a numerator and denominator, simplifies the rational number.

Problem

Develop a program that calculates the least common multiple of two given numbers.

Subprograms

... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... Subprogram 1 Subprogram 2 Main program call subprogram 1 call subprogram 1 call subprogram 2

Specification :What does it do?

Specification :What does it do?

... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... Main program call subprogram 1 call subprogram 1 call subprogram 2

Implementation :How does it do it?

Implementation :How does it do it?

... ... ... ... ... ... ... ... ... ... ... ... ... ... Subprogram 1 Subprogram 2

Thinking with subprograms

  • Define a large problem as a composition of partial solutions from subproblems
  • For each subproblem: develop its implementation or use implementation from others

Advantages

  • Legibility (shorter code)
  • Mantainability (bugs/changes are easily located)
  • You don't repeat yourself

Subprograms

are represented in C++ as

functions

Function specification


		    return_type function_name(type1 parameter1, type2 parameter2);	
		

Function specification


           /**
            * The function function_name does ...
            * parameter1 represents ...
            * parameter2 is ...
            * returns the result ...
            **/
		    return_type function_name(type1 parameter1, type2 parameter2);	
		

Specification example


            /**
             * The function repeat outputs the same charater a number of times.
             * 
             * n represents the number of times
             * c is the character that is repeated
             * The function returns nothing
             */
            void repeat(int n, char c);	
		

Specification example


            /**
             * The function gcf calculates the greatest common factor
             * between two numbers.
             * 
             * a y b are the two numbers
             * The function returns the calculated greatest common factor
             */
            int gcf(int a, int b);	
		

Online documentation

link

Copy vs Reference

What does this do? How is it different from previous examples?

Parameters are copied, so they do not change. Does not work!


            /**
             * Swaps real values 
             * 
             * a and b are the values to be swapped
             * Returns nothing
             */
            void swap(float a, float b);	
		

Parameters are referenced, so they must be variables. Works!


            /**
             * Swaps the real values of the variables 
             * 
             * a and b are references to the variables
             * Returns nothing
             */
            void swap(float& a, float& b);	
		

Parameters by copy

By default: when invoking, values of arguments are copied to the corresponding parameters

Parameters by copy


        float x = 5; float y = 3;
        swap(x,y);
        
  • a gets the value of x (5)
  • b gets the value of y (3)

        void swap(float a, float b);
        

Parameters by copy


        swap(5,3);
        
  • a gets the value of x (5)
  • b gets the value of y (3)

        void swap(float a, float b);
        

Parameters by reference

When invoking, the argument variables are referenced (aliased). Whatever happens to the parameters happens to the variables

  • They work as output parameters.
  • They are related to pointers (see later)

Parameters by reference


        float x = 5; float y = 3;
        swap(x,y);
        
  • a gets a reference to x
  • b gets a reference to y

        void swap(float& a, float& b);
        

Parameters by reference


        float x = 5; float y = 3;
        swap(x,y);
        //swap(5,3) does not compile
        
  • a gets a reference to x
  • b gets a reference to y

        void swap(float& a, float& b);
        

Parameters by reference


        float x = 5; float y = 3;
        swap(x,y);
        //swap(5,3) does not compile
        
  • Whatever happens to a happens to x
  • Whatever happens to b happens to y

        void swap(float& a, float& b);
        

Output parameter vs. return value

The output of a function can be represented as a reference parameter or as the return value of the function.

Output parameter Return value

                    void sqr(float x, float& x2);
                    

                    float sqr(float x);
                    

                    float t; //t has a value
                    float t2_1;
                    sqr(t,t2_1);
                    t2_1 += 1;
                    

                            float t; // t has a value
                            float t2_1 = sqr(t) + 1;
                    

Output parameter vs. return value

When possible, use return values instead of reference parameters.

When is that not possible?

  • When the function is given to you (you are not implementing it).
  • When you have several values to return
  • Low level efficiency/memory reasons (out of the scope of this course)

Copy vs. reference: cost

  • Cost of copy proportional to data type's size
  • Cost of reference is constant (always 64 bits)

Copy vs. reference: cost


            struct BigType {
                float v[1000000]; 
            }; 
        
This is too costly:

            void function(BigType bt);
        
This might modify it (and sometimes I don't want to):

            void function(BigType& bt);
        

Copy vs. reference: cost


            struct BigType {
                float v[1000000]; 
            }; 
        

            void function(const BigType& bt);
        

More about this later in this course

Function implementation


		    return_type function_name(type1 parameter1, type2 parameter2);	
		

Function implementation


		    return_type function_name(type1 parameter1, type2 parameter2) {
                //Code that implements the behavior of the function
            } 
		

Implementation example

Implementation example

Implementation example

Distributing code

Where to locate the implementation code?

Distributing code

Where to locate the code?

  • Specification
  • Implementation
  • Main program

Distributing code

triangle.cpp

Distributing code

repeat.h

triangle.cpp

Distributing code

repeat.h

repeat.cpp

triangle.cpp

Compile both .cpp


g++ repeat.cpp triangle.cpp -o triangle
                

Compilation gets complex

You need to compile all .cpp files


            g++ repeat.cpp triangle.cpp -o triangle
        

Better if done step by step (no need to recompile)


                g++ repeat.cpp -c -o repeat.o
                g++ repeat.o triangle.cpp -o triangle
            

More about this later on this course

Function testing

When implementing a function, do not integrate with the rest of the software yet.

TEST IT

Function testing

How? Create another main program with the only purpose of testing it.

Function testing

There are tools for facilitating the testing process

Function testing

When to write the test code?

  • After production code (traditional methodology)
  • Before production code
  • Parallel to production code (test-driven development)