Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Advanced C 1992

.pdf
Скачиваний:
92
Добавлен:
17.08.2013
Размер:
4.28 Mб
Скачать

Special Pointers and Their Use

C C C

 

C4C

 

C C C

 

C

it work properly) under Windows in less time than it took to write the entire thing myself. I had to write it, though, to provide the example of both menus and the use of arrays of pointers. Now you can decide what you want to do.

State Machines

You might think that state machines are part of your state government, but not for the purposes of this book. The example program JUSTIFY is a state machine (refer to Listing 4.1). Most state machines consist of a controlling variable (the state variable), whose value indicates the current operating status of the function (or program). The state variable generally is an integer value, and depending on its current state, can be changed to another state.

Generally, in most state machines the state of the controlling variable does not need to be incremented (or decremented) in single steps. For example, it may change directly from one state to another. States generally can be considered to be unique but equal. When you are writing a state machine, you must consider the process and what needs to be done (see Figure 4.1).

Figure 4.1. An example of a state machine’s state transitions.

135

Part I • Honing Your C Skills

Figure 4.1 shows that the program has a number of “states.” The state machine part of JUSTIFY is the processing of the three parameters: the input filename, the output filename, and the output width you want.

Listing 4.5 shows the way the state machine works. The major part of this machine is a simple switch() loop, with a case to handle each state. At the end of each state’s case statement is the code necessary to update the status of the state variable, nCurrentParameter. The next time the switch() statement is executed, this new state of nCurrentParameter controls which case: statement is executed. As usual with a switch() statement, only one case statement block is executed (you don’t allow case statements to fall through, into the following case statement, in this state machine).

One important factor limits JUSTIFY’s state machine: You allow the state variable to change to only the next state, and you don’t allow states to be skipped. The only way to get to the WIDTH state, therefore, is from the OUTNAME state, and the only way to get to the OUTNAME state is from the INNAME state. After the WIDTH state has been achieved, any further changes in the state are errors because you have nothing else to get. The result is that the next state from the WIDTH state is the error state, LAST_THING, which, if processed, gives the user an error message. Listing 4.5 is the parameter processor from the JUSTIFY program.

Listing 4.5. State machine from JUSTIFY.C.

switch(nCurrentParameter)

{

case INNAME:

strcpy(szInputFile, argv[i]); nCurrentParameter = OUTNAME; break;

case OUTNAME:

strcpy(szOutputFile, argv[i]); nCurrentParameter = WIDTH; break;

case WIDTH:

sscanf(argv[i], "%d", &nTempWidth);

if (nTempWidth < 20 || nTempWidth > 128)

{

GiveHelp(BAD_WIDTH, NULL);

}

136

Special Pointers and Their Use

C C C

 

C4C

 

C C C

 

C

else

{

nLineWidth = nTempWidth;

}

nCurrentParameter = LAST_THING;

break;

default:

GiveHelp(BAD_PARM, NULL); break;

}

State machines can prove valuable in helping to organize your programs. The use of a state variable was a logical choice as a method to keep track of where I was in the program’s command line and to track which parts of the required command parameters had been processed.

Summary

In this chapter, you learned about command line arguments, pointer arrays, function pointers, and state machines.

Each program is passed, as parameters to the main() function, the command line parameters.

Command line parameters are processed by the operating system, by being parsed into separate tokens.

You can obtain the name of your program (the executable file’s name) using the parameters passed to main().

Like data objects, functions can have pointers to them.

Like any other pointer, a function pointer can be placed in an array and indexed using an index variable.

Function pointers can be passed as parameters to other functions, which then can call these functions.

137

Part I • Honing Your C Skills

Properly designed menu-driven programs can offer an excellent user interface.

It generally is not worth the effort to design your own menu system. Using Windows, OS/2, the Macintosh, XWindows, or some other commercially available menuing system is a much better choice.

Using state machines enables you to efficiently design a program that must process data in either a fixed or random format.

138

Decimal,CBinary, Hex,Cand Octal CC C C

C5C C

5 C C C

C C C

C C C

Decimal, Binary, Hex,

and Octal

By now, you probably have realized that computers don’t save numbers in memory in the same format as humans do. The CPU converts a number that the computer’s user provides to a format that the CPU better understands. This conversion, transparent to both the user and the programmer, enables the computer to work efficiently.

Decimal

We work with decimal (base 10) numbers. Decimal numbers have become popular primarily because we, as humans, usually have ten fingers. Yes, it’s true, our number system is based on counting on our fingers. Why, then, don’t we use base 5, (the fingers on one hand), or base 20 (both hands and feet)?

139

Part I • Honing Your C Skills

Decimal numbers have become so natural to use that we no longer stop to think about the concept of what we are doing. We add, carry, subtract, multiply, and divide with ease (most of us do, anyway) and don’t stop to consider any other based number systems; when we are asked whether we use any of these other systems, most people reply “No.” The next most common system, however, is base 60—time, where 60 seconds make a minute, and 60 minutes make an hour. We don’t get shaken when we are presented with time computations; when we have to convert to or work in number systems other than decimal, however, our palms sweat and we get the shakes.

Let’s review the decimal number system. First, decimal numbers have the characters to represent items. Figure 5.1 shows the first ten digits and what they represent.

Figure 5.1. Decimal numbers 0 through 9.

The first use of numbers was probably to count food stocks, livestock, and other objects encountered daily. As shown in Figure 5.1, a problem begins when you have more than nine objects. Things get difficult then: Should new digits be created, or a new system?

When the decimal system was developed, someone decided that ten characters (or digits) were sufficient and that a system had to be created to indicate how many hands there were to represent the object being counted—the tens column was created. It then was possible to write, using two digits, numbers that were ten times as large as before. No one realized that there would ever be a need for a number larger than 99. (After all, the greatest number of fish ever caught at a single time probably was only 18). The decimal number system was born, capable of representing as many as 99 objects.

140

Decimal, Binary, Hex, and Octal

C C C

 

C5C

 

C C C

 

C

Then Joe came along. Brighter than most, he invented the fishing net. He forgot to patent the fishing net, and soon a number of cheap but usable clone fishing nets were available. Bob, who bought one of the better clones, managed one day to catch much more than 99 fish. He went home and proudly announced that his catch was “99 and many more,” to which his loving wife wanted to know how many more. The hundreds column then was created. Bob’s wife simply carried the concept of the tens column out to a new column. And so it went—soon thousands, millions, and (when government was created) billions were only a short way off.

All of this math, using the decimal number system, could be done with the help of the oldest digital computer, the hand.

Binary

Digital computers, invented later, didn’t have hands. They used memory to store numbers. This memory, which lacked fingers, could hold only a zero (nothing) or a one (something). Any number greater than one couldn’t be represented within a single computer memory location. (I’m ignoring the analog computer, which could store more than zero and one in a single memory location—they never became popular and are not widely available today).

After the first few hours of working with zero and one, it was apparent that a way to represent numbers larger than one had to be developed. This task wasn’t difficult because designers and engineers are bright folks, and a scheme of using consecutive locations in memory was quickly developed.

Because only two states existed in a single memory location, the representation of numbers with computers was called binary. The use of this word is common with computers: Computers sometimes are referred to today as binary computers. To a computer, binary is as natural as decimal is to humans. Computers have no problems counting, doing math, storing, and performing I/O using binary numbers. The representation of binary numbers, however, left much to be desired. For instance, the year 1992 can be represented using only four digits with the decimal number system; in binary, it is represented as 11111001000 (11 digits). This number is not nearly as easy for humans to work with, write, or understand.

Look at Figure 5.2 to see how the binary value for 1992 is determined. This figure shows the binary value, the value of each bit, and the decimal result.

141

Part I • Honing Your C Skills

Figure 5.2 The year 1992 in decimal and binary.

Hex

Computers did not always have an 8-bit block of memory defined. Early computers used 10, 11, and 16 bits, and other computers probably were developed that had every other possible number of bits.

Hex is the compromise that enables both computers and people to understand number representation. The hex number system is based on 16. My guess is that the word hex was adopted because the base was 6 greater than base 10. Hex adds a new wrinkle: Binary uses only 2 digits, 0 and 1; decimal uses 10, 0 to 9; hex, however, uses 16 numeric digits. Because you don’t have 16 digits, either 6 new characters must be created to represent the new numbers, or you must use 6 existing characters. Introducing 6 new characters into the currently used character set isn’t easy, but reusing 6 other characters is easy.

The developers of hex notation chose to use the characters A through F for the new digits (see Figure 5.3). No standard exists for whether the digits are represented in upperor lowercase; I prefer uppercase, however, because numeric characters give the appearance of being uppercase (or larger) characters.

142

Decimal, Binary, Hex, and Octal

C C C

 

C5C

 

C C C

 

C

Figure 5.3. Hex numbers 0 through F.

Because most of the development of computers was done in countries that used the Roman alphabet, the choice of the number of bits in a computer’s word generally was determined by the number of characters the computer could recognize. As the computer was being developed, a number of systems to organize the characters and assign each to a numeric value already were in existence. The minimum number of characters was fairly large: It was necessary to have letters—both upperand lowercase (52), numbers (10), punctuation and symbols (about 20), which brought the total to between 80 and 90 characters.

In binary number systems, the number of bits increases in the following progression: 1, 2, 4, 8, 16, 32, 64, 128, 256, and so on. Most people quickly realized that 64 (a 6-bit word) was too small, 128 (a 7-bit word) was much better, and that 256 (an 8-bit word) was all that would ever be needed. Obviously, this artificial limit was based on current needs, with no consideration of the future. Sixteen bits now are used to represent characters in some applications.

Eight bits generally was accepted for the size of the basic block of computer memory. This amount was referred to as a byte; the origins of this word, however, escape me.

143

Part I • Honing Your C Skills

Hex might have been developed as a compromise between binary, required for the computer, and decimal, required for programmers. Two hex digits can be held in the standard-size computer memory, which is eight bits.

The example of 1992 becomes 7C8 when it is represented in hex. This number, which is not as long as its decimal equivalent (it has only three digits), is almost as indecipherable as the binary. It isn’t necessary to be able to read hex numbers to be a good programmer, but it helps.

To see how the hex value for 1992 is determined, look at Figure 5.4. It shows the hex value, the value of each digit, and the decimal result.

Figure 5.4. The year 1992 in decimal and hex.

Octal

Octal, the base 8 number system, enjoyed great popularity on a number of DEC computers, primarily the PDP-8. Trust me, though, octal is dead. Don’t use it, because no one else uses it anymore. Some computers used word lengths that were not 8 bits (a byte) long. Rather, they used a 12-bit word that easily was divided into 4 octal digits of 3 bits each. Unlike hex, which has more than 10 characters, octal has only 8, which

144