មេរៀនទី៩: ទម្រង់ Struct Keyword

មេរៀនទី៩: ទម្រង់ទិន្នន័យជាមួយនឹង  Struct Keyword

មកដល់ពេលនេះ  អ្នកប្រាកដជាបានដឹងយ៉ាងច្បាស់ ហើយអំពីរ បៀបប្រកាសអថេរ  សំរាប់ផ្ទុកគ្រប់ប្រភេទទិន្នន័យ ដូចជាប្រភេទ ចំនួនគត់ (Integer) ចំនួនទសភាគ (Floating -point) និងប្រភេទ តួអក្សរ ជាដើម  (Character)។ មនិតែប៉ុណ្ណោះអ្នកកប៏ានដឹងអពំវី ិធ បីងេត្កស៊េរីនៃចំនួនទាំងនោះ  (Array) និងស៊េរីនៃ Pointer  ដែល ចង្អុលទៅកាន់ទីតាំងណាមួយ  នៃ  Memory   ដែលមានផ្ទុក ទិន្នន័យ ប្រភេទណាមួយដែលយើងចង់បាន។   ឧបមាថាអ្នកត្រូវការ  សរសេរ កមμវិធីមួយសំរាប់គ្រប់គ្រងពត៌មានរបស់បុគ្គលិកក្រុមហ៊ុន “ក”    ហើយពត៌មានដែល                                                        អ្នកត្រូវការកត់ត្រាពី បុគ្គលិក នោះរួមមានដូចជា ឈេμាះ អត្ដលេខ ក្នុងក្រុមហ៊ុនថៃែ្ង ខឆា្ន កំេំ ណតីអាសយដ្ឋានស្នាក់នៅបច្ចុប្បន្នជាដើម   ដែលក្នុងនោះអ្នកបានឃើញថាមានពត៌មានខ្លះមាន ប្រភេទជា   String  និងខ្លះទៀតជាតំលៃលេខ។  ជាការពិតណាស់  ពេលនេះដើម្បី រក្សាទុក  ទិន្នន័យរបស់ បុគ្គលិក  ទាំងនោះ  គឺអ្នកអាចបង្កើត Array សំរាប់ប្រភេទទិន្នន័យនីមួយៗ និង  រក្សាទុកពតម៌ានទាំងនោះ បាន យ៉ាងងាយ ក៏ប៉ុន្ដែធ្វើតាមលក្ខណៈនេះគឺមានភាពចង្អៀតចង្អល់ ណាស់ ពីព្រោះវាមិនបានអនុញ្ញាត អោយអ្នកអាច ចូលទៅដល់ការ ពិនិត្យ មើល ពត៌មានអំពី អាសយដ្ឋានស្នាក់នៅរបស់បុគ្គលិកឈេμាះ “សម” ឬក៏ពត៌មានអំពីថ្ងៃខែឆ្នាំកំណើតរបស់  កញា្ញ ឈេμាះ  “គ”   បានដោយងាយស្រួលនោះទេ  គឺត្រូវការអានពីគ្រប់ Array ដែល មានទំនាក់ទំនងជាមួយពត៌មានដែលយើងត្រូវការ ជាមួយនឹងលេខ លំដាប់  (Index) ណាមួយយ៉ាងត្រឹម ត្រូវ។  ក៏ប៉ុន្ដែ, ក្នុងភាសា C  បានអនុញ្ញាតអោយយើងមានលទ្ធភាពអាចធ្វើការ ជាមួយទំរង់ ការងារ ប្រភេទនេះដោយវិធីមួយផ្សេងទៀតដែលមានលក្ខណៈប្រសើជាងការប្រើ Array ដូច ដែលបានរៀបរាប់ មុននេះ  នោះគឺការរៀបចំទំរង់ទិន្នន័យ ថμីមួយ ដោយពាក្យគន្លឹះ struct។

 I. Definition Structure យើងបានស្គាល់បណ្ដាទិន្នន័យ មានទំរង់ ខ្លះៗដូចជា Array, ដែលមានបណ្ដាធាតុ មានប្រភេទទិន្នន័យដូចគ្នា ។ Ex:  int x[100]; ប៉ុន្ដែបើយើងចង់បង្កើតទិន្នន័យមានទំរង់,  ដែល បណ្ដា ធាតុរបស់វាមានប្រភេទខុសគ្នានោះយើងត្រូវ Declaration វាជាទិន្នន័យប្រភេទ struct ។ ហើយអាចហៅទិន្នន័យប្រភេទ struct ថា record ក៏បាន ។

II.   Declaration Struct: ទិន្នន័យប្រភេទ structure ត្រូវ Declaration ដោយ Keyword struct, បន្ទាប់មកជាបណ្ដា

field របស់ struct ។

Ex1: Address រួមមាន លេខផ្ទះ, ឈេμាះផ្លូវ, ទីក្រុង,  ដូច្នេះយើងអាច Declaration Address ជាមួយ

keyword struct ដូចខាងក្រោម ៖

struct Address

{     int home,

char street[20];

char city[15];

}     A, B;

ឬម្យ៉ាងទៀតមិនបាច់មានឈ្នោះរបស់ ; struct ទេ, គឺ Declaration ដោយផ្ទាល ់បណ្ដា Variable A, B

ដូចខាងក្រោម ៖

struct   /* No Name */

{    int home; char street [20]; char city[15];

}    A, B;

Note: ដូច្នេះយើងមាន field បីគឺ Home, Street, City ដែលមាន ប្រភេទទិន្នន័យផ្សេងៗគ្នា ហើយមានទំនាក់ ទំនងជាមួយគ្នា បង្កើតបាន Address . ក្រោយមកយើង Declaration Variable A, B ជា struct .

ª យើងអាច Declaration struct និង Variable ដាក់ផ្សេងពីគ្នាបាន ។

struct Address

{    int home;

char street[20];

char city[15];

};

Declaration Variable :

struct Address A, B;

Ex2: ដើម្បី Declaration រយៈពេល DATE យើងមាន 3field: ថ្ងៃ, ខែ, ឆ្នាំ ។

struct Date  {

unsigned char day; unsigned char month; unsigned int year;

}  date1, deta2;

ឬ struct Date date1, date2

ដោយថ្ងៃ, ខែ, ឆ្នាំ គ្នាចំនួនអវិជ្ជមាន ដូច្នេះយើង Declaration ជា unsigned  ។

Ex3: Declaration   ប្រវត្ដិរូបរបស់បុគ្គលិកម្នាក់រួមមាន ៖ ឈេμាះ,  ថ្ងៃខែឆ្នាំកំណើត, អាស័យដ្ឋាន,

ប្រាក់ខែ … struct Date  {

unsigned char day; unsigned char month; unsigned int year;

};

struct people { char dat;

struct Date Dob;

unsigned char sex;          /*girl = 0, boy = 1*/

struct Address addre;

float salary;

} peopleA, peopleB;

–     ក្នុង Ex3, យើងសង្កេតឃើញថា Declaration struct ក្នុង struct ។

–     បើចង់តាងតំលៃអោយធាតុ Name យើងសរសេរ ៖

peopleA.Name = “Dara”;

–     បើចង់តាងតំលៃអោយធាតុ City គឺសរសេរ ៖

peopleA.Address.City = “Phnom Penh”;

III. Access to ធាតុរបស់ struct:

ជាមួយ Declaration :

struct Address

{     int home;

char street[20];

char city[15];

} A, B;

យើងអាច Access ទៅធាតុរបស់ struct ដូចខាងក្រោមៈ

A.home = 118; A.street = “sihanu”;

A.city  = “Phnom Penh”;

ឬប្រើក្នុង Function:

printf (“Enter Name Street:”); gets (A.street);

 IV.  Declaration Array of struct:

យើងអាច declaration array of struct ដើម្បីផ្ទុកទិន្នន័យបានច្រើន

Ex:  struct people a[100];

ជាការ  declaration  Array    100,  a  មានប្រភេទជា  people  ។  ក៏ដូចជាបណ្ដា  array

ផ្សេងទៀតដែរ,array of struct ក៏ត្រូវមាន index ចាប់ពីលេខ 0 ទៅដែរ ។

ពិនិត្យឧទាហរណ៍ខាងក្រោមៈ

Ex:5    date

{ char Name[80];

int day;

int month;

int year;

}

static struct date dateofbirth [ ] = {     “Data”, 10, 3, 1970,

“Bopha”, 22, 4, 1968,

“Vanna”, 11, 11, 1950 };

ឬ static struct date dateofbirth[5];

deteofbirth[2].Name = “Vanna”;

 V. ឧទាហរណ៍អនុវត្ដន៍ ៖

ឧទាហរណ៍ខាងក្រោមនេះអនុវត្ដន៍នូវអ្វីៗដែលយើងបានរៀនកន្លងមកដូចជា array,        struct, function…

# include <stdio.h>

# include <conio.h>

# define MAX 100 struct Address  {

char  name[30];

int   homenumber;

char  street [20];

char  city[15];

}  addr[MAX];

void  init_list (void);

void  enter (void);

int  menu_select (void);

void  delete1 (void);

void  list (void);

int  find_free (void);

main ( )

{ char choice;

init_list ( );            /* create array of struct */

for (, ,)                   /* loop have no condition */

{ choice = menu_select ( );

switch (choice)

{case  1: enter( ); break;

case  2: delete1 ( ); break;

case  3: list ( ); break;

case  4: exit (0);

}

}    }

function init_list ដើម្បីបង្កេតី

តំលៃរបស់ array Address ។
/* create list of Address */

void init_list (void)

{ register int t;

for (t = 0 ; t < MAX ; ++t)

addr[t].name[0] = ‘\0’;

}

/* create menu selete*/

int  menu_select (void)

{ char s[80] ;

int c ;

printf (“1. Enter Name \n”); printf (“2. Delete Name \n”); printf (“3. List Name \n “); printf (“4. Exit \n”);

do {

printf (“\n Please select your choose:”);

gets(s);

c = atoi(s);

} while (c< 0 || c > 4);

return (c);

}

/*Enter Address into list */

void  enter (void)

{     int slot ;

char s[80] ;

/* find free space in array for access */

slot = find_free ( );

if (slot = = -1)  {

printf (“\n list is full !”);

return ;

}

printf (“Name :”); fflush(stdin); gets (addr[solt].name);

printf (“Home Number :”);

scanf (“%d”, &addr[solt].homenmber)

while (gecthar ( )!=’\n’;

prinft (“Name street :”); gets(addr[solt].street);

printf(“ City 🙂 ; fflush(stdin); gets(addr[slot].city);

}

/*find free space */

int find_free (void)

{  register int t;

for(t = 0;addr[t].name[0] && t<MAX;t++)

if (t = =MAX) return (-1);  /*No free space*/

return(t);

}

ចំណាំ ៖  យើងប្រើតំលៃ –1 ដើម្បីប្រាប់ថាអស់ space ។  តំលៃ1 ជាតំលៃដែល array មិន ប្រើប្រាស់ជា Index

/*Delete*/

void delete1 (void)

{  register int slot;

char s[80];

printf (“´Number of Record # :”); gets(s);

slot = atoi (s);

if (solt >= 0&& slot <MAX)

addr[slot-1].name[0]= ‘\0’;

}

/* Display Data On Screen */

void list (void)

{  register int t;

for (t = 0; t <MAX ; ++t)

{ if (addr[t].name[0])

{  printf (“%s \n”, addr[t].name);

printf (“%d \n”, addr[t].homenumber);

printf (“%s \n, addr[t].street);

printf (“%s \n, addr[t].city);

}

}

printf (“\n\n”);

}

ក្នុង function enter( ), យើងឈើញថា

scanf (“%d”, &addr[slot].homenumber);

while (getchar( ) !=’\n’);

ពេលយើង Read ផ្ទះលេខ, យើងត្រូវប្រើសញ្ញា Address & ដើម្បី Read ។ ចំនុចមួយទៀត យើងត្រូវប្រើ statement while (getchar( ) !=’\n’); ដើម្បីរំលងសញ្ញា Enter ហើយយើងចុះដើមបន្ទាត់ថីμ ។  បើគμាន  statement  នេះ,  នោះ  statement  Read  ម្ដងទៀតនឹងខុស។ បើយើងលុប statement while (gechar( ) !\n’); នោះពេលយើង Read ឈេμាះ street នឹងគμានអ្វីទាំងអស់។

VI. បញ្ផូល  parameter ក្រោមរៀង  struct ទៅអោយ  function :

ពេលបញ្ផូល   parameter   ប្រភេទ   struct   ទៅ   function,   យើងអាចបញ្ផូនបណ្ដា  filed

នីមួយៗរបស់ struct ទៅអោយ struct ។ ឧទាហរណ៏ ខាងក្រោមនឹងអធិប្បាយពីបញ្ឌានេះ។

struct toto

{  char x; int y; float z;

char s[10];

}tata;

 field នីមួយៗរបស់ struct នឹងត្រូវបញ្ផូនទៅអោយ function ដូចខាងក្រោម :

func1 (tata.x);

func2 (tata.y);

func3 (tata.s);            /*បញ្ផូន Address របស់ string s*/

func4 (tata.s[2]);   /*បញ្ផូន value character */

/* យើងអាចបញ្ផូន Address របស់បណ្ទា field ទៅអោយ function  */

func1 (&tata.x);

func2 (&tata.y);

func3 (tata.s)            /*បញ្ផូន Address របស់ string*/

func4 (&tata.s[2]);              /*បញ្ផូន character*/

+ បញ្ផូន parameter ជា struct : Ex7:

#include <stdio.h>

struct type_toto {

int a, b;

};

void f1 (struct type_toto parm);

main ( )

{  struct type_toto arg;

arg. a= 1000;

f1 (arg);

}

void f1 (struct type_toto parm)

{  printf(“%d”, parm.a);

}

VII. Pointer of stuct :

ក្នុងCអនុញ្ញាតិអោយប្រើ Pointer point to struct បាន។

Ex:

struct bal  {

char name[80] ;

} person ;

strcut bal *p;

គឺជា Declaration pointer ប្រភេទ bal (struct),. តែមិនទាន់មាន Address ជាក់ស្ដែងទេ ។ យើងតាង

p = &person ;

ពេលនេះ p ផ្ទុក Address  ជាមួយធាតុរបស់ struct តាមរយៈ pointer point to វានេះ, យើងប្រើប្រាស់ operator ដែលមានសញ្ញា Æ។ ឧបមានចង់ point to field balance,យើងត្រូវសរសេរៈ p Æbalance; Note: ចំពោះការ Access ជាមួយធាតុរបស់ struct តាមរយៈ pointer នោះយើងប្រើសញ្ញា Æ ។

ចំពាះ access ជាមួយធាតុរបស់ struct តាមរយៈ variable ធមμតានោះយើងប្រើសញ្ញា (.) ។

Ex8:  អធិប្បាយពីនាឡិការ  ៖

# include <stdio.h>

# define DELAY 128000 struct my_time     {  int hours;

int minutes; int seconds; int hunds;

};

void display (struct my_time *t); void update (struct my_time *t); void delay (void);

main ( )

{    struct my_time  systime ;

systime.hours = 0;    systime.minutes = 0;

systime.seconds = 0; systime.hunds = 0; textmode(C40); textbackground(1); textcolor(14);clrscr ();

for (; 😉                           /* loop have no condition */

{ update (&systime);

display (&systime);

}

return 0;

}

void display (struct my_time  *t)

{gotoxy(18, 12 ); cprintf (“%02d :”, tÆhours);

gotoxy(21,12);  cprintf (“%02d :”, tÆminutes);

gotoxy(24,12) ; cprintf (“%02d :”, tÆseconds);

gotoxy(27,12);  cprintf (“%02d ”, tÆhunds);

}

void update (struct my_time *t)

{    tÆhunds ++;

if (tÆhunds = = 100)

{  tÆhunds = 0;

t Æseconds ++;

}

if (tÆseconds = = 60)

{  tÆseconds = 0;

t Æminutes ++;

}

if ( tÆminutes = =60)

{  tÆminutes = = 0;

tÆhours ++;

}

if ( tÆhours = = 24) tÆhours = 0 ;

delay ();

}

void delay (void)

{    long int t;

for (t = 1; t < DELAY; ++t);

}

Note : លទ្ឋផលដូចខាងក្រោម  ៖

14 : 02 : 55 : 50

–   យើងអាចប្រែប្រួលតំលៃរបស ់ DELAY ដើម្បីកមμវិធីតំណើរការយឺតៗ

–   ក្នុងផ្នែកខាងដើមនៃកមμវិធី,  យើង Déclaration struct my_time តែមិនទាន់មាន   variable

ជាក់ស្ដែងទេ ។ ក្នុងផ្នែក main( ) យើង Declaration systime ដែលមានតំលៃដើម 00: 00:00 ។ មានន័យថា systime, ដំណើរការតែក្នុង main ( ) តែប ៉ុណ្ណោះ ។

–   Function  update  (  )  ធ្វើអោយប្រែប្រួលតាមរយៈពេល និង  function  display  (  )

ប្រើសំរាប់ display result on screen ។ ក្នុង Function ទាំងពីរសុទ្ឋតែមាន parameter ជា pointer  point  to  my_time  ។    In  Function  update()  និង  display(),  ធាតុ នីមួយៗរបស់ systime ត្រូវបាន Access តាមរយៈ pointer ។ ដោយវាអាច update តាមលៃរយៈពេល ។

VIII. union:union បើយើង Declaration variable ច្រើនជា Function នោះវា ប្រើតែ block memory

តែមួយប៉ុណ្ណោះ, ទោះជានៅរយៈពេលខុសគ្នាក៏ដោយ ៖ ឧទាហរណ៍

union table   {    int number; long address; char code;

}; union table a; union table b; union table c;

ដូច្នេះ Declaration ជា union ធ្វេិីអោយមានការសន្សំសំចៃ memory ។

លំហាត់អនុវត្ដន៍

1.1. ចូរសរសេរកមμវីធីអនុវត្ដន៍ខាងក្រោម

a.   Read form Keyboard នូវ Data នៃ array of struct ដែលមានប្រភេទជា point

ដូចខាងក្រោម ៖

struct point {  int num ; float x ; float y ;

}

ចំនួនធាតុនៃ array ត្រូវកំណត ់ដោយ statement # define b.   Display the Result on screen.

1.2.  សរសេរកមμវីធីខាងលើក្រោមរាង Function : Funtion មួយសំរាប់ Read Data, Function

មួយទៀតសំរាប់ Display ។

2.  សំនួរបន្ថែម ៖

union table a;

2.1.  ចូររកចំនុចខុសក្នុង struct ខាងក្រោម ៖

struct parts

{    int partno;

char descript[20];

float price;

char *ptr;

2.2. ធ្វើដូចម្ដេចដើម្បីសំដែងធាតុ partno របស់ parts. struct inven

{    int partno ;

}

/* struct inven parts; */

struct inven parts;

struct inven *ptr = &parts;

a. part.partno b. ptrÆpartno

c. partno d. a និង b

 

2.3.  ចូរបង្កើតឈេμាះមួយអោយ character ទី៣ នៃ variable name របស់ address ។

struct fullname{

struct   addr


char firstname[20];

char lastname[20];

};

{  struct fullname name ;

char address[60];

char city[4];

}

struct fullname

{       char firstname[20];

char lastname[20];

}

struct addr address;

struct addr   *ptr = &address;

a.   address.namefirstname[2];

b.   ptrÆname.firstname[2];

c.  ចំលើយ a, b សុទ្ឋតែត្រូវ

d.  គμានចំលើយត្រឹមត្រូវទេ ។