Basic Functions

5 minute read

This article is part 1 in a series: C++ introduction



So, a friend of mine is studying C++ and had some issues understanding how functions works. So I wrote a short gist to try to explain it to her. Then I thought that - oh I got a blog, why not just paste this snippet and description in there so that people could read it if they find it enlightening!? So here it is (slightly edited from the original gist)!

Please, if you find ANY type of errors or anything, please let me know, and I’ll update it!

First off, a Disclaimer:

Global functions is an abomination in OOP, and I would not recommend using them like this, but this is just an example of functions, how they look and what they do, so, the usage of global functions is (imho) okay, in this case!

Dissecting a function

This is a function:

int _tmain(int argc, char* args) {
  return 0;
}

Not only is this a function, its the main entry point of a c++ program, the main function!

A function always begin with a type, in this case a integer type. This type tells what the function is expected to return. It can return basically any type, any object or even another function (don’t care about the last statement for now, cause that is not for now!) or void. If it returns void, it returns nothing.

Next part of the function is the name. A functions name is up to the person who writes it to decide, it can be named basically anything at all (there are reserved words and there are characters a function can not contain, but generally, it can be named whatever you want), it is preferred that it is named after what it does, you want your code to be easy to understand.
Its also good to know that most projects have a code standard, it is a very good idea to follow this standard.

After the name there are a set of parentheses containing the in-parameters, function arguments. A function does not require arguments, but it can them. The arguments can be of any type, just like the return type. (Observe, I will not go through how pointers/references, const values or anything like that works here, only the basics). The arguments needs to be a type, following a name, in the example functions case, a int value named argc, and a char pointer named args (what those two in the main function does is not important at the moment). A function can have as many parameters as the writer wants it to have, it might be a good idea to narrow it down a bit though, a few params should be enough, else the design might be a bit… wrong.

After the parameters, inside the curly-brackets, is the function scope. Inside this scope is where all the functionality of the function exists. All variables created (allocated on the stack, which I will cover in a later post) inside a function, will be destroyed at the end of the scope (or whenever the function exits). At the end of the function (or any other exit point) a return must be (if void, return is not required, but could still use it (return;, cause there is no type but void, which is nothing!). The return value have to be of the same type as the declared type at the beginning of the function, else the compiler will cry. In the main function case above, 0 is returned, and 0 is a none flotingpoint number, a integer, so its okay.

Implementing a function

As long as the rules above is followed, implementing a function should not be a big deal.
Here is an example function that is not the main function:

double DoSomethingCool(int aInt, char aChar) {
  if(aChar == 'A') {
    return 0.0;
  }
  return static_cast<double>(aInt) / 3.0;
}

Now, this function has the return type double (a double is a decimal/floating point value), its named DoSomethingCool (which obviously is a lie, god damn developer!) and takes two parameters: a int named aInt and a char named aChar. Inside, all it does is check if the character equals A, then it exits the function (using return) with the value 0.0, which is a double. If its not an A, it casts the aInt parameter to a double (using a static_cast) and then divides it by 3.0. The value from the equation is returned. Then the function ends.

Not too hard, right? :)

Invoking a function

So, we now know how a function works and how to implement it, but what good is a function if its not used?
Well, another example:

double DoSomethingCool(int aInt, char aChar) {
  if(aChar == 'A') {
    return 0.0;
  }
  return static_cast<double>(aInt) / 3.0;
}

int _tmain(int argc, char* args) {
  double thevalue = DoSomethingCool(5, 'A');
  double anotherValue = DoSomethingCool(3, 'B');
  return 0;
}

So, whats happening here?
First of all, the function that was created earlier is declared and implemented. After the function is declared, the main function is implemented.
Inside the main function scope, there are two variables declared, two doubles. The values are not set to the variables right away instead there is a function call after the equal sign.
Now, as we know, a function returns a value, and in the DoSomethingCool functions case, a double.
This means that the variables will contain the value that the function returns. The two functions got different values when called, its actually the same function called twice, but the values sent in are different. In the example, the first call contains a 5 and a A as params, that means that the aInt will be 5 and the aChar will be A inside the function scope. And if the aChar parameter is A, 0.0 will be returned, so: thevalue will equal 0.0 (floating point precision is not mentioned here, we take that in a later chapter) when the function have returned.
In the next case, the params are 3 and B, which means that aInt will be 3, and aChar will be B. Now, the aChar does not equal A in this case, so it will cast the aInt to double and divide it by 3.
So, anotherValue is 1!

Then the main function returns 0 and the program is done.


That’s it for now. If you find anything that is wrong, please alert me so I can fix it!

This post have been moved from the old blog.
Original publish date is Oct 5 2014.