บทที่ 11 ข้อมูลแบบโครงสร้างและยูเนียน

สพฐ 1untitled-41 e0b89ee0b8a3e0b8b0e0b981e0b8aae0b887e0b8a7e0b8b4e0b897e0b8a2e0b8b21 google

การสร้างชนิดข้อมูล ก่อนจะศึกษาชนิดข้อมูลแบบโครงสร้างและยูเนียนนั้น จะต้องรู้จักคำสั่งในการสร้างชนิดข้อมูลก่อน เพราะข้อมูลแบบโครงสร้างและยูเนียน จะใช้คำสั่งนี้สร้างขึ้นมา นั่นก็คือ typedef ผู้ใช้จะสามารถสร้างข้อมูลใหม่จากขนิดข้อมูลพื้นฐานที่มีอยู่เดิมแล้ว โดยรูปแบบคำสั่งของ typedef ดังนี้ รูปแบบ   Typedef [ชนิดข้อมูล] [ชื่อชนิดข้อมูลใหม่]ตัวอย่างข้างล่างนี้เป็นการสร้างและใช้ชนิดข้อมูลนั้นๆ
typedef char*STRING;
STRING stringPtrAry[20];
ตัวอย่างด้านบน ในบรรทัดแรก แสดงการสร้างชนิดข้อมูลขึ้นมาใหม่หนึ่งตัว ให้เป็นชนิดข้อมูล STRING และบรรทัดที่ 2 เป็นการประกาศตัวแปรที่ชื่อ stringPtrAry โดยให้มีชนิดข้อมูลเป็น STRING และมีขนาดเป็น 20 ซึ่งตัวแปรที่ชื่อ stringPtrAry ก็จะมีลักษณะเหมือนกับสตริงที่ศึกษากันในบทที่ผ่านมา ข้อมูลแบบโครงสร้าง                ชนิดข้อมูลแบบโครงสร้าง (Structrue) คือ การรวมตัวแปร ที่มีชนิดข้อมูลหลายแบบมารวมกันให้เป็นโครงสร้างเดียวกัน แล้วโครงสร้างนั้นก็จะมีชื่อประจำตัวของโครงสร้างนั้นด้วยแต่ละตัวแปรในโครงสร้าง จะเรียกว่าสมาชิก ซึ่งในหนึ่งโครงสร้างนั้นสามารถมีตัวแปรหรือสมาชิกได้ไม่จำกัด และแต่ละสมาชิกมีหน่วยความจำของตัวเอง
ในรูปที่ 11-1 มีอยู่ 2 ตัวอย่าง ตัวอย่างแรกเป็นโครงสร้างชื่อ fraction ซึ่งจะมีสมาชิก 23 สมาชิก และตัวอย่างที่ 2 จะเป็นโครงสร้างที่ชื่อ student ซึ่งจะมีสมาชิก 3 สมาชิก
105

การสร้างและกำหนดลักษณะของโครงสร้าง
การสร้างข้อมูลแบบโครงสร้างสามารถทำได้ 2 แบบ คือการสร้างตัวแปรเป็นโครงสร้างและการสร้างโครงสร้างเป็นชนิดข้อมูลใหม่
การสร้างตัวแปรเป็นโครงสร้าง การสร้างตัวแปรเป็นโครงสร้าง จะมีรูปแบบดังนี้
struct { [รายชื่อสมาชิก] } [ชื่อของโครงสร้าง];
ตัวอย่างด้านล่างนี้ เป็นตัวอย่างโครงสร้างที่ชื่อ student ซึ่งภายในของโครงสร้างนี้จะมีสมาชิกดังนี้ id,name และ gradePoints
Struct
{
char id[10];
char name[26];
int gradePoints;
}student;การสร้างโครงสร้างเป็นชนิดข้อมูลใหม่ การสร้างโครงสร้างเป็นชนิดข้อมูลใหม่ ซึ่งโดยการใช้โครงสร้างจะนิยมใช้แบบนี้ เพราะโครงสร้างที่สร้างขึ้น จะเป็นชนิดข้อมูลใหม่อีกชนิดหนึ่งซี่งสามารถนำสร้างตัวแปรได้ โดยมีรูปแบบดังนี้
Typedef struct { [รายชื่อสมาชิก ]} [ชื่อชนิดข้อมูลใหม่];
ตัวอย่างด้านล่างนี้ เป็นตัวอย่างตัวแปรแบบโครงสร้างที่ชื่อ STUDENT ภายในของโครงสร้างจะมีสมาชิก id,name และ gradePoints พร้อมกับสร้างตัวแปร aStudent ให้มีโครงสร้างตามโครงสร้าง STUDENT และการส่งค่าโดยให้มีพารามิเตอร์มีชนิดข้อมูลเป็น STUDENT ด้วย
Typedef struct
{
char id[10];
char name[26];x
}STUDENT;
STUDENT aStudent;
Void printStudent (STUDENT Stu);การกำหนดค่าเริ่มต้น 
              
ผู้ใช้สามารถกำหนดค่าเริ่มต้นให้กับโครงสร้างได้ ในรูปที่ 11-2 แสดง 2 ตัวอย่างของการกำหนดค่าเริ่มต้นให้กับโครงสร้าง ตัวอย่างแรกเป็นการกำหนดค่าให้กับแต่ละสมาชิก ส่วนตัวอย่างที่ 2 เป็นการกำหนดค่าให้บางสมาชิกของโครงสร้าง โดยค่าที่จะกำหนดให้จะเก็บลงในสมาชิก เรียงตามลำดับของโครงสร้างที่สร้างไว้ แต่ถ้าเป็นการกำหนดค่าบางสมาชิก ในสมาชิกที่ ไม่ได้ถูกกำหนดจะมีค่าเป็นค่ามาตรฐานของชนิดข้อมูลนั้น โดยที่ถ้าสมาชิกนั้นเป็นชนิดข้อมูลแบบ integer และ float จะมีค่าเป็น 0 และถ้าเป็น character และ string จะเป็น ‘’

106
รูปที่ 11-2 การกำหนดค่าเริ่มต้นให้กับโครงสร้างการเข้าถึงโครงสร้าง       
        
หลังจากที่สร้างโครงสร้างได้แล้ว ต่อมาก็ศึกษาการเข้าถึงสมาชิกแต่ละตัวในโครงสร้างที่สร้างขึ้น ซึ่งผู้ใช้สามารถที่จะเข้าถึงและกระทำต่อสมาชิกภายในโครงสร้างได้ โดยตัวอย่างการเข้าเข้าถึงสมาชิแต่ละสมาชิกในโครงสร้าง Student ได้แสดงตัวอย่างด้านล่างนี้
aStudent.id
aStudent.name
aStudent.gradePointsในรูปที่ 11-13 เป็นการเรียกใช้สมาชิกแต่ละสมาชิกของโครงสร้าง SAMPLE ในรูปที่ 11-2

 107 108 109

7
3
0.0

110       x                                   y                     t                  u

Sam 2

รูปที่ 11-3 การเรียกใช้สมาชิกแต่ละสมาชิกในโครงสร้าง SAMPLEผู้ให้สามารถใช้คำสั่งเงื่อนไขเพื่อหาค่าได้ โดยมีเงื่อนไขอยู่ว่า ถ้าค่าใน u มีค่าเท่ากับ A ให้นำค่าสมาชิก x มาบวกกับสมาชิก y แล้วเก็บค่าไว้ในสมาชิก x โดยชุดคำสั่ง ได้แสดงข้างล่าง
If (sam2.u=’A’)
Sam2.x + =sam2.y;และผู้ใช้ยังสามารถที่จะรับค่าจากคีย์บอร์ดเข้าสู่สมาชิกต่างๆ ในโครงสร้าง ในตัวอย่างจะใช้คำสั่ง sanf รับค่าเข้าสู่สมาชิกแต่ละตัวในตัวแปร sam1 ที่มีชนิดเป็นโครงสร้าง student
scanf(“%d %d %f %c”,
&sam1.x,&samt.y,%sum1.t,&sum1.y);โปรแกรมที่ 11-1 เป็นโปรแกรมที่ใช้คูณ 2 fractions และพิมพ์ค่าออกมา

     #include<stdio.h>
#include<conio.h>
typedet struct
{
clrscr();
int numerators;
int denominator;
} FRACTION;
int main(void)
{
FRACTION fr1;
FRACTION fr2;
FRACTION res;
printf(“Write the first fraction in the form of x/y:”);
scanf(“%d/%d”, &fr1.numerator, &fr1.denominator);
printf(“Write second fraction in the form of x/y:”);
scanf(“%d /%d”,&fr2.numerator, &fr2.denominator);
res.numerator = fr1.numerator * fr2.numerator;
res.denominator= fr1.denominator * fr2.denominator;
printf(“\The result of %d/%d* %d/%d is %d/%d”;
fr1.numerator,fr1.denominator;
fr2.numerator,fr2.denominator;
res.numertor,res.denominator);
getch();
return 0;
}
ผลลัพธ์ที่ได้ :
Write the first fraction in the form of x/y: 2/6
Write second fraction in th from of x/y: 7/4
The result of 2/6*7/4 is 14/24

ถ้าผู้ใช้มีตัวแปรโครงสร้างที่มีโครงสร้างเหมือนกัน ผู้ใช้สามารถที่จะคัดลอกข้อมูลจากตัวแปรหนึ่งไปไว้ในอีกตัวแปรหนึ่งได้โดยใช้เครื่องหมาย = ในรูปที่ 11-4 แสดงการคัดลอกข้อมูลจาก sam1 ไปไว้ใน sam2

ก่อน
2 5 3.2 A
x y t u
7 3 0.0 R

X        Y         t          u

            Sam2                                                 sam1
Sam2=sam1;
2 5 3.2 A

X    y      t       u

2 5 3.2 A

X        y         t        u

Sam2                                             sam1

หลัง

รูปที่ 11-4 แสดงการคัดลอกโครงสร้างพอยเตอร์ของโครงสร้าง
ผู้ใช้สามารถใช้พอยเตอร์กับโครงสร้างได้เหมือนกัน ซึ่งในรูปที่ 11-5 แสดงการใช้พอยเตอร์กับโครงสร้าง

111
รูปที่ 11-5 แสดงการใช้พอยเตอร์กับโครงสร้าง ซึ่งในขั้นตอนแรกจะต้องสร้างพอยเตอร์ ให้มีโครงสร้างตามโครงสร้างของตัวแปรที่ต้องการก่อนSAMPLE *ptr;
จากนั้นก็กำหนดให้พอยเตอร์ตัวนั้นชี้ไปยังตัวแปรโครงสร้างที่ต้องการ
ptr=&sam1;
และเมื่อต้องการใช้สมาชิกต่างๆในโครงสร้างที่พอยเตอร์ชี้ไปก็สามารถทำได้ดังนี้
(*ptr).x              (*ptr).y          (*ptr).t           (*ptr).uที่ต้องใช้วงเล็บ เพราะเครื่องหมายวงเล็บมีลำดับความสำคัญมากกว่าเครื่องหมายจุดและถ้าไม่ใส่วงเล็บความหมายของตัวแปรจะเปลี่ยนไปอีกแบบหนึ่งดังแสดงในรูปที่ 11-6

112
รูปที่ 11-6 แสดงการใช้พอยเตอร์แบบที่ถูกและแบบที่ผิด
การใช้พอยเตอร์กับโครงสร้างนั้น จะมีวิธีใช้อีกแบบนอกจากวิธีแบบนอกจากวิธีที่ผ่านทมาแล้ว โดยวิธีที่ผ่านมาแล้วเรียกว่า Indirection (ตัวอย่าง (*ptr).x) แล้วยังมีอีกวิธีหนึ่งคือ Selection โดยวิธีนี้จะใช้เครื่อง -> แสดงในรูปที่ 11-7
113
รูปที่ 11-7 แสดงการใช้พอยเตอร์โดยวิธี Selectionในโปรแกรมที่ 11-2 เป็นโปรแกรมจำลองการทำงานของนาฬิกา ซึ่งมีโครงสร้างอยู่ 1 ตัวโดยมี 3 สมาชิก คือ ชั่วโมง, นาที และวินาที และมี 2 ฟังก์ชั่น ฟังก์ชั่นแรกคือ ฟังก์ชั่น increment เป็นตัวคำนวณเวลา และฟังก์ชั่นที่ 2 คือ ฟังก์ชั่น show เป็นที่ใช้แสดงเวลาออกมา
โปรแกรมที่ 11-2 โปรแกรมจำลองการทำงานของนาฬึกาโดยใช้พอยเตอร์

include<stdio.h>
include<conio.h>
typedet struct
{
clrscr();
int hr;
int min;
int ser;
}CLOCK;
void increment(CLOCK*clock);
void show(CLOCK* clock);int main (void)
{
CLOCK clock={14,38,56};
int i;
for(i=o; i<o;++)
{
increment (&clock);
show (&clock);
}
return 0;
{
void increment (CLOCK*clock)
{
(clock->sec)++;
if(clock->min)++;
{
clock->min=0;
(clock->hr)++;
if(clock->hr==24)
clock->hr=0;
}
}
}
void show(CLCOCK* clock)
}
printf(“%02d:%02d:%2d:\n
clock->hr,clock->min,clock-<sec”);
getch();
return;
}
ผลลัพธ์ที่ได้:
14:38:57
14:38:58
14:38:59
14:39:00
14:39:01
14:39:02

โครงสร้างซ้อนโครงสร้างผู้ใช้สามารถที่สร้างโครงสร้างให้มีสมาชิกภายในเป็นโครงสร้าง และสมาชิกที่เป็นโครงสร้างก็สามารถมีได้ไม่จำกัดจำนวน
ตัวอย่าง สมมุติต้องการมีโครงสร้างที่ชื่อ stamp โดยต้องการจะเก็บ date และ time ไว้ภายใน date จะต้องเก็บ month,day และ year ส่วน hour,minute และ second ซึ่งโครงสร้างของ stamp แสดงในรูปที่ 11-8
114
รูปที่ 11-8 แสดงโครงสร้างซ้อนโครงสร้าง การประกาศโครงสร้างซ้อนโครงสร้าง
การประกาศโครงสร้างซ้อนโครงสร้างนั้น โดยจะใช้โครงสร้างจากรูปที่ 11-8 มาสร้างซึ่งสามารถทำได้ดังนี้
typedet struct
{
int month;
int day;
int year;
}DATE;
typedef struct
{
int hour;
int min;
int sec;
} TIME
typedef struct
{
DATE date;
TIME time;
}STAMP;
STAMP stamp;การเข้าถึงโครงสร้างซ้อนโครงสร้าง                เมื่อใดที่ผู้ใช้ต้องการจะเข้าถึงสมาชิกในโครงสร้าง จะต้องเรียกเข้าจากระดับสูงสุดไล่ลงไปยังจุดต่ำสุด ซึ่งตัวอย่างด้านล่างเป็นการเข้าโครงสร้าง  stamp
stamp
stamp.date
stamp.date.month
stamp.date.day
stamp.date.year
stamp.time
stamp.time.hour
stamp.time.min
stamp.time.secการกำหนดค่าเริ่มต้นโครงสร้างซ้อนโครงสร้างการกำหนดค่าเริ่มต้นให้กับโครงสร้างซ้อนโครงสร้าง จะมีกฎอยู่ว่า โครงสร้างที่อยู่ภายในโครงสร้างหลักจะต้องกำหนดค่าอยู่ในวงเล็บปีกกา และสมาชิกภายในโครงสร้างนั้นจะต้องคั่นด้วยเครื่องหมายลูกน้ำเท่านั้น ถ้าในโครงสร้างหลักมีสมาชิกข้างในเป็นโครงสร้างหลายสมาชิกจะต้องคั่นระหว่างสมาชิกด้วยเครื่องหมายลูกน้ำด้วย ดังเช่นตัวอย่างด้านลางเป็นกำหนดค่าเริ่มต้นให้กับโครงสร้าง stamp
STAMP     stamo={{05,10,1936},{23,45<00}};โครงสร้างที่มีอาร์เรย์เป็นส่วนสมาชิกการประกาศโครงสร้างที่มีอาร์เรย์เป็นสมาชิก                โครงสร้างสามารถมีอาร์เรย์เป็นสมาชิกได้ โดยการประกาศนั้นก็เหมือนกับการประกาศอาร์เรย์ทั่วไป สามารถดูได้ในรูปที่ 11-9
การเข้าถึงอาร์เรย์ในโครงสร้างนั้น ก็สามารถทำได้กับสมาชิกที่มีชนิดข้อมูลแบบต่างๆแต่อาร์เรย์จะต้องมีลำดับหรือ Index ด้วย ตัวอย่างในถัดไปเป็นการเข้าถึงสมาชิกที่เป็นอาร์เรย์ในรูปที่ 11-9
student
student.name
student.name[i]
student.midterm
student.midterm[i]
student.final

120
รูปที่ 11-9 แสดงการประกาศอาร์เรย์ในโครงสร้าง ข้อมูลแบบยูเนียน                ข้อมูลแบบยูเนียน (Union)  เป็นข้อมูลที่มีลักษณะคล้ายกับข้อมูลแบบโครงสร้าง แต่ตัวแปรหรือสมาชิกต่างๆ ในยูเนียนนั้น จะใช้หน่วยความจำเดียวกัน คือจะมีตัวแปรหรือสมาชิกใดสมาชิกหนึ่งเท่านั้นที่ใช้หน่วยความจำในช่วงเวลานั้น
121
รูปที่ 11-10 แสดงการประกาศและลักษณะของยูเนียน
โปรแกรมที่ 11-3 แสดงการใช้ SH_CH2  เพื่อแสดงค่าของ 1 ตัวเลขและ 2 ตัวอักษรซึ่งจะแสดงให้เห็นถึงผลกระทบของการใช้งานยูเนียนที่ว่า สมาชิกทั้งหมดจะใช้หน่วยความจำที่เดียวกัน โปรแกรมที่ 11-3 แสดงผลกระทบของการใช้ยูเนียน

#include<stdio.h>
#include<conio.h>
typedef union
{
clrscr();
short num;
char chAry[2];
}SH_CH2;
int main(viod)
{
SH_CH data;
data.num=16706;
printf(“Short: %hd\m”,data.num);
printf(“Ch[0]: %c\n”,data.chAry[0]);
printf(“Ch[1]: %c\n”,data.chAry[1]);
getch();
return 0;
}
      ผลลัพธ์ที่ได้:
Short : 115
Ch[0] : A
Ch[1] : B

การเข้าถึงยูเนียน
ในการเข้าข้อมูลแบบยูเนียนนั้นก็จะเหมือนกับการเข้าถึงข้อมูลแบบโครงสร้าง โดยตัวอย่างด้านล่างจะเป็นการเข้าถึงยูเนียน SH_CH2 ในรูปที่ 11-10
data.num
data.chAr7y[0]

Design by Pratya |

ใส่ความเห็น