Is the one with the square function, or the one with all in one function usually preferred? |
That's up to you. Just pick one and go with it. Some advice: Don't paralyze yourself over little details like this, they often don't matter. If the square function was some huge, complicated function with lots of branches, then I would say it's good to factor it out into its own equation, but in this case, it's really just up to you. Like Jonnin said, once you write more code you'll get the hang of what looks nice and readable, and what doesn't.
Here's some tips for when to use functions:
- When you spot duplicate code (or mostly duplicate code that only differs by a few values).
- When you have really long functions.
- When you have multi-line logic that you want make sure it kept together.
If you're worried about efficiency and stuff like take, I suggest looking up data structure and algorithms. This is where performance can actually matter. (If you're in a college, look if they offer classes like that, otherwise look it up with online resources or PDFs.) But again, don't paralyze yourself and not write anything because you're afraid of how something
might be inefficient. An extra function push/pop is not going to make or break your program, don't worry about that specifically.
Also, is it better to have the .h for function prototypes and .cpp for definitions, or should I put everything in one or the other? |
Normally, the function prototypes (that you want to be usable by other files) go in the .h, and the definitions go in the .cpp.
I kind of wanted to know if it was the accepted practice to wrap everything up into classes and functions, rather than having a bunch of code in main. |
Classes are a whole other beast, but generally I'd say a function shouldn't span more than ~50-100 lines of code. This is just a heuristic though, I certainly have tons of functions that are more than that.
Some functions might just be a line long, but the point of them is to be a "human readable" piece of reusable logic.
e.g.
1 2 3 4 5
|
/// t must be in range [0, 1]
byte interpolation(byte a, byte b, double t)
{
return std::round( (1.0 - t) * a + t * b );
}
|
Speaking of comments, do they only go over the prototype of the function? |
Comments go wherever you want :)
One use of comments is to spell out the intention of what the code should be doing.
Comments are to provide context to someone reading your code to explain what's happening, for times when the code itself might not be clear.
When comments are put above a function, it's usually to give a summary of what that function does, and any cautionary notes about the function.
// Calculates distance over both the prototype and the function. |
I don't understand this comment. "over both the prototype and the function"? You're using C++ syntax terms while explaining the logic of a function.
I would just saying something like,
"Calculates the distance between two (x, y) points". Done.
Here's an example of a comment on a random piece of code I have. I probably put a comment there because it might not be immediately obvious of what the for loop is doing. It can help the reader not get lost in the code.
1 2 3 4 5 6 7 8
|
// initialize template map to be completely white
for (size_t i = 0; i < map_specs.pixels.size(); i += 4)
{
map_specs.pixels[i+0] = 255;
map_specs.pixels[i+1] = 255;
map_specs.pixels[i+2] = 255;
map_specs.pixels[i+3] = 255;
}
|
If I have parts of a function that I don't think are worth it to factor out into their own functions, I might do something like this, to denote a "section" of the process.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
//
// 1. Make image (cone)
//
Point center(width/2, height/2);
double factor = (width/2) * std::sqrt(2);
for (unsigned y = 0; y < height; y++)
for (unsigned x = 0; x < width; x++)
{
double d = distance(Point(x, y), center);
d = d / factor;
image.pixels[4 * width * y + 4 * x] = 255 * d;
}
//
// 2. Do something else
//
// ...
|