Sams Teach Yourself C in 24 Hours (64 page)

BOOK: Sams Teach Yourself C in 24 Hours
4.48Mb size Format: txt, pdf, ePub

17: main(void)

18: {

19: char *str[MAX_NUM] = {“The choice of a point of view”,

20: “is the initial act of culture.”,

21: “--- by O. Gasset”};

22:

23: #if TEST_1 == 1

24: #if TEST_2 == 2

25: #if TEST_3 == 3

26: StrPrint(str, MAX_NUM);

27: #else

28: StrPrint(str, MAX_NUM - ONE);

29: #endif

30: #else

31: StrPrint(str, MAX_NUM - TWO);

32: #endif

33: #else

34: printf(“No TEST macro has been set.\n”);

35: #endif

continues

29 067231861x CH23 1/25/00 11:03 AM Page 404

404

Hour 23

LISTING 23.4

continued

36:

37: return NO_ERROR;

38: }

39: /* function definition */

40: void StrPrint(char **ptr_s, int max)

41: {

42: int i;

43:

44: for (i=0; i

45: printf(“Content: %s\n”,

46: ptr_s[i]);

47: }

The following output is shown on the screen after the executable 23L04.exe is created and run on my machine:

Content: The choice of a point of view

OUTPUT
Content: is the initial act of culture.

Content: --- by O. Gasset

The purpose of the program in Listing 23.4 is to print the content of character
ANALYSIS
strings controlled by the nested #if directives.

At the beginning of the program, nine macro names are defined in lines 5–13. The prototype of a function, StrPrint(), is given in line 15. Lines 19–21 define and initialize an array of char pointers called str.

The #if directives in lines 23–25 evaluate macro names, TEST_1, TEST_2, and TEST_3, respectively. If the three macro names all evaluate to nonzero values, thenStrPrint() is called in line 26 to print the content of all character strings pointed to by the pointers in the str array.

If, however, only TEST_1 and TEST_2 are nonzero, the statement in line 28 prints out the content of the MAX_NUM-ONE strings. Likewise, if only TEST_1 evaluates to a nonzero value, the StrPrint() function is called in line 31 to print out the content of the MAX_NUM-TWO strings.

The last case is that TEST_1, TEST_2, and TEST_3 all return zero. Then the printf() call in line 34 is executed to display onscreen the message No TEST macro has been set.

As you can tell from the program in Listing 23.4, TEST_1, TEST_2, and TEST_3 are all defined with nonzero constants; the content of all character strings referenced by the pointers of the str array are printed out as the output from the program.

You can experiment with the effects of these nested directives by changing the values of the macros TEST_1, TEST_2, and TEST_3.

29 067231861x CH23 1/25/00 11:03 AM Page 405

Compiling Programs: The C Preprocessor

405

Summary

In this lesson you learned the following important concepts and directives regarding the preprocessor in C:

• The C preprocessor runs before the compiler. During the preprocessing stage, all occurrences of a macro name are replaced by the macro body that is associated with the macro name.

23

• The C preprocessor also enables you to include additional source files in the program or compile sections of C code conditionally.

• The C preprocessor is not part of the C compiler.

• A macro statement ends with a newline character, not a semicolon.

• The #define directive tells the preprocessor to replace every occurrence of a macro name defined by the directive with a macro body that is associated with the macro name.

• The #undef directive is used to remove the definition of a macro name that has been previously defined.

• You can specify one or more arguments to a macro name defined by the #define directive.

• The #ifdef directive enables you to specify code that is to be included only when a particular macro name is defined.

• The #ifndef directive is a mirror directive to the #ifdef directive. With #ifndef, you specify code that is to be included when a particular macro name is not defined.

• The #endif directive is used to mark the end of an #ifdef, an #ifndef, or an #if block.

• The #if, #elif, and #else directives enable you to select alternate portions of code to compile.

In the next lesson you’ll see a summary of what you’ve learned and what you can do after studying this book.

Q&A

Q Is the C preprocessor part of the C compiler?

A
No. The C preprocessor is not part of the C compiler. With its own line-oriented grammar and syntax, the C preprocessor runs before the compiler in order to han-dle named constants, macros, and inclusion of files.

29 067231861x CH23 1/25/00 11:03 AM Page 406

406

Hour 23

Q How do you remove a macro name?

A
By using the #undef directive with a macro name, that macro name can be removed, or “undefined.” According to the ANSI C standard, a macro name has to be removed before it can be redefined.

Q Why do you need the
#endif
directive?

A
The #endif directive is used with an #if, #ifdef, or #ifndef directives because statements under the control of a conditional preprocessor directive are not enclosed in braces ({ and }). Therefore, #endif must be used to mark the end of the block of statements.

Q Can the conditional expression following the
#if
directive be an arithmetic
expression?

A
Yes. The conditional expression evaluated by the #if directive can be an arithmetic expression. If the expression evaluates to a nonzero value, the code between the

#if directive and the next nearest conditional directive are included for compilation. Otherwise, the code is skipped entirely and will not be part of the compiled program.

Workshop

To help solidify your understanding of this hour’s lesson, you are encouraged to answer the quiz questions and finish the exercises provided in the workshop before you move to the next lesson. The answers and hints to the questions and exercises are given in Appendix B, “Answers to Quiz Questions and Exercises.”

Quiz

1. What’s wrong with the following macro definition?

#define ONE 1;

2. What is the final value assigned to result after the assignment statement is executed?

#define ONE 1

#define NINE 9

#define EXPRESS ONE + NINE

result = EXPRESS * NINE;

3. What message will be displayed by the following code segment?

#define MACRO_NAME 0

#if MACRO_NAME

printf(“Under #if.\n”);

#else

printf(“Under #else.\n”);

#endif

29 067231861x CH23 1/25/00 11:03 AM Page 407

Compiling Programs: The C Preprocessor

407

4. What message will be displayed by the following code segment?

#define MACRO_NAME 0

#ifdef MACRO_NAME

printf(“Under #ifdef.\n”);

#endif

#ifndef MACRO_NAME

printf(“Under #ifndef.\n”);

#endif

23

Exercises

1. In Hour 18, “Using Special Data Types and Functions,” you learned how to define enum data. Rewrite the program in Listing 18.1 with the #define directive.

2. Define a macro name that can multiply two arguments. Write a program to calculate the multiplication of 2 and 3 with the help of the macro. Print out the result of the multiplication.

3. Rewrite the program in Listing 23.2 with the #if, #elif, and #else directives.

4. Rewrite the program in Listing 23.3 with nested #if directives.

29 067231861x CH23 1/25/00 11:03 AM Page 408

30 067231861x CH24 1/25/00 10:48 AM Page 409

HOUR 24

Where Do You Go from

Here?

It’s not what you know, but what you can.

—A. Alekhine

Congratulations! You’re now in the last chapter of this book. You just need to spend one more hour to complete your 24-hour journey. In this lesson you’ll learn more about the C language from the following topics:

• Programming style

• Modular programming

• Debugging

Also, a brief review on what you’ve learned from this book is included in this lesson. Before you start to cover these topics, let’s have a look at the last example in this book.

30 067231861x CH24 1/25/00 10:48 AM Page 410

410

Hour 24

Creating a Linked List

In this section, I’m going to build functions that can create a linked list, and add items to or delete items from the created linked list. I save those functions into a source file (that is, a
module
; refer to the section “Modular Programming” in this lesson). In addition, I will set up an interface between the module file and the user. In other words, the user can call one of the functions saved in the module via the interface. The interface is invoked in the main() function that is saved in another source file. I will put data declarations and function prototypes in a separate header file.

A
linked list
is a chain of nodes (or elements). Each node consists of data items and a pointer that points to the next node in the list. The last item has a null pointer to signify the end of the list.

A linked list is a very powerful, and very versatile, data structure. No matter what programming project you eventually undertake, it’s likely that you’ll want to use a linked list at some point. Why are linked lists so popular? For starters, they are relatively easy to implement, unlike some other data structures that may be more powerful but get complicated quickly. Secondly, it is easy to “walk” a linked list by simply following the pointers along. It’s almost as easy as using an array, but with a linked list you have the flexibility of dynamic memory allocation.

A linked list with N nodes is shown in Figure 24.1.

FIGURE 24.1

Head

node 1

node 2

• • •

node N

A linked list with N

nodes.

Null

As you can see from Figure 24.1, a start pointer points to the first node in the list. The pointer in the last (
N
th) node is a null pointer.

The linked list I’m going to build is a very simple one, in which each element only contains two items: a student name and an ID number. Listing 24.1 contains the module program, which is saved in the source file named 24L01.c.

TYPE

LISTING 24.1

Putting Cohesive Functions in the Module Program

1: /* 24L01.c: A module file */

2: #include “24L02.h”

3:

4: static NODE *head_ptr = NULL;

5:

30 067231861x CH24 1/25/00 10:48 AM Page 411

Where Do You Go From Here?

411

6: /**

7: ** main_interface()

8: **/

9: void main_interface(int ch)

10: {

11: switch (ch){

12: case ‘a’:

13: list_node_add();

14: break;

15: case ‘d’:

16: if (!list_node_delete())

17: list_node_print();

18: break;

19: case ‘p’:

20: list_node_print();

21: break;

22: default:

24

23: break;

24: }

25: }

26: /**

27: ** list_node_create()

28: **/

29: NODE *list_node_create(void)

30: {

31: NODE *ptr;

32:

33: if ((ptr=(NODE *)malloc(sizeof(NODE))) == NULL)

34: ErrorExit(“malloc() failed.\n”);

35:

36: ptr->next_ptr = NULL; /* set the next pointer to NULL */

37: ptr->id = 0; /* initialization */

38: return ptr;

39: }

40:

41: /**

42: ** list_node_add()

43: **/

44: void list_node_add(void)

45: {

46: NODE *new_ptr, *ptr;

47:

48: new_ptr = list_node_create();

49: printf(“Enter the student name and ID: “);

50: scanf(“%s%ld”, new_ptr->name, &new_ptr->id);

51:

52: if (head_ptr == NULL){

53: head_ptr = new_ptr;

54: } else {

continues

30 067231861x CH24 1/25/00 10:48 AM Page 412

412

Hour 24

LISTING 24.1

continued

55: /* find the last node in the list */

56: for (ptr=head_ptr;

57: ptr->next_ptr != NULL;

58: ptr=ptr->next_ptr)

59: ; /* doing nothing here */

60: /* link to the last node */

Other books

What's In A Name by Cook, Thomas H.
Blood Bond 5 by William W. Johnstone
Historia de los griegos by Indro Montanelli
Fry Me a Liver by Delia Rosen
Fight for Love by David Manoa
Princess by Jean P. Sasson
Fanon by John Edgar Wideman