Moät soá kieán thöùc cô sôû veà laäp trình baèng ngoân ngöõ C

Phaâàn tröôùc | Muïc luïc | Phaâàn sau

XX. Kieåu hôïp (union)

Noäi dung:

 

Kieåu hôïp

Hôïp (union) laø khoái boä nhôù duøng ñeå löu tröõ döõ lieäu vôùi kieåu khaùc nhau. Khaùc vôùi struct, caùc ñoái töôïng döõ lieäu coù theå coù cuøng ñòa chæ vuøng nhôù löu tröõ.

Khai baùo cuõng töông töï nhö struct:

union automobile {
     int year;
     char model[8];
     int engine_power;
     float weight;
};

Ñònh nghóa bieán cuõng töông töï:

union automobile sedan, pick_up, sport_utility;

Toång hôïp:

union automobile {
     int year;
     char model[8];
     int engine_power;
     float weight;
} sedan, pick_up, sport_utility;

Teân tag boû qua neáu ta chæ ñònh nghóa 1 laàn vaø khoâng ñònh nghóa caùc bieán khaùc nöõa.

union {
     int year;
     char model[8];
     int engine_power;
     float weight;
} sedan, pick_up, sport_utility;

Tham chieáu ñeán union

Ta cuõng coù theå duøng (.) hoaëc -> nhö struct.

sedan.year = 1997;
 
Hoaëc
 
union automobile *ptr;
ptr->year = 1997;

Ví duï:

1:  /* Referencing a union */
2:  #include <stdio.h>
3:  #include <string.h>
4:
5:  main(void)
6:  {
7:     union menu {
8:        char name[23];
9:        double price;
10:    } dish;
11:
12:    printf("The content assigned to the union separately:\n");
13:    /* reference name */
14:    strcpy(dish.name, "Sweet and Sour Chicken");
15:    printf("Dish Name: %s\n", dish.name);
16:    /* reference price */
17:    dish.price = 9.95;
18:    printf("Dish Price: %5.2f\n", dish.price);
19:
20:    return 0;
21: }
 
Keát quaû:
The content assigned to the union separately:
Dish Name: Sweet and Sour Chicken
Dish Price: 9.95

Söï khaùc nhau giöõ union vaø struct

Struct löu tröõ cho taát caû caùc phaàn töû phaàn boä nhôù töông öùng. Cho neân ñoä lôùn cuûa moãi struct baèng toång kích thöôùc cuûa caùc phaàn töû trong struct. Khi gaùn giaù trò cho struct, moãi phaàn töû coù giaù trò rieâng ñöôïc löu giöõ moät caùch an toaøn cho ñeán khi coù leänh caäp nhaät soá lieâu môùi. Do ñoù, coù theå gaùn giaù trò, truyeàn giaù trò hoaëc traû laïi giaù trò töø haøm.

Union chæ löu tröõ taïi moãi thôøi ñieåm nhaát ñònh giaù trò cuûa moät phaàn töû. Moïi phaàn töû coù chung nhau ñòa chæ. Cho neân khi taïo union, boä nhôù chæ daønh cho union ñoä lôùn baèng kích thöôùc cuûa phaàn töû coù kích thöôùc lôùn nhaát. Khoâng coù nghóa ghi gaùn giaù trò ñoàng thôøi cho moïi phaàn töû cuûa union, vì giaù trò cuûa phaàn töû sau seõ cheùp choàng leân phaàn töû tröôùc. Cuõng vì theá, khoângù theå gaùn giaù trò, truyeàn giaù trò hoaëc traû laïi giaù trò töø haøm, maø phaûi duøng con troû.

Thöû xem neáu ta muoán gaùn ñoàng thôøi caùc giaù trò cuûa phaàn töû cho union, caùi gì xaõy ra baèng ví duï sau:

Ví duï:

1:  /* Memory sharing in unions */
2:  #include <stdio.h>
3:
4:  main(void)
5:  {
6:     union employee {
7:        int start_year;
8:        int dpt_code;
9:        int id_number;
10:    } info;
11:
12:    /* initialize start_year */
13:    info.start_year = 1997;
14:    /* initialize dpt_code */
15:    info.dpt_code = 8;

16:    /* initialize id */
17:    info.id_number = 1234;
18:
19:    /* display content of union */
20:    printf("Start Year:  %d\n", info.start_year);
21:    printf("Dpt. Code:   %d\n", info.dpt_code);
22:    printf("ID Number:   %d\n", info.id_number);
23:
24:    return 0;
25: }
 
Keát quaû:
 
Start Year:  1234
Dpt. Code:   1234
ID Number:   1234

Ví duï:

1:  /* The size of a union or a structure */
2:  #include <stdio.h>
3:  #include <string.h>
4:
5:  main(void)
6: {
7:    union u {
8:        double x;
9:        int y;
10:    } a_union;
11:
12:    struct s {
13:       double x;
14:       int y;
15:    } a_struct;
16:
17:    printf("The size of double: %d-byte\n",
18:            sizeof(double));
19:    printf("The size of int:    %d-byte\n",
20:            sizeof(int));
21:
22:    printf("The size of a_union:  %d-byte\n",
23:            sizeof(a_union));
24:    printf("The size of a_struct: %d-byte\n",
25:            sizeof(a_struct));
26:
27:    return 0;
28: }
 
Keát quaû:
 
The size of double: 8-byte
The size of int:    2-byte
The size of a_union:  8-byte
The size of a_struct: 10-byte

Söû duïng union

Tham chieáu ñeán cuøng moät vò trí boä nhôù baèng caùc kieåu khaùc nhau

hoaëc

laøm cho caáu truùc ( struct) linh hoaït hôn baèng caùch loàng union nhö phaàn töû vaøo trong structure trong tröôøng hôïp coù nhöõng phaàn töû ( ví duï a,b,c) chæ söû duïng taïi moãi thôøi ñieåm moät caùi (chæ a hoaëc b hoaëc c); neáu khai baùo taát caû trong struct seõ laøm coàng keành boä nhôù, neáu duøng union seõ tieát kieäm ñöôïc.

Ví duï:

1:  /* Using unions */
2:  #include <stdio.h>
3:  #include <string.h>
4:
5:  struct survey {
6:     char name[20];
7:     char c_d_p;
8:     int age;
9:     int hour_per_week;
10:    union {
11:        char cable_company[16];
12:        char dish_company[16];
13:    } provider;
14: };
15:
16: void DataEnter(struct survey *s);
17: void DataDisplay(struct survey *s);
18:
19: main(void)
20: {
21:    struct survey tv;
22:
23:    DataEnter(&tv);
24:    DataDisplay(&tv);
25:
26:    return 0;
27: }
28: /* function definition */
29: void DataEnter(struct survey *ptr)
30: {
31:    char is_yes[4];
32:
33:    printf("Are you using cable at home? (Yes or No)\n");
34:       gets(is_yes);
35:    if ((is_yes[0] == `Y') ||
36:        (is_yes[0] == `y')){
37:       printf("Enter the cable company name:\n");
38:       gets(ptr->provider.cable_company);
39:       ptr->c_d_p = `c';
40:    } else {
41:       printf("Are you using a satellite dish? (Yes or No)\n");
42:          gets(is_yes);
43:       if ((is_yes[0] == `Y') ||
44:           (is_yes[0] == `y')){
45:          printf("Enter the satellite dish company name:\n");
46:          gets(ptr->provider.dish_company);
47:          ptr->c_d_p = `d';

48:       } else {
49:          ptr->c_d_p = `p';
50:       }
51:    }
52:    printf("Please enter your name:\n");
53:       gets(ptr->name);
54:    printf("Your age:\n");
55:       scanf("%d", &ptr->age);
56:    printf("How many hours you spend on watching TV per week:\n");
57:       scanf("%d", &ptr->hour_per_week);
58: }
59: /* function definition */
60: void DataDisplay(struct survey *ptr)
61: {
62:    printf("\nHere's what you've entered:\n");
63:    printf("Name: %s\n", ptr->name);
64:    printf("Age:  %d\n", ptr->age);
65:    printf("Hour per week: %d\n", ptr->hour_per_week);
66:    if (ptr->c_d_p == `c')
67:       printf("Your cable company is: %s\n",
68:          ptr->provider.cable_company);
69:    else if (ptr->c_d_p == `d')
70:       printf("Your satellite dish company is: %s\n",
71:          ptr->provider.dish_company);
72:    else
73:       printf("You don't have cable or a satellite dish.\n");
74:    printf("\nThanks and Bye!\n");
75: }
 
Keát quaû:
 
Are you using cable at home? (Yes or No)
No
Are you using a satellite dish? (Yes or No)
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!

Ñònh nghóa stuct tröôøng bit

struct tag_name {
   data_type name1: length1;
   data_type name2: lenght2;
   . . .
   data_type nameN: lengthN;
} variable_list;

 

C seõ caáp phaùt cho variable_list n byte, baèng toång caùc length chia cho ñoä lôùn 1 byte, neáu dö thi n+1 byte.

Ví duï:
 
struct bf {
   int jumper1: 1;
   int jumper2: 2;
   int jumper3: 3;
} jumpers;

Ví duï:

1:  /* Applying bit fields */
2:  #include <stdio.h>
3:  #include <string.h>
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);
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");
83: }
 
Keát quaû:
 
Are you using cable at home? (Yes or No)
No
Are you using a satellite dish? (Yes or No)
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!

Baøi taäp

  1. Trong ñònh nghóa sau, giaù trò cuûa caùc phaàn töû laø bao nhieâu?
union u {
      int date;
     char year;
} a_union = {1997};
  1. Kích thöôùc cuûa caùc ñoái töôïng sau:
struct s {
     int x;
     char ch[4];
} a_structure;
 
union u {
     int x;
     char ch[4];
} a_union;
  1. Vieát chöông trình yeâu caàu ngöôøi söû duïng cho teân vaøo. Hoûi ngöôøi ñoù coù phaûi laø coâng daân VN hay khoâng. Neáu phaûi thì nhaäp teân tænh vaøo, neáu khoâng phaûi thì nhaäp teân quoác gia vaøo (duøng union).

 

Phaâàn tröôùc | Muïc luïc | Phaâàn sau