Read Sams Teach Yourself C in 24 Hours Online
Authors: Tony. Zhang
. . .
data_type nameN: lengthN;
} variable_list;
Here the struct keyword is used to start the declaration. tag_name is the tag name of the struct data type. data_type, which must be either int, unsigned int, or signed int, specifies the data type of the bit fields. name1, name2, and nameN are names of bit fields.
length1, length2, and lengthN indicate the lengths of bit fields, specified in bits. The length of any one bit field may not exceed the length of the int data type.
variable_list contains the variable names of the bit field.
For instance, the following statement defines a structure called jumpers with three bit field members:
struct bf {
int jumper1: 1;
int jumper2: 2;
int jumper3: 3;
} jumpers;
Here jumper1, jumper2, and jumper3 are the three bit fields with lengths of 1 bit, 2 bits, and 3 bits, respectively. Figure 20.3 demonstrates the memory allocations of the 3 bit
20
fields.
1 bit
2 bits
3 bits
10 bits
FIGURE 20.3
The memory alloca-
jumper1
jumper2
jumper3
unused
tions of
jumper1
,
jumper2
, and
jumper3
in a 16-bit
int
.
26 067231861x CH20 1/25/00 11:00 AM Page 348
348
Hour 20
The program in Listing 20.6 is an example of using the bit fields defined with struct. In fact, the program in Listing 20.6 is a modified version of the program in Listing 20.5.
TYPE
LISTING 20.6
Applying Bit Fields
1: /* 20L06.c: Applying bit fields */
2: #include
3: #include
4:
5: struct bit_field {
6: int cable: 1;
7: int dish: 1;
8: };
9:
10: struct survey {
11: char name[20];
12: struct bit_field c_d;
13: int age;
14: int hour_per_week;
15: union {
16: char cable_company[16];
17: char dish_company[16];
18: } provider;
19: };
20:
21: void DataEnter(struct survey *s);
22: void DataDisplay(struct survey *s);
23:
24: main(void)
25: {
26: struct survey tv;
27:
28: DataEnter(&tv);
29: DataDisplay(&tv);
30:
31: return 0;
32: }
33: /* function definition */
34: void DataEnter(struct survey *ptr)
35: {
36: char is_yes[4];
37:
38: printf(“Are you using cable at home? (Yes or No)\n”);
39: gets(is_yes);
40: if ((is_yes[0] == ‘Y’) ||
41: (is_yes[0] == ‘y’)){
42: printf(“Enter the cable company name:\n”);
43: gets(ptr->provider.cable_company);
26 067231861x CH20 1/25/00 11:00 AM Page 349
Understanding Unions
349
44: ptr->c_d.cable = 1;
45: ptr->c_d.dish = 0;
46: } else {
47: printf(“Are you using a satellite dish? (Yes or No)\n”);
48: gets(is_yes);
49: if ((is_yes[0] == ‘Y’) ||
50: (is_yes[0] == ‘y’)){
51: printf(“Enter the satellite dish company name:\n”);
52: gets(ptr->provider.dish_company);
53: ptr->c_d.cable = 0;
54: ptr->c_d.dish = 1;
55: } else {
56: ptr->c_d.cable = 0;
57: ptr->c_d.dish = 0;
58: }
59: }
60: printf(“Please enter your name:\n”);
61: gets(ptr->name);
62: printf(“Your age:\n”);
63: scanf(“%d”, &ptr->age);
64: printf(“How many hours you spend on watching TV per week:\n”);
65: scanf(“%d”, &ptr->hour_per_week);
66: }
67: /* function definition */
68: void DataDisplay(struct survey *ptr)
69: {
70: printf(“\nHere’s what you’ve entered:\n”);
71: printf(“Name: %s\n”, ptr->name);
72: printf(“Age: %d\n”, ptr->age);
73: printf(“Hour per week: %d\n”, ptr->hour_per_week);
74: if (ptr->c_d.cable && !ptr->c_d.dish)
75: printf(“Your cable company is: %s\n”,
76: ptr->provider.cable_company);
77: else if (!ptr->c_d.cable && ptr->c_d.dish)
78: printf(“Your satellite dish company is: %s\n”,
79: ptr->provider.dish_company);
80: else
81: printf(“You don’t have cable or a satellite dish.\n”);
82: printf(“\nThanks and Bye!\n”);
20
83: }
Because the program in Listing 20.6 is basically the same as the one in Listing 20.5, I have the same output shown on the screen after I run the executable 20L06.exe and enter the same answers to the survey:
Are you using cable at home? (Yes or No)
OUTPUT
No
Are you using a satellite dish? (Yes or No)
26 067231861x CH20 1/25/00 11:00 AM Page 350
350
Hour 20
Yes
Enter the satellite dish company name:
ABCD company
Please enter your name:
Tony Zhang
Your age:
30
How many hours you spend on watching TV per week:
8
Here’s what you’ve entered:
Name: Tony Zhang
Age: 30
Hour per week: 8
Your satellite dish company is: ABCD company
Thanks and Bye!
[ic:analysis]The purpose of the program in Listing 20.6 is to show you how to declare bit fields and how to use them. As you can see in lines 5–8, two bit fields, cable and dish, are declared with the struct data type. Each of the bit fields is 1 bit long. Then a structure called c_d is defined with the two bit fields in line 12, which is within another structure declaration from line 10 to line 19.
The bit fields cable and dish are used as flags to indicate whether the user is using cable or a satellite dish based on the answers made by the user. If the user has cable, the cable bit field is set to 1 and the dish bit field is set to 0. (See lines 44 and 45.) On the other hand, if the user has a satellite dish, dish is set to 1 and cable is set to 0, as shown in lines 53 and 54. If, however, the user has neither cable nor a satellite dish, both cable and dish are set to 0 in lines 56 and 57.
So you see, you’ve used the combinations of the two bit fields, cable and dish, to represent the three situations: having cable, having a satellite dish, or having neither cable nor a satellite dish.
Because the program in Listing 20.6 is basically the same as the one in Listing 20.5, I get the same output after I run the executable program of Listing 20.6 and enter the same information as I did to the executable 20L05.exe.
Summary
In this hour you’ve learned the following very important concepts about unions in C:
• A union is a block of memory that is used to hold data items of different types.
26 067231861x CH20 1/25/00 11:00 AM Page 351
Understanding Unions
351
• A union is similar to a structure, except that data items saved in the union are overlaid in order to share the same starting memory location.
• The size of a union is at least the size of the size of the largest member in the union.
• The union keyword is used to specify the union data type in a union declaration or a union variable definition.
• To reference a union member, you can use either a dot operator (.) to separate the union name and the union member name or an arrow operator (->) to separate the name of a pointer that points to the union and the union member name.
• The ANSI C standard allows you to initialize a union by assigning the first union member a value.
• You can access the same memory location with different union members.
• To make a structure flexible, you can nest a union inside a structure so that the structure can hold different types of values.
• You can define bit fields, which can be a single bit or any number of bits up to the number of bits in an integer, by using the struct data type.
In the next hour you’ll learn how to read from and write to disk files.
Q&A
Q What are the differences between a union and a structure?
A
Basically, the difference between a union and a structure is that the members in a union are overlaid and they share the same starting memory location, whereas the members in a structure have their own memory locations. Like a structure, you reference a union’s members by using one of its member names.
Q What will happen if you initialize all members of a union together?
A
The value that is assigned to a union member last will be the value that stays in the
20
memory storage of the union until the next assignment to the union. In ANSI C, you can initialize a union by initializing its first member.
Q How do you reference a union member?
A
If the name of a union is used to reference the union members, the dot operator (.) can be used in between the union name and the name of a union member. If it is a pointer which points to a union, the arrow operator (->) can be used between the pointer name and the name of a union member.
26 067231861x CH20 1/25/00 11:00 AM Page 352
352
Hour 20
Q Can you access the same memory location with different union members?
A
Yes. Because all union members in a union share the same memory location, you can access the memory location with different union members. For example, in the program in Listing 20.4, two character constants are assigned to a union memory storage through one of the union members, and then the two characters saved at the memory location of the union are printed out with the help of another union member.
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. Of the following two statements, which one is the declaration of a union and which one is the definition of union variables?
union a_union {
int x;
char y;
};
union a_union x, y;
2. What’s wrong with the following union declaration?
union automobile {
int year;
char model[8]
float weight;
}
3. In the following statement, what are the values contained by the two union members?
union u {
int date;
char year;
} a_union = {1997};
26 067231861x CH20 1/25/00 11:00 AM Page 353
Understanding Unions
353
Exercises
1. Rewrite the program in Listing 20.1 by switching the order between the statement in line 15 and the statement in line 17. What do you get after running the rewritten program? Why?
2. Rewrite the program in Listing 20.2. This time, print out values held by all the members in the info union each time one of the members is assigned a value.
3. Write a program to ask the user to enter his or her name. Then ask the user whether he or she is a U.S. citizen. If the answer is Yes, ask the user to enter the name of the state where he or she comes from. Otherwise, ask the user to enter the name of the country he or she comes from. (You’re required to use a union in your program.)
4. Modify the program you wrote in Exercise 3. Add a bit field and use it as a flag. If the user is a U.S. citizen, set the bit field to 1. Otherwise, set the bit field to 0. Print out the user’s name and the name of country or state by checking the value of the bit field.
20
26 067231861x CH20 1/25/00 11:00 AM Page 354
27 067231861x CH21 1/25/00 11:09 AM Page 355
HOUR 21
Reading and Writing
with Files
I can only assume that a “Do Not File” document is filed in a “Do Not
File” file.
—F. Church
In Hour 5, “Handling Standard Input and Output,” you learned how to read and write characters through standard input or output. In this lesson you’ll learn to read data from and write data to disk files. The following topics are discussed in this lesson:
• Files and streams
• Opening a file with fopen()
• Closing a file with fclose()
• The fgetc() and fputc() functions
• The fgets() and fputs() functions
• The fread() and fwrite() functions
• The feof() function
27 067231861x CH21 1/25/00 11:09 AM Page 356
356
Hour 21