In this blog post, I'll discuss the fundamental Data types in Steve McConnell's book Code Complete.
- To increase accuracy when adding numbers with differing magnitudes, add them starting with the smallest values.
- Avoid equality operations and anticipate rounding errors; cope by switching to greater precision, BCD, or integer variables.
Characters and Strings
To avoid endless strings in C, initialize strings to null, and use strncpy() instead of strcpy().
- Use enumerated types for more type-checking, and as a richer alternative to boolean variables.
- Explicitly assign their values to specify first and last values for iteration, and an invalid or "null" type.
In C, use or define an ARRAY_LENGTH() macro as #define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x)).
Creating Your Own Types
Don't name a type created using typedef after the underlying data type, and don't refer to predefined types.
By passing only one or two fields from a structure into a method, you promote information hiding from the method.
- Symptoms of pointer errors tend to be unrelated to causes of pointer errors.
- By isolating pointer operations to methods, you minimize the possibility of propagating careless mistakes through your program.
- Allocating dog tags allow you to check for freeing memory twice or overwriting memory beyond the last byte.
- Free pointers at the same scoping level as they were allocated, such as in the same method, or a constructor/destructor pair.
- Set a pointer to NULL after deallocation; writing to it produces an error, and deallocating twice is more easily caught.
- In C++, a reference cannot point to NULL and the object it refers to cannot be changed.
- In C, you can use char or void pointers for any type of variable.
- Passing a global variable to a method, and then referring to both the parameter and global variable is especially tricky.
- Initialization order among different "translation units," or files, is not defined in languages like C++.
- Try to contain a global variable as a class variable, and provide an accessor for any other code that needs it.
- Replace global data with access methods to centralize control over it and protect yourself against changes.
- Build access methods at the level of the problem domain rather than at the level of the implementation details.
My Key takeaways in these two chapters are;
- Working with specific data types means remembering many individual rules for each type.
- Creating your own types makes your programs easier to modify and more self-documenting, if your language supports that capability.
- When you create a simple type using typedef or its equivalent, consider whether you should be creating a new class instead.
- Structures can help make programs less complicated, easier to understand, and easier to maintain.
- Whenever you consider using a structure, consider whether a class would work better.
- Pointers are error-prone. Protect yourself by using access routines or classes and defensive-programming practices.
- Avoid global variables, not just because they’re dangerous, but because you can replace them with something better.
- If you can’t avoid global variables, work with them through access routines.
- Access routines give you everything that global variables give you, and more.