free counters

 

statcounter free invisible

Banner

Biz 6-cı mövzuda cərgələr ilə tanış olduq. Misal üçün əgər biz int tipli və 10 elementdən ibarət cərgə yaratmaq istəyiriksə onda int x[9]; yazırıq. Bu zaman yaddaşda hər biri 4 bayt(int) olan 10 yerdən ibarət hissə ayrılır və bu hissənin başlanğıcına x adı ilə müraciət olunur.

Cərgələr çox əlverişlidir və çox istifadə olunur, lakin onların bir mənfi cəhəti var. Onlar statikdirlər, yəni əgər 100 baytlıq struct ishci tipindən olan 1000 elementli mühendisler cərgəsi elan etmişiksə (struct ishci muhendisler[1000];) bu zaman yaddaşda 100*1000 bayt yer ayrılır.

Əgər proqramın icrasının müəyyən nöqtəsində bizim bu cərgəyə ehtiyzcımız yoxdursa onda biz bu yaddaşı azad edə bilmərik. Belə olan hallarda siyahılardan istifadə edirlər. Siyahılar bir tərəfədn ünvan dəyişənləridir, yəni onları proqramın icrası zamanı istənilən vaxt yaradıb, silə bilərik.

Digər tərəfdən isə siyahılar cərgələri xatırladır. Onların hər-bir elementi digər elementlə əlaqəli olduğundan onların hamısına eyni adla müraciət etmək olur. Siyahıların cərgələrdən üstün cəhəti odur ki, siyahılar dinamikdirlər və onlara istənilən sayda element əlavə etmək olar.

Cərgələr ilə isə bu mümkün deyil. Əgər 10 elementli cərgə elan etmiçiksə 11-ci elementi ona heç-bir yolla etmək olmaz.

Siyahıların sintaksisini verməzdən və proqram nümunələri ilə tanış olmazdan əvvəl gəlin siyahıların yaddaşda necə yerləşməsi ilə tanış olaq.

Əgər biz hər-hansı bir tipdən (adi və ya struct) olan adi dəyişən elan etmək istəyiriksə onda
tip deyishenin_adi; sintaksisndən istifadə edirik.
mis : int x;
struct isnci muhendis;

Əgər biz hər-hansı bir tipdən (adi və ya struct) olan ünvan dəyişəni elan etmək istəyiriksə onda
tip *deyishenin_adi; sintaksisndən istifadə edirik.
mis : int *x;
struct isnci *muhendis;

Əgər biz hər-hansı bir tipdən (adi və ya struct) olan cərgə elan etmək istəyiriksə onda
tip deyishenin_adi[elem_sayi]; sintaksisndən istifadə edirik.
mis : int x[10]; struct isnci muhendis[10];

Əgər biz hər-hansı bir tipdən (adi və ya struct) olan siyahı elan etmək isə bir balaca artıq iş tələb edir.

Gəlin bunu konkret misal üzərində izah edək.
ishci tipindən olan muhendisler siyahısını elan edək , daha sonra bu siyahıya bir neçə obyekt əlavə edək.
Verilmiş tipdən siyahı yaratmaq üçün yeni tip yaratmaq(struct) lazımdır.
Baxdığımız məsələ üçün yeni yaradacağımız tipin adı olsun ishci_siyahı.

Sintaksis belə olar:

struct siyahinin_tipinin_adi {

tip1 dey1;
tip2 dey2;
.
.
tipn deyn;

struct siyahinin_tipinin_adi *kecid_deyisheni; }

misal:

struct siyahi1{

char msg[10];
int x;

struct siyahi1 *novb_el;}

Beləliklə biz yeni tip yaratdıq, struct siyahi1; Bu tipdən olan syh ünvan dəyişənini elan edək.

struct siyahi1 *syh; Hal-hazırda yaddaşda vəziyyət aşağıdakı kimidir.

shy - ya yaddaşda yer ayırıb onun elementlərinə qiymətlər mənimsədək.

syh = malloc(sizeof(struct siyahi));
memset(syh,0,sizeof(struct siyahi));
strcpy(syh->ad, "ali");
syh->x=9;
syh->novb_el=NULL;

yaddaşın vəziyyəti:


shekil_9_1

Hal-hazırda siyahımızda 1 element var. siyahıya yeni element əlavə edək . Bunun üçün struct siyahi tipindən olan diger ünvan dəyişəni (dey1) elan edib, elementlərinə qiymətlər mənimsədək. Daha sonra dey1-i syh -ya elave ederik. (əsas məqam)

struct siyahi *dey1;
dey1 = malloc(sizeof(struct siyahi));
memset(dey1,0,sizeof(struct siyahi));
strcpy(dey1->ad, "ali");
dey1->x=9;
dey1->novb_el=NULL;

yaddaşın vəziyyəti:


shekil_9_2

dey1 – I yaratdıq , onu syh-ya elave edək (qoşaq). QEYD: BÜTÜN SİYAHILARA YENİ OBYEKTLƏRİN ƏLAVƏ OLUNMASINDA AŞAĞIDAKI QAYDADAN İSTİFADƏ EDİRLƏR. syh->novbel=dey1; yaddaşa baxaq:


shekil_9_3

Beləliklə biz siyahıya yeni element əlavə etdik. Lakin dey1 ünvan dəyişəni hələ də bizim siyahının son elementinə müraciət edir. Belə saxlamaq olmaz, bu təhlükəlidir. Ünvan dəyişənləri ilə işləyən zaman xüsusilə ehtiyatlı olmaq lazımdır. Bizim siyahıda istifadəçilərin qiymətli məlumatları ola bilər. Əgər ona hansısa ünvan dəyişəni bizim nəzərimizdən uzaq müraciətdədirsə onda bu o deməkdir ki, biz proqramımızda istifadəçi məlumatlarına açıq pəncərə yerləşdirmişik. Pis proqramlaşdırma təcrübəsi!

Gəlin dey1-in syh-ya olan müraciətini ləğv edək. Bunu üçün sadəcə olaraq dey1=NULL; yazmağımız yetər.

Yaddaşın vəziyyəti: Gelin syh-ya daha bir obyekt əlavə edək. dey azad olduğundan ondan istifadə edə bilərik.


dey1 = malloc(sizeof(struct siyahi));
memset(dey1,0,sizeof(struct siyahi));
strcpy(dey1->ad, "veli");
dey1->x=10;
dey1->novb_el=NULL;

obyekti yaratdıq, onu siyahıya əlavə edək. /*yuxarida problem var*/

İndi tutaq ki, siyahıda 10 obyekt var.

Biz istəyirik ki siyahıda olan 3-cü obyektin x elementini çapa verək.

Kod aşağıdakı kimi olacaq.

struct siyahi *dey1;
dey=syh;

Ikinci obyektə sürüşmək üçün yazırıq.

dey1=dey1->novb_el;

Bir addım da sürüşsək onda 3-cü obyektin üstünə düşürük.

dey1=dey1->novb_el;

İndi dey1 siyahıda 3-cü obyektə müraciət edir və biz asanlıqla x elementini çap edə bilərik.

printf("%d\n",dey->x);
Ümumiyyətlə dey1=dey1->novb_el; kodu siyahıda yuxarıdan aşağı hərəkət etmək üçün istifadə olunur. Bu zaman manevr imkanlarını artırmaq üçün siyahının ilk və son elementlərinə istinad edən ünvan dəyişənlərindən istifadə olunur. aşağıdakı kimi:

proqram nümunəsi

prog_9_1.c


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* struct ishciler adli siyahi elan edirik */

struct ishciler{
char ad[20];
int x;

struct ishciler *novb_el;};


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

struct ishciler *muhs,*dey; /*muhendisler*/

muhs = malloc(sizeof(struct ishciler));
memset(muhs,0,sizeof(struct ishciler));

muhs->x=50;
strcpy(muhs->ad,"Veli");

/*kecid elementini NULL -a menimsedirik.
Yaddashda hec bir yere istinad etmesen.*/
muhs->novb_el=NULL;

/*muhs siyahisinda artiq bir obyektimiz
var(shekil_9_1), elave obyektler elave edek */

dey = malloc(sizeof(struct ishciler));
memset(dey,0,sizeof(struct ishciler));
dey->x=60;
strcpy(dey->ad,"Imran");

/*kecid elementini NULL -a menimsedirik.
Yaddashda hec bir yere istinad etmesen.*/

dey->novb_el=NULL;

/*yeni obyekti yaratdiq. shekil_9_2*/

/*yeni yaratdigimiz dey obyektini siyahiya elave edek*/

muhs->novb_el=dey; /* hal-hazirki veziyyet shekil_9_3 - e uygundur*/

/*dey-in siyahiya olan istinadını ləvğ edək.*/

dey=NULL; /*shekil_9_4*/

/*siyahida olan obyektlerin elementlerini cap edek*/

dey=muhs; /*dey siayhinin evveline istinad edir*/

printf("muhs siyahisinda olan elemntler\n");
while(dey!=NULL){
printf("%s,%d\n",dey->ad,dey->x);
dey=dey->novb_el; /*novbeti elemente surushuruk,
eger dey==NULL -sa(siyahinin sonu) onda dovru bitir. */
}

return 0;
}

proqramı yerinə yetirək

user@gnu_linux:~/prg#
user@gnu_linux:~/prg# gcc prog_9_1.c -o prog_9_1
user@gnu_linux:~/prg#
user@gnu_linux:~/prg# ./prog_9_1
muhs siyahisinda olan elemntler
Veli,50
Imran,60
user@gnu_linux:~/prg#
user@gnu_linux:~/prg#

Indi isə gəlin bu proqramın funksiyalardan istifade etdiyimiz halına baxaq.

prog_9_2.c

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

/* struct ishciler adli siyahi elan edirik */

struct ishciler{
char ad[20];
int yash;

struct ishciler *novb_el;};

/* cox vaxt siyahinin tipini elan etdikden sonra
ilk ve son elementlerine istinad eden unvan
deyishenlerinden istifade ederek
yeni tip yaradiriq. ashagidaki kimi:*/

struct ishci_syh{
struct ishciler *ilk_el; /*siyahinin ilk elementine istinad eden unvan deyisheni*/
struct ishciler *son_el; /*siyahinin son elementine istinad eden unvan deyisheni*/
};

/*yeni yaratdigimiz tipden deyishen (siyahi) elan edek*/

struct ishci_syh *syh;

/*indi ise siyahi ile istifade deceyimiz funksiyalari elan edek */

void elave_et(struct ishci_syh *,char *,int ); /*siyahiya yeni element elave etmek ucun*/

void cap_et(struct ishci_syh *); /* siyahinin elementlerini cap etmek ucun*/

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

syh = malloc(sizeof(struct ishci_syh));
memset(syh,0,sizeof(struct ishci_syh));

/*ilk ve son elementleri NULL - a menimsedek*/

syh->ilk_el=NULL;
syh->son_el=NULL;

/*siyahiya obyektler elave edek*/

elave_et(syh,"Ali",45);
elave_et(syh,"Samir",37);
elave_et(syh,"Tahir",40);
elave_et(syh,"Rustam",43);
elave_et(syh,"Hidayet",55);
elave_et(syh,"Tofiq",38);
elave_et(syh,"Ibrahim",24);

/*siyahinin elementlerini cap edek*/

cap_et(syh);

return 0;
}


/* elave_et funksiyasi*/

void elave_et(struct ishci_syh *syh, char *s, int x){

struct ishciler *dey;

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

strcpy(dey->ad,s);
dey->yash=x;
dey->novb_el=NULL;

/*obyekti yaratdiq, elementlerine qiymetler
menimsetdik. Indi obyekti siyahiya elave edek*/

/*burada ashagidaki qaydadan istifade edeceyik.
eger siyahida obyekt yoxdursa ona ilk ve son element
yeni yaratdigimiz obyekte istinad etmelidir,
eks halda obyekti siyahinin sonuna artiracayiq.
bu cur elave etme meslenin shertinden ve
proqramcinin isteyinden asili olur.*/

/*yoxlayaq eger siyahi boshdursa onda ilk ve son element
yeni obyekte istinad etsin ve dey -in istinadini levg edek.*/

if ((syh->ilk_el==NULL)&&(syh->son_el==NULL)){
syh->ilk_el=dey;
syh->son_el=dey;
dey=NULL; }
else{

/*siyahida artiq obyekt var, yeni obyekti (dey)
siyahinin sonuna elave et ve dey-in istinadini legv et.*/

syh->son_el->novb_el=dey; /*dey-i siyahinin sonuna qoshuruq*/
syh->son_el=dey; /*son_el -i yeni yerine (sona) surushdururuk*/
dey=NULL; /*dey -in siyahiya istinadini levg edirirk*/
}
}


/* cap_et funksiyasi*/


void cap_et(struct ishci_syh *syh){

struct ishciler *dey;

dey=syh->ilk_el;

printf("siyahinin elementleri\n");

while(dey!=NULL){
printf("%s,%d\n",dey->ad,dey->yash);
dey=dey->novb_el;
}
}

proqramı yerinə yetirək

user@gnu_linux:~/prg#
user@gnu_linux:~/prg# gcc prog_9_2.c -o prog_9_2
user@gnu_linux:~/prg#
user@gnu_linux:~/prg# ./prog_9_2
siyahinin elementleri
Ali,45
Samir,37
Tahir,40
Rustam,43
Hidayet,55
Tofiq,38
Ibrahim,24
user@gnu_linux:~/prg#
user@gnu_linux:~/prg#

axırıncı dəyişikliklər (18.07.10 20:34)

 

Şərh əlavə et


Təhlükəsizlik şifrəsi
Yenilə

Saytımızda hansı proqram haqda dərslərin olmasını istəyirsiniz?
 
Üzv : 24
Kontent : 1146
Baxılanlar : 511805
 9 qonaq