Read Sams Teach Yourself C in 24 Hours Online
Authors: Tony. Zhang
The C language provides you with an additional data type—the enum data type. enum is short for
enumerated
. The enumerated data type can be used to declare named integer constants. The enum data type makes the C program more readable and easier to maintain. (Another way to declare a named constant is to use the #define directive, which is introduced later in this book.)
Declaring the
enum
Data Type
The general form of the enum data type declaration is
AX
enum tag_name {enumeration_list} variable_list;
YNT
Here tag_name is the name of the enumeration. variable_list gives a list of variable
S
,
names that are of the enum data type. enumeration_list contains defined enumerated
,
names that are used to represent integer constants. (Both tag_name and variable_list are optional.)
For instance, the following declares an enum data type with the tag name of automobile: enum automobile {sedan, pick_up, sport_utility};
Given this, you can define enum variables like this:
enum automobile domestic, foreign;
Here the two enum variables, domestic and foreign, are defined.
Of course, you can always declare and define a list of enum variables in a single statement, as shown in the general form of the enum declaration. Therefore, you can rewrite the enum declaration of domestic and foreign like this:
enum automobile {sedan, pick_up, sport_utility} domestic, foreign;
Assigning Values to
enum
Names
By default, the integer value associated with the leftmost name in the enumeration list field, surrounded by the braces ({ and }), starts with 0, and the value of each name in the rest of the list increases by one from left to right. Therefore, in the previous example, sedan, pick_up, and sport_utility have the values of 0, 1, and 2, respectively.
In fact, you can assign integer values to enum names. Considering the previous example, you can initialize the enumerated names like this:
enum automobile {sedan = 60, pick_up = 30, sport_utility = 10};
23 067231861x CH18 1/25/00 10:31 AM Page 297
Using Special Data Types and Functions
297
Now, sedan represents the value of 60, pick_up has the value of 30, and sport_utility assumes the value of 10.
The program shown in Listing 18.1 prints out the values of enum names.
TYPE
LISTING 18.1
Defining enum Data Types
1: /* 18L01.c: Defining enum data types */
2: #include
3: /* main() function */
4: main()
5: {
6: enum language {human=100,
7: animal=50,
8: computer};
9: enum days{SUN,
10: MON,
11: TUE,
12: WED,
13: THU,
14: FRI,
15: SAT};
16:
18
17: printf(“human: %d, animal: %d, computer: %d\n”,
18: human, animal, computer);
19: printf(“SUN: %d\n”, SUN);
20: printf(“MON: %d\n”, MON);
21: printf(“TUE: %d\n”, TUE);
22: printf(“WED: %d\n”, WED);
23: printf(“THU: %d\n”, THU);
24: printf(“FRI: %d\n”, FRI);
25: printf(“SAT: %d\n”, SAT);
26:
27: return 0;
28: }
The following output is shown on the screen after the executable file, 18L01.exe, of the program in Listing 18.1 is created and executed on my computer:
human: 100, animal: 50, computer: 51
OUTPUT
SUN: 0
MON: 1
TUE: 2
WED: 3
THU: 4
FRI: 5
SAT: 6
23 067231861x CH18 1/25/00 10:31 AM Page 298
298
Hour 18
The purpose of the program in Listing 18.1 is to show you the default values
ANALYSIS
of the enum names, as well as the values assigned to some enum names by the programmer.
As you can tell, there are two enum declarations, in lines 6–8 and lines 9–15, respectively.
Note that the variable lists in the two enum declarations are omitted because there is no need for the variable lists in the program.
The first declaration has a tag name called language and three enumerated names, human, animal, and computer. In addition, human is assigned the value of 100; animal is initialized with 50. According to the enum definition, the default value of computer is the value of animal increased by 1. Therefore, in this case, the default value of computer is 51.
The output made by the statement in line 17 shows that the values of human, animal, and computer are indeed 100, 50, and 51.
The second enum declaration in the program contains seven items with their default values. Then, lines 19–25 print out these default values one at a time. It is not surprising to see that the values represented by the enumerated names, SUN, MON, TUE, WED, THU, FRI, and SAT, are 0, 1, 2, 3, 4, 5, and 6, respectively.
Now, let’s look at another example, shown in Listing 18.2, which demonstrates how to use the enum data type.
TYPE
LISTING 18.2
Using the enum Data Type
1: /* 18L02.c: Using the enum data type */
2: #include
3: /* main() function */
4: main()
5: {
6: enum units{penny = 1,
7: nickel = 5,
8: dime = 10,
9: quarter = 25,
10: dollar = 100};
11: int money_units[5] = {
12: dollar,
13: quarter,
14: dime,
15: nickel,
16: penny};
17: char *unit_name[5] = {
18: “dollar(s)”,
19: “quarter(s)”,
23 067231861x CH18 1/25/00 10:31 AM Page 299
Using Special Data Types and Functions
299
20: “dime(s)”,
21: “nickel(s)”,
22: “penny(s)”};
23: int cent, tmp, i;
24:
25: printf(“Enter a monetary value in cents:\n”);
26: scanf(“%d”, ¢); /* get input from the user */
27: printf(“Which is equivalent to:\n”);
28: tmp = 0;
29: for (i=0; i<5; i++){
30: tmp = cent / money_units[i];
31: cent -= tmp * money_units[i];
32: if (tmp)
33: printf(“%d %s “, tmp, unit_name[i]);
34: }
35: printf(“\n”);
36: return 0;
37: }
While the executable file (18L02.exe) is being executed, I enter 141 (for 141 cents) and obtain the following output on the screen:
Enter a monetary value in cents:
OUTPUT
18
141
Which is equivalent to:
1 dollar(s) 1 quarter(s) 1 dime(s) 1 nickel(s) 1 penny(s)
The purpose of the program in Listing 18.2 is to use the enum data type to repre-ANALYSIS sent the value of the amount of money entered by the user.
Inside the main() function, an enum declaration with a tag name of units is made in lines 6–10. The numbers assigned to the enumerated names are based on their ratios to the unit of cent. For instance, one dollar is equal to 100 cents. Therefore, the enum name dollar is assigned the value of 100.
After the enum declaration, an int array, called money_units, is declared, and is initialized with the enumerated names from the enum declaration. According to the definition of the enum data type, the declaration of the money_units array in the program is actually equivalent to the following one:
int money_units[5] = {
100,
25,
10,
5,
1};
So now you see that you can use enumerated names, instead of integer numbers, to make up other expressions or declarations in your program.
23 067231861x CH18 1/25/00 10:31 AM Page 300
300
Hour 18
In lines 17–22, an array of pointers, unit_name, is declared and initialized. (The usage of arrays of pointers was introduced in Hour 16, “Applying Pointers.”)
Then, the statement in line 15 asks the user to enter an integer number in the unit of cent.
The scanf() call in line 26 stores the number entered by the user to an int variable called cent.
The for loop in lines 29–34 divides the entered number and represents it in a dollar-quarter-dime-nickel-penny format.
Note that the integer constants represented by the enumerated names are used in lines 30
and 31, through the money_units array. If the value of a unit is not 0, a corresponding string pointed to by the array of pointers, unit_name, is printed out in line 33. Therefore, when I enter 141 (in unit of cent), I see its equivalent in the output: 1 dollar(s) 1
quarter(s) 1 dime(s) 1 nickel(s) 1 penny(s).
Making
typedef
Definitions
You can create your own names for data types with the help of the typedef keyword in C, and make those name synonyms for the data types. Then, you can use the name synonyms, instead of the data types themselves, in your programs. Often, the name synonyms defined by typedef can make your program more readable.
For instance, you can declare TWO_BYTE as a synonym for the int data type: typedef int TWO_BYTE;
Then, you can start to use TWO_BYTE to declare integer variables like this: TWO_BYTE i, j;
which is equivalent to
int i, j;
Remember that a typedef definition must be made before the synonym created in the definition is used in any declarations in your program.
Why Use
typedef
?
There are several advantages to using typedef definitions. First, you can consolidate complex data types into a single word and then use the word in variable declarations in your program. In this way, you don’t need to type a complex declaration over and over, which helps to avoid typing errors.
23 067231861x CH18 1/25/00 10:31 AM Page 301
Using Special Data Types and Functions
301
The second advantage is that you just need to update a typedef definition, which fixes every use of that typedef definition if the data type is changed in the future.
typedef is so useful, in fact, that there is a header file called stddef.h included in the ANSI-standard C that contains a dozen typedef definitions. For instance, size_t is a typedef for the value returned by the sizeof operator.
The program shown in Listing 18.3 is an example of using typedef definitions.
TYPE
LISTING 18.3
Using typedef Definitions
1: /* 18L03.c: Using typedef definitions */
2: #include
3: #include
4: #include
5:
6: enum constants{ITEM_NUM = 3,
7: DELT=’a’-’A’};
8: typedef char *STRING[ITEM_NUM];
9: typedef char *PTR_STR;
10: typedef char CHAR;
11: typedef int INTEGER;
12:
18
13: void Convert2Upper(PTR_STR str1, PTR_STR str2);
14:
15: main()
16: {
17: STRING str;
18: STRING moon = {“Whatever we wear”,
19: “we become beautiful”,
20: “moon viewing!”};
21: INTEGER i;
22: INTEGER term = 0;
23:
24: for (i=0; i
25: str[i] = malloc((strlen(moon[i])+1) * sizeof(CHAR));
26: if (str[i] == NULL){
27: printf(“malloc() failed.\n”);
28: term = 1;
29: i = ITEM_NUM; /* break the for loop */
30: }
31: Convert2Upper(moon[i], str[i]);
32: printf(“%s\n”, moon[i]);
33: }
34: for (i=0; i
35: printf(“\n%s”, str[i]);
continues
23 067231861x CH18 1/25/00 10:31 AM Page 302
302
Hour 18
LISTING 18.3
continued
36: free (str[i]);
37: }
38: printf(“\n”);
39: return term;
40: }
41: /* function definition */
42: void Convert2Upper(PTR_STR str1, PTR_STR str2)
43: {
44: INTEGER i;
45:
46: for (i=0; str1[i]; i++){
47: if ((str1[i] >= ‘a’) &&
48: (str1[i] <= ‘z’))
49: str2[i] = str1[i] - DELT;
50: else
51: str2[i] = str1[i];
52: }
53: str2[i] = ‘\0’; /* add null character */
54: }
I have the following output displayed on the screen after running the executable file, 18L03.exe, of the program in Listing 18.3:
Whatever we wear
OUTPUT
we become beautiful
moon viewing!
WHATEVER WE WEAR
WE BECOME BEAUTIFUL
MOON VIEWING!
The purpose of the program in Listing 18.3 is to show you how to create your
ANALYSIS
own names for data types such as char and int. The program in Listing 18.3
converts all characters in a Japanese haiku into their uppercase counterparts.
In lines 3 and 4, two more header files, stdlib.h and string.h, are included for the malloc(), and strlen()functions that are invoked later in the program.
An enum declaration is made in lines 6 and 7 with two enumerated name, ITEM_NUM and DELT. ITEM_NUM is assigned the value of 3 because there are three strings in the haiku.
DELT contains the value of the difference between a lowercase character and its uppercase counterpart in the ASCII code. In line 7, the values of ‘a’ and ‘A’ are used to calculate the difference. In lines 8–11, I define the names STRING, PTR_STR, CHAR, and INTEGER, for a char array of pointers with three elements, a char pointer, a char, and an int data type, respectively, so that I can use these names as synonyms to these data types in the program.