From RoboWiki
Here you can find a few tips and tricks for several programming languages. Feel free to add your own!
Contents |
[edit] General Practice
- When programming, always remember these three general rules
- Keep code simple: The best code is always simple and minimalistic code
- Keep code documented: Document pieces of code and algorithms as much as possible to help other developers
- Never write the same code twice: If a common piece of code is used several times, wrap it as a function
- Design before writing code
- Keep your code minimalistic: A method and approach to generating clear and concise code in the least amount of instructions possible that naturally leads to optimized code.
- Do not have multiple return points from a function, keep the count as low as possible to reduce complexity
- Check for possible errors before calling a function, not after. If you pass a negative value to a sqrt() function, it might or might not return an error. Always check if the given value is within the domain of the function first
- Document your code to help yourself, help with better design, and help others
- Be wary of buffer overflows since languages such as C/C++ do not check array bounds
- Your first attempt should be your as close to the final production code; Think before writing code
- Never have deeply nested code or code that is too long
- Show your sources; If you are using an algorithm, clearly note the source and/or document
- Debugging tips
- Try not to use try/throw/catch blocks if they can be tested with if/else statements; This is due to performance issues
- Use the debugger in your IDE or the command line debugger GDB
- Printing out data onto the command line is an effective way of debugging
- Always read your warnings, as they give good insight to possible run-time errors
- Set your compiler to the highest warning level/sensitivity. This is done by passing the -Wall -Wextra parameters in the GNU C/C++ compilers
- In languages with unmanaged memory (such as C/C++, where the language does not manage how you access memory), segmentation faults, or errors in which the process reads or writes out of bounds, are common
- Prevent this by always defaulting non-initialized pointers to NULL, checking if a pointer is valid when given as a parameters, and checking all memory allocations
[edit] Spartan programming
This is a concept that comes from an article which points out great methods of quality code generation, found here. The goal is to keep all of the below issues as low as possible, meaning keep horizontal complexity low, keep token count low, etc...
- Horizontal complexity: The depth of nesting of control structures.
- Vertical complexity: The number of lines or length of code.
- Token count.
- Character count.
- Parameters. The number of parameters to a routine or a generic structure.
- Variables.
- Loop usage: The number of iterative instructions and their nesting level.
- Conditionals. The number of if and multiple branch switch statements.
All of these suggestions, if followed, greatly reduces code complexity, makes the code easier to maintain, as well as makes the code significantly easier to work with. Also, these practices help you better manage variables:
- Minimize number of variables. Inline variables which are used only once. Take advantage of foreach loops.
- Minimize visibility of variables and other identifiers. Define variables at the smallest possible scope.
- Minimize accessibility of variables. Prefer the greater encapsulation of private variables.
- Minimize variability of variables. Strive to make variables final in Java and const in C++. Use annotations or restrictions whenever possible.
- Minimize lifetime of variables. Prefer ephemeral variables to longer lived ones. Avoid persistent variables such as files.
- Minimize names of variables. Short-lived, tightly scoped variables can use concise, terse names.
- Minimize use of array variables. Replace them with collections provided by your standard libraries.
[edit] C
- In strict C, you can mimic a 'pass by reference' (a feature of C++) with pointers:
// Example code: (Note how in C++ you would write int &val, but in C you write int *val void AddNumber(int *val, int adder) { *val += adder; }
- Note that you must pass the address of the integer you wish to change to this function (for example, AddNumber(&myNumber, myOtherNumber)).
- The C99 standard is easier to work with as you do not need to declare variables in the beginning of a code block
- Make code more compact using Bit fields
- It is possible to port object-oriented ideas to C. Examples of this can be found at Porting Object-Oriented Concepts to C.
- You can write a custom assert macro that may print out the line and filename an error occurs in
// In this case, we use "Assert(bool assertion, int errCode)" to validate a boolean expression // In case of an error, we use a special custom function __Assert to print out the error onto the command line #define Assert(assertion, errCode) __Assert((assertion), (errCode), __FILE__, __LINE__)
[edit] C++
- All of the above may be applied to C++
- A general rule of thumb for design when it comes to data members of a class is to have roughly 7 data members, with more or less 2. This is because the average human can remember 7 data members at a time, which helps when developing other code
There is often confusion between the differences between private, public, and protected. These come from one of the basic concept of Object Oriented Programming, which is the core principle of C++: Data encapsulation. These three keywords can be seen as class-level member scope control and access flags. Any class member following one of the three keywords is considered under that control.
If you create a member in a class that contains information related to it's internal workings, but should not be edited by an end-user of the class, it should be within "private" control. This prevents end users from access the member even hides it from derived classes.
If the member is allowed to be called or changed by the end-user, then it should be "public". For example, almost all constructors and get/set functions are made public.
If a member is not to be accessed outside of the class, but should give access to a derived class, then it should be given "protected" control.
