The Concept of Subroutines
Now that you have looked at the concept of representing data with symbols (i.e., variable names), you can move forward with representing program actions or commands with almost the same thing. In this topic, you will be creating and using subroutines, which in C are called functions.
Subroutines, or subprograms, are small parts of a program that accomplish specific tasks in the program. They are very helpful at simplifying the programming process through the use of abstraction. As promised previously, you will be continuing the process of learning about abstraction, and expanding your knowledge of it. These subroutines act as modules that contribute to the success or execution of a more complicated process.
The initial abstraction is that the main program is also a function in the C programming language. The main function has one target: it solves a problem or creates a solution. However, since that target may involve accomplishing several smaller subgoals, the main function is considered a driver. It is acceptable for this one function to execute several different kinds of operations because they all still come under the umbrella of solving the stated problem or creating the specified solution. As you will see, all other functions must have one task or goal, and, since they are not drivers, they must be tightly focused.
Anybody can use functions, and many people can write working programs. However, a good Computer Scientist will approach the process of writing a program more as an architect than a carpenter. In other words, an architect specifies what should be done, for example in how the roof should be sloped, or how the walls should be reinforced. She does not worry about mounting shingles or hammering nails as the carpenter must. As you learn to create and apply functions, you will also be learning how to be an architect by abstracting the actual operations into program functions.
Subroutine (function) Characteristics
Well designed functions have the following characteristics:
a | ACCOMPLISH ONE TASK. functions are designed to take care of one piece of business. They may be able to do that business repeatedly, or under varying circumstances, or in different parts of a program, but they should do only one thing. A corollary to this rule is that the identifier used for the function must be clear and precise. If a function is called addTwoItems, it should add two items; it should not input anything, it should not output anything, and it should not add three or more items; it should add two items. An obvious result of this is that functions will never be called func1, or func2, or foo, or bar, or anything other than exactly what the function is meant to do. Another fairly obvious point is that since functions always conduct some action, their identifiers should in almost all cases start with a verb. |
b | DEMONSTRATE MODULARITY AND REUSABILITY. Since functions should accomplish one task, each one is a self-contained and unique module (i.e., its own self contained package) that takes care of its own business. This is much like the components in a personal computer. The video card does nothing but get video data from the bus, manipulate that data appropriately, and send the data to the monitor. Even though the video card may support a movie display, it does not do anything to support the DVD player or the hard drive; it is just a video card. Then to extend on the analogy, remember that a video card can send any kind of image to the screen. The image might be text characters, it might be a scanned picture, and it might be a 3-D game image. In addition, the graphics card will commonly be designed to display information on a variety of different monitors. Functions, acting like modules, should do the one job they are given, but they should be able to do it with a variety of incoming or outgoing data or conditions; this makes functions modular, reusable, and generalizable. |
c | MEET SPECIFICATIONS. While further discussion on this will be provided later, there are three primary concerns for designing a function: 1) what conditions are assured to be true before the function is called (i.e., the preconditions), 2) what conditions must be true when the function is finished (i.e., the postconditions), and 3) how will unexpected or exceptional conditions be handled if the function encounters them (i.e., the exceptional conditions). Like a trained professional, once a function has been thoroughly tested with these concerns in mind, that function can be trusted to implement its part of the program with minimum chance of failure. |
The concept of subroutines, known as functions in the C programming language, will be one of the most important foundational knowledge components you will apply. Once you understand the specifications, goals, and implementation of functions, you will be able to write any program – at any scale – that you wish to write.
Watch this video to expand on the concept of functional abstraction and modularity. It will give you a flavor of how everything is functional in some kind of way.