C Proqramlaşdırma Dili

Makroslar və include fayllar

Makroslar və include fayllar

Biz indiyə kimi proqramlarda #include <stdio.h>, #include <stdlib.h>, #include <string.h> kimi sətirlərdən istifadə etdik və qeyd etdik ki, proqramın mətninə bu sətirlərin əlavə olunması bizə printf, malloc, strcpy kimi funksiyalardan istifadə etməyə imkan verir.
Hər hansı bir funksiyadan proqramda istifadə edə bilmək üçün proqrama bu funksiyanın elanı (adı və parametrlərinin qeyd edildiyi sətir) və mətni (funksiyanın kod hissəsi) verilməlidir.
Biz öz funksiyalarımızı tərtib edərkən, həm elanı, həm də mətni eyni faylda yerləşdirirdik. gcc imkan verir ki, biz ayrı-ayrı fayllarda elan olunmuş funksiya və dəyişənlərə öz proqramımızdan müraciət edə bilək.
Bunun üçün #include direktivindən istifadə edirlər.
#include <fayl.h> və ya #include"fayl.h" kimi.
Bir qayda olaraq, proqrama #include vasitəsilə əlavə olunan faylların sonu .h ilə bitir.

Gəlin, prog_9_2.c proqramında elan etdiyimiz bəzi dəyişənləri və funksiyaları yeni menim_faylim.h faylına köçürək. Bu faylı proqrama əlavə edib yerinə yetirək.

Proqramın yeni versiyası belə olacaq: prog_10_1.c


//prog_10_1.c

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

#include "menim_faylim.h"

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

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

/* İlk ve son elementləri NULL -a mənimsədək */

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

/* Siyahıya obyektlər əlavə edək */

elave_et(syh,"Əli",45);
elave_et(syh,"Samir",37);
elave_et(syh,"Tahir",40);
elave_et(syh,"Rüstəm",43);
elave_et(syh,"Hidayət",55);
elave_et(syh,"Tofiq",38);
elave_et(syh,"İbrahim",24);

/* Siyahının elementlərini çap edək */

cap_et(syh);

return 0;
}

Nümunə

menim_faylim.h faylının mətni:


#ifndef MENIM_FAYLIM_H
#define MENIM_FAYLIM_H


/* struct ishciler adlı siyahı elan edirik */

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

struct ishciler *novb_el;};

/* Çox vaxt siyahının tipini elan etdikdən sonra
   ilk və son elementlərinə istinad edən ünvan dəyişənlərindən
   istifadə edərək, yeni tip yaradırıq. Aşağıdakı kimi: */

struct ishci_syh{
struct ishciler *ilk_el;	/* Siyahının ilk elementinə istinad edən ünvan dəyişəni */
struct ishciler *son_el;	/* Siyahının son elementinə istinad edən ünvan dəyişəni */
};

/* Yeni yaratdığımız tipdən dəyişən (siyahı) elan edək */

struct ishci_syh *syh;

/* elave_et funksiyası */

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 yaratdıq, elementlərinə qiymətlər mənimsətdik.
   İndi obyekti siyahıya əlavə edək. */

/* Burada aşağıdakı qaydadan istifadə edəcəyik.
   Əgər siyahıda obyekt yoxdursa, onda ilk və son element
   yeni yaratdığımız obyektə istinad etməlidir,
   əks halda, obyekti siyahının sonuna artıracağıq.
   Bu cür əlavə etmə məsələnin şərtindən və
   proqramçının istəyindən asılı olur. */
    
/* Yoxlayaq, əgər siyahı boşdursa, onda ilk və son element
   yeni obyektə istinad etsin və dey-in istinadını ləğv edək. */

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

/* Siyahıda artıq obyekt var, yeni obyekti (dey)
   siyahının sonuna əlavə et və dey-in istinadını leğv et. */
    
syh->son_el->novb_el=dey;	/* dey-i siyahının sonuna qoşuruq. */
syh->son_el=dey;		/* son_el-i yeni yerinə (sona) sürüşdürürük. */ 
dey=NULL;			/* dey-in siyahıya istinadını leğv edirik. */ 
}
}


/* cap_et funksiyası */


void cap_et(struct ishci_syh *syh){

struct ishciler *dey;

dey=syh->ilk_el;

printf("Siyahının elementləri\n");

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

#endif

Proqramı kompilyasiya edib, yerinə yetirək.


user@gnu_linux:~/prg# 
user@gnu_linux:~/prg# gcc prog_10_1.c -o prog_10_1
user@gnu_linux:~/prg# 
user@gnu_linux:~/prg# ./prog_10_1
Siyahının elementləri
Əli,45
Samir,37
Tahir,40
Rüstəm,43
Hidayət,55
Tofiq,38
İbrahim,24
user@gnu_linux:~/prg# 
user@gnu_linux:~/prg# 

menim_faylim.h faylındakı 
#ifndef
#define
#endif

makrosları menim_faylim.h faylının bizim proqrama sonsuz əlavə olunmasının qarşısını alır.
Əgər diqqət yetirdinizsə, biz stdio.h faylını < və > vasitəsilə, menim_faylim.h faylını isə, " və " simvolları vasitəsilə proqrama əlavə etdik.
Əgər biz faylı < və > vasitəsilə proqrama əlavə ediriksə, onda gcc həmin faylı /usr/include qovluğunda axtaracaq və bu qovluqda adətən gcc-nin standart faylları olur. stdio.h, string.h və s.
" və " simvollarından istifadə etdikdə isə, gcc həmin faylın bizim tərəfimizdən yaradıldığını bilir və bu faylı bizim proqram yerləşən qovluqda axtarır.
 

Makroslar

C dilində istifadə olunan digər əhəmiyyətli vasitələrdən biri də, makroslardır. Makroslar 2 cür olur: şərt makrosları və təyin makrosları.

Təyin makrosları (#define)
Təyin makrosları hər hansı bir ifadənin başqa ifadə ilə əvəz edilməsinə xidmət edir. Misal üçün, əgər biz proqramın hər hansı yerində #define MAX_QIYMET 1024 sətrini yerləşdiririksə, onda gcc proqramda MAX_QİYMET ifadəsinə rast gəldiyi bütün yerlərdə onu 1024 ilə əvəz edəcək.

Sadə proqrama baxaq.


#define MAX 8

int main(){
int i,x[MAX];

for (i=0, i<=MAX; ++i)
x[i]=i;
return 0;

Bu proqram 9 elementli, tam tipli x cərgəsi elan edir və onun elementlərinə 0-dan 8-ə kimi qiymətlər mənimsədir.

Şərt makrosları
Şərt makrosları bizə imkan verir ki, müəyyən şərtdən asılı olaraq, proqramın hər hansı hissəsinin kompilyator tərəfindən nəzərə alınmamasını təmin edək.
Sintaksis belədir:


#if şərt

    proqram kodu

#endif

Bu zaman, əgər şərt 1 qiyməti alarsa, onda kompilyator proqram kodu hissəsini nəzərə alacaq, əks halda isə, bu hissə kompilyator tərəfindən inkar ediləcək, başqa sözlə, şərh kimi qəbul olunacaq.