I just love Steve McConnell’s classic book Code Complete 2, and I recommend it to everyone in the Software ‘world’ who’s willing to progress and sharpen his skills.
Other blog posts in this series:
- Part 1 (Chapters 1 – 4): Laying the Foundation
- Chapter 5: Design in Construction
- Chapter 6: Working Classes
- Chapter 7: High-Quality Routines
- Chapter 8: Defensive programming
- Chapter 9: Pseudocode Programming Process
- Chapter 10: General Issues in Using Variables
- Chapter 11: General Issues in Using Variables
- Chapter 12: Fundemental Data Types
Structures
The term “structure” refers to data that’s build up from other types. You’ll generally want to create classes rather than structures so that you can take advantage of the privacy and functionality offered by classes in addition to the public data supported by structures. But sometimes structures can be useful, here are some reasons for using them:
- Use structures to clarify data relationships – structures bundle group of related items together
- Use structures to simplify operations on blocks of data – it’s easier to operate on the structure than to perform the same operation on each of the elements. It’s also more reliable, and it takes fewer lines of code.
- Use structures to simplify parameter lists
- Here is an example of a hard way to pass a group of related parameters:
HardWayRoutine( name, address, phone, gender, salary )
- And here is the easy way:
EasyWayRoutine ( employee )
- Here is an example of a hard way to pass a group of related parameters:
- Use structures to reduce maintenance – Because you group related data when you use structures, changing a structure requires fewer changes throughout a program.
Pointers
Pointer usage is one of the most error-prone areas of modern programming, to such an extent that modern languages like Java, C#, and Visual Basic don’t provide a pointer data type.
Even if your language doesn’t require you to use pointers, a good understanding of pointers will help your understanding of how your programming language works. Conceptually, every pointer consists of two parts:
- a location in memory and
- a knowledge of how to interpret the contents of that location
General Tips on Pointers
- Isolate pointer operations in routines or classes
- Declare and define pointers at the same time
- Delete pointers at the same scooping level as they were allocated
- Check pointers before using them – make sure the memory location it points to is reasonable
- Use extra pointer variables for clarity – the point is made elsewhere that a variable shouldn’t be used for more than one purpose. This is especially true for pointer variables.
- Simplify complicated pointer expressions
- Set pointers to null after deleting or freeing them – one reason pointer errors are hard to detect is that sometimes the error doesn’t produce any symptoms. By setting pointers to null after freeing them, you ensure that writing data to a dangling pointer produces an error.
Global Data
Global variables are accessible anywhere in a program. Even if global variables don’t always produce errors, however, they’re hardly ever the best way to program.
Common Problems with Global Data
- Inadvertent changes to global data – You might change the value of a global variable in one place and mistakenly think that it has remained unchanged somewhere else
- Bizarre and exciting aliasing problems with global data – “Aliasing” refers to calling the same variable by two or more different names. Here is the example in Visual Basic:
Sub WriteGlobal( ByRef inputVar as Integer )
inputVar = 0
globalVar = inputVar + 5
MsgBox( "Input Variable: " & Str( inputVar ) )
MsgBox( "Global Variable: " & Str( globalVar ) )
End Sub
Here’s the code that calls the routine with global variable as an argument: WriteGlobal( globalVar )
Here’s the surprising result:
Input Variable: 5
Global Variable: 5
The subtlety here is that globalVar
and inputVar
are actually the same variable! MsgBox()
displays the same variable twice, even though they refer to two different names.
+ Code reuse hindered by global data – if the class you want to reuse reads or writes global data, you can’t just plug it into the new program.
+ Modularity and intellectual manageability damaged by global data – if you use global data, can you concentrate on one routine at a time? No. You have to concentrate on one routine and every other routine that uses the same global data.
Reasons to Use Global Data
- Preservation of global values
- Streamlining use of extremely common data
- Eliminating tramp data – sometimes you pass data to a routine or class merely so that it can be passed to another routine or class.
Using Access Routines Instead of Global Data
Anything you can do with global data, you can do better with access routines. The use of access routines is a core technique for implementing abstract data types and achieving information hiding.
How to Use Access Routines
Hide data in a class. Declare that data by using the static
keyword or its equivalent to ensure only a single instance of the data exists. Write routines that let you look at the data and routines that let you change data. Require code outside the class to use the access routines rather than working directly with data.
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.