C Proqramlaşdırma Dili

Strukt tiplər

Strukt tiplər

İndiyə qədər biz dəyişən elan edərkən, int, double, char, long kimi standart tiplərdən istifadə edirdik. Əlbəttə bu tiplər çox əlverişlidir, lakin çox vaxt məsələnin şərtinə uyğun olaraq, proqramçının özü yaratdığı tiplərdən istifadə etmək lazım gəlir.
Tutaq ki, hər hansı zavodun 100 000 işçisi var. Bizdən tələb olunur ki, bu zavodun işçilərinin məlumatlar bazası proqramını yazaq. Hər bir işçi haqqında onun adı, soyadı, yaşı, maaşı, vəzifəsi barədə məlumatlar qeyd edilməlidir. Bunun üçün yeni struct tipi təyin edək.
Yeni tip təyin etmək üçün sintaksis aşağıdakı kimidir.


struct yeni_tipin_adı {
    tip dey1;
    tip dey2;
    tip dey3;
    .
    .
    tip deyn; };

Məsələmizə uyğun təyin etməli olduğumuz yeni tip belə olar. Gəlin, bu yeni yaradacağımız tipə ishci adını verək.


struct ishci {
    int		yash;
    char	ad[12];	
    char	soyad[20];
    char	vezife[20];
    double	maash; };

Beləliklə, biz yeni ishci tipi təyin etdik. Bu elandan sonra biz proqramımızda bu tipdən adi tiplər kimi, dəyişənlər və ünvan dəyişənləri elan edə bilərik, lakin gərək tipin adından (ishici) əvvəl kompilyatora bu tipi bizim özümüz yaratdığımızı bildirmək üçün struct ifadəsini yerləşdirək.
Məsələn, struct ishci dey1, ishci1, *muhendis, yeni_ishciler[100];
Yuxarıdakı elanda biz ishci tipindən olan dey1 və ishci1 dəyişənləri, muhendis ünvan dəyişəni və 100 elementli yeni_ishciler cərgəsi yaratdıq.
100 000 işçi barəsində məlumat saxlamaq üçün biz yeni yaratdığımız ishci tipindən olan 100 000 elementli cərgədən istifadə edə bilərik.
struct ishci ishciler[100000];
İndi isə, maraqlı məqam. Tutaq ki, int tipindən olan x dəyişənimiz var. (int x;)
Əgər biz bu dəyişənə 4 qiyməti mənimsətmək istəyiriksə, x=4; yazırıq. Bəs strukt tipindən olan dəyişənlərə və ya onların təşkil onlunduqları ayrı-ayrı elementlərə necə qiymət mənimsədək?
strukt tipinin elementlərinə müraciət etmək üçün . və ya -> operatorlarından istifadə olunur. Aşağıdakı kimi:


struct ishci reis;
reis.yash = 50;
strcpy(reis.ad,"Anar"); 

Artıq strukt tipindən istifadə etməklə, proqram tərtibinin vaxtı çatıb.


//prog_8_1.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* yeni_tip adlı struct tipi yaradırıq */

struct yeni_tip{
char ad[20];
int x; };

int main(int argc, char *argv[]){

/* struct yeni_tip-den dey adlı dəyişən elan edirik */

struct yeni_tip dey;

dey.x=50;
memset(dey.ad,0,20);	/* memset (stdlib.h) ad-ın bütün baytlarına 0 qiyməti yazırıq.
                        sətirlərlə işləyərkən bunu etmək vacibdir. */

strcpy(dey.ad,"Əli");

printf("%s,%d\n",dey.ad,dey.x);
return 0;	
}

Nümunə

Proqramı yerinə yetirək.


user@gnu_linux:~/prg# 
user@gnu_linux:~/prg# gcc prog_8_1.c -o prog_8_1
user@gnu_linux:~/prg# 
user@gnu_linux:~/prg# ./prog_8_1
Əli,50
user@gnu_linux:~/prg# 
user@gnu_linux:~/prg#


Strukt tipindən olan ünvan dəyişənləri
Strukt tipindən aşağıdakı kimi ünvan dəyişəni təyin edək:
strukt ishci *muhendis;
Əgər biz strukt tipdən adi yox, ünvan dəyişəni təyin ediriksə, onda strukt tipinin elementlərinə müraciət zamanı . əvəzinə -> istifadə edirik. Misal üçün: muhendis->yash=45; kimi.

Diqqət! Ünvan dəyişənləri üçün yaddaşda yer ayırmadan onların elementlərinə müraciət etmək olmaz.

Paraqraf 4-dən bilirik ki, hər hansı bir tipdən olan ünvan dəyişəninə yaddaşda yer ayırmaq üçün tip *dey;
dey = (tip *) malloc (sizeof(tip));
sintaksisindən istifadə edirik.
Bu sintaksisə əsasən, yuxarıda təyin etdiyimiz muhendis ünvan dəyişəninin elementlərinə qiymət mənimsədə bilmək üçün, əvvəlcə ona yaddaşda aşağıdakı kimi yer ayırmalıyıq.
muhendis = (struct ishci *)malloc(sizeof(struct ishci));
Bu operatordan sonra biz artıq muhendis dəyişəninin istənilən elementinə -> operatoru vasitəsilə müraciət edə bilərik.


muhendis->yash=33;
strcpy(muhendis->ad,"Rüstəm");

Proqram nümunəsi:


//prog_8_2.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* yeni_tip adlı struct tipi yaradırıq */

struct yeni_tip{
char ad[20];
int x; };

int main(int argc, char *argv[]){

struct yeni_tip *dey;

/* malloc yaddaşda yer ayırır, bu yerdə əvvəlcədən başqa məlumatlar ola bilər və bu bizə
gözlənilməyən problemlər yarada bilər. Ona görə, malloc-la yaddaşda yer ayıranda,
onun bütün baytlarını memset-le 0-a mənimsətmək məsləhətdir. */

dey = malloc(sizeof(struct yeni_tip));
memset(dey,0,sizeof(struct yeni_tip));

dey->x=50;
strcpy(dey->ad,"Vəli");

printf("%s,%d\n",dey->ad,dey->x);
return 0;
}

Nümunə

user@gnu_linux:~/prg# 
user@gnu_linux:~/prg# gcc prog_8_2.c -o prog_8_2
user@gnu_linux:~/prg# 
user@gnu_linux:~/prg# ./prog_8_2
Vəli,50
user@gnu_linux:~/prg# 
user@gnu_linux:~/prg#