The order in which you write function declaration matter in C/C++? O_o That sounds like an oversimplification...
Yep, especially when you consider declarations are not the same as definitions. I probably should have touched on that a bit in my previous lesson...
But if I want to talk specifically about another language, that will have to be another lesson in itself.
I got your back
Lesson 3.1: Things To Consider While Writing Functions
Rule #1: The compiler is lazy and stupid.If you call a function, it must have been declared prior to that point in the code. This will not work:
void a() {
b();
}
void b() {
// do something maybe
}
The compiler has not found a declaration for b at the point where it is called in a. The compiler, being lazy, won't go out of its way to find b. Because it is stupid, it will just assume b does not exist anywhere in the code. There are two ways to get around this. The programmer could simply not call functions in code from before they are defined. If they want more flexibility, then they can use a neat mechanism called function prototypes:
void a();
void b();
void a() {
b();
}
void b() {
// do something maybe
}
That code will work. Prototypes are made by only using the function header (see Lesson 3), followed by a semicolon. The function body is left off. This tells the compiler that the function does exist, but it is defined elsewhere. Even though b's function definition (which contains the function body) is after a's, its declaration (with the prototype) is still before a's definition, so it works.
Every function with a declaration must also have exactly one definition somewhere within the
compilation unit.
Rule #2: A function should do one thing very well.Corollary to Rule #2: A function that does multiple things should be split into multiple functions that each do one thing.Another Corollary to Rule #2: A function should have an accurate and descriptive name.Writing the entire code of a program into the main method is legal. That does not mean it is good. The modular programming paradigm came about as a response to the fact that code needs to be split up into reusable pieces in order to be effective and efficient when performing larger, more complicated tasks.
How much or how little a single function does depends on how broad/narrow your definition of a "thing" is. At the most extreme side of modular programming, the main function would exist only to call other functions. There are some who believe this is good practice. I'm not here to preach about what practice is best. I'm here to teach about good practices, so that you, as the programmer, can decide for yourself which practice you prefer.
Consider the following code:
#include <iostream>
using namespace std;
int print(int a) {
return a+1;
}
void addOne(int a) {
cout << a << endl;
}
int main() {
cout << print(5) << endl;
return 0;
}
Is this valid C++ code? Yes. Is it good C++ code? Hell no. The print function returns 1 + the integer argument, and the addOne function prints the integer argument. Meanwhile, the main function prints an integer, even though there is already a function that does that. This code fails Rule #2 and both of its corollaries. Let's make it better:
#include <iostream>
using namespace std;
int addOne(int a) {
return a+1;
}
void print(int a) {
cout << a << endl;
}
int main() {
print(addOne(5));
return 0;
}
There, much better. Granted, it's a bit overkill to have a method that adds one to a number, but this is example code, not practical code. It makes a point: functions should do what they say they do, and nothing more or less. There's a name for this concept, but I can't for the life of me remember it. If someone could help my brain out, it would be much appreciated.
There are more things to consider about functions, but they will have to be addressed after more lessons, because they involve language features that I haven't covered yet.