BİLİŞİM - BİLGİSAYAR - EĞİTİM
  Yapılar (Struct)
 

8.   Yapılar (struct):

Farklı tipte birden fazla verinin oluşturduğu bütün.

Veri tipi olarak daha önce diziyi tanımlamıştık. Dizide birbirinin aynı tipi olan veriler peşpeşe saklanıyordu.

Yapılar da aynı dizi gibi birbirleriyle ilgili olan verileri içerir. Fakat diziden farkı, tek bir yapı elemanı birbirnden farklı tipte birden fazla veriyi içerir. Bu sayede bilgiler daha düzenli şekilde gösterilir.

Yapı yeni bir tip olmayıp var olan standart tiplerden oluşur.

 

8.1  Yapı Tanımı:

Bir öğrencinin numarasını, adını ve sınavdan aldığı notu içeren bir yapı tanımlaması aşağıdaki gibidir.

 

struct ogryapi {

                char numarasi[10];

                char adi[20];

                int notu ;

}

struct ogryapi ogr;

 

Artık ogryapi isimli bir veri tipi vardır ve üç  üyeden (alandan) oluşmaktadır ( member =üye : kayıdı oluşturan farklı veri tiplerinin her biri).

 

   * Tanımlamada her alanın adı ve tipi belirtilir.

   * Yapı tipi olduğunu gösterir struct saklı sözcüğü kullanılır.

    * Aynı alan adı farklı yapılarda (bağımsız olarak) kullanılabilir.

 

Tanımlama genel olarak

 

struct Yapı_Adı {

         Alan1;

         Alan2;

               . . .

         Alan_n;

};

 

Bu tipte bir değişken ise

                struct Yapı_Adı Deği_Adı;

şeklinde yapılır.

 

Tanımlanan tipte bir değişken tanımlandığınıda, değişken için bellekte tüm alanları içerecek şekilde yer ayırılır.

İlgili değişkendeki herhangi bir alan üzerinde işlem yapmak için  aralarında nokta karakteri olmak koşuluyla sırasıyla değişkenin adı ve ilgili alanın adı verilir. Yukarıdaki  öğrenci örneğinde öğrecinin numarasına

ogr.numarasi  şeklinde erişilir.

 

Örnek 8.1.1:  Karmaşık sayılarda toplama işlemi gerçekleştirme.

 

main()

{

  struct complex {

    float real, imag;

  };

  struct complex z1, z2, z3;

  clrscr();

  printf("1. sayının reel ve imajiner kısımları gir ");

  scanf("%f %f", &z1.real, &z1.imag);

  printf("2. sayının reel ve imajiner kısımları gir ");

  scanf("%f %f", &z2.real, &z2.imag);

  z3.real = z1.real + z2.real;

  z3.imag = z1.imag + z2.imag;

  printf("%2.0f + %2.0fjn",z3.real, z3.imag);

}

 

 

 

 

Örnek 8.1.2: Yapı içerisinde başka bir yapı kullanımı.

 

    struct tarih {

     int   gun;

     int   ay;

     int   yil;

  };

  struct kisiler {

     char adi[21];

     struct tarih  dogum;

  };

main()

{

   struct kisiler  a;

    strcpy(a.adi,"veli");

   a.dogum.gun = 15;

   a.dogum.ay = 8;

   a.dogum.yil = 1905;

   printf("%s %dn",a.adi,a.dogum.yil);

   getch();

}

 

Diğer bir tanımlama şekli

 

struct  {

         Alan1;

         Alan2;

                . . .

         Alan_n;

} değişkenler;

    struct {

    float real, imag;

  }z1, z2, z3;

 

Örnek 8.1.3:  Öğrenci ile ilgili olarak numara ve sınav notu oku.  Sınavın ortalamasını ve ortalamayı geçenleri listele

 

#define OGRSAY  3

main()

{

   struct ogrenci{

     char no[10];

     int  notu;

   };

   struct ogrenci ogr[OGRSAY];

   int i, j;

   float t, ort;

   clrscr();

   for (i=0; i<OGRSAY; i++) {

       printf("%d. öğrencinin numarası ve notu : ", i+1);

       scanf("%s%d",ogr[i].no, &ogr[i].notu);

   }

  t = 0;

   for (i=0; i<OGRSAY; i++)

       t = t + ogr[i].notu;

ort = t / OGRSAY;

   printf("--------------------------------------------n");

   printf("Ortalama = %fn", ort);

   printf("--------------------------------------------n");

   printf("Ortalamayı geçen öğrencilern");

   for (i=0; i<OGRSAY; i++)

       if (ogr[i].notu > ort)

          printf("%stt%dn", ogr[i].no, ogr[i].notu);

getch();

}

 

Tanımlama Anında Yapı Değişkenine Değer Atama

struct ogryapi   a = {"95003", 56};

 

Veri Tiplerine Yeni İsim Verme

 

  C dilinde var olan veri tiplerini yeni bir isim vermekmümkündür. Tanımlama biçimi:

typedef tanımlı_tip yeni_ismi;

  typedef int tamsayi;

 

Artık tamsayı isminde bir veri tipi vardır. Değişken tanımlamada kullanılabilir.

tamsayi i, j;

  typedef unsigned char byte;

  byte x;

 

Yapılar ile kullanımı

 

  struct complexyapi {

                float re, im;

  };

  tydef struct complexyapi complex;

  complex z1, z2;

  veya

typedef struct { float re, im } complex;

  complex z;

 

Örnek 8.1.4: İşlevin değerinin yapı olması durumu

 

typedef struct {

  float re, im;

} complex;

  main()

{

  complex topla(complex, complex);

  complex cikart(complex, complex);

  complex carp(complex, complex);

  complex z1={1,1}, z2={2,2};

  complex z3;

  clrscr();

  printf("%3.0f %3.0fj   %3.0f %3.0fjn",z1.re,z1.im,z2.re,z2.im);

  z3 = topla(z1, z2);

  printf("%3.0f  %3.0fn",z3.re,z3.im);

  z3 = cikart(z1, z2);

  printf("%3.0f  %3.0fn",z3.re,z3.im);

  z3 = carp(z1, z2);

  printf("%3.0f  %3.0fn",z3.re,z3.im);

  getch();

}

complex topla(complex a, complex b)

{

 complex z;

 z.re = a.re + b.re;

 z.im = a.im + b.im;

 return z;

}

complex cikart(complex a, complex b)

{

 complex z;

 z.re = a.re - b.re;

 z.im = a.im - b.im;

 return z;

}

complex carp(complex a, complex b)

{

 complex z;

 z.re = a.re * b.re - a.im * b.im;

 z.im = a.re * b.im + a.im * b.re;

 return z;

}

 

Union: Değişken Yapısı

 

Bir yapıdaki üyelerin hepsi aynı durumda kullanılmayabilir. Üyelerin bir bölümü belirli bir durum için geçerli iken ir kısmı farklı bir durum için geçerlidir. Gereksiz yer harcamalarına karşı union tipi kullanılabilir.

Tanımlama biçimi:

 

  union ad {

      tip değişken_1;

      tip değişken_2;

      ...

      tip değişken_n

   };

 

 

 

  Aynı yerde belirtilen alanlardan herhangi biri saklanır. En uzun alan ne ise o kadar yer ayrılır.

 

union ikisi {

    int kisa;

    long uzun;

};

union ikisi i;

main()

{

  i.uzun = 32768;

  printf("%d  %ld n",i.kisa, i.uzun);  {-32768 32768 }

}

 

Union Değişkenin Tanımlama Anında Değer Alması

 

Değişkene tanımlama anında değer atandığında alanlardan ilki kullanılıyor gibi davranır dil. Bu nedenle atanacak değerin tipine dikkat edilmelidir.

 

union sayilar {

int i;

     float f;

  };

  union sayilar a = {2};    /* a.i = 2 anlamındadır */

  union sayilar a = {2.7};    /* a.i = 2 değeri atanır. */

 

Bitler Üzerine Çalışmalar

 

VE , VEYA ve DEĞİL işleçleri mantıksal ifadeleri bağlamakta kullanıldığı gibi doğrudan tamsayılar üzerinde de kullanılabilir. Bu kullanımda işleçler doğrudan tamsayıyı oluşturan bitleri etkiler.

 

 x &  y  : x ve y tamsayılarının bitlerinin sırayla VE işlemine tutar.  (AND)

 x | y      : x ve y tamsayılarının bitlerinin sırayla VEYA işlemine tutar.  (OR)

~ x        : x  tamsayının her bir bitinin tersini alır (NOT)

x ^ y      : x ve y tamsayılarının bitlerinin sırayla dışlayan VEYA işlemine tutar.  (exclusive OR)

x <<  n  : x sayısını n bit sola kaydırır. Boşalan yerlere 0 gelir.

x >> n   : x sayısını n bit sağa kaydırır. Boşalan yerlere 0 gelir.

 

 5   &     3   = 1

 

(101) &  (011) = (001)

          |             = (111) yani 7

5 << 1 = 10 --> (101) shl 1 = (1010)

 

Hex-Octal gösterim

 

0xn : n 16 lıdır (HEXADECIMAL)   0x11 : 17

0n   : n 8 lidir   (OCTAL)                                    011   : 9

n     : n 10 ludur (DECIMAL)                               11 :  11

 

Klavyedeki  tuşların durumunu gösterir bilgi bellekten okunduğunda her bitin anlamı şöyledir.

 

       Bit No

        0        sağ shift basılı/basılı değil

        1        sol shift basılı/basıldı değil

        2        kontrol tuşu basılı/basılı değil

        3        alt tuşu basılı/basılı değil

        4        scroll tuşu açık/kapalı

        5        num lock tuşu açık/kapalı

        6        caps lock tuşu açık/kapalı

 

Bu durumda num lock tuşunun açık olup olmadığını anlamak için okunan bilginin 5. bitinin değerini sınamak gerekecektir. Okunan bilginin x olduğunu varsayr ise;

 

if (x & 32)

    printf("num lock açık");

else

    printf("num lock kapalı");

x & 32 işlemine x değerinin 32 sayısı ile maskelenmesi denir. 32 değeri maske diye çağırılır. 32 sayısının 8 bit olduğunu düşünürsel sayının sadece 5. biti bir olup diğerleri sıfırdır.

32 = (0010 0000)

x & 32 işlemi ile x değerinin 5. bitinin bir olup olmaması sınanır. Bir ise sonuç 32 (farklı sıfır), sıfır ise sonuç 0 olur.

 

 

 

Örnek 8.1.5: Klavyedeki Num Lock tuşunun durumunu söyleyen programı yazınız.

 

#include <dos.h>

main()

{

 unsigned int b1;

 clrscr();

 b1 = peek(0x0040, 0x0017);  /* dos.h> */

 if (b1 & 32)

   printf("Num lock açıkn");

 else

   printf("Num lock kapalın");

 getch();

 

İlgili işlevler

 

                poke (segment, offset, int value)                     X             peek  (segment, offset)

                pokeb (segment, offset, char value)                X             peekb(segment, offset)

 

 Örnek 8.1.6: Öğrencinin doğum tarihi 2 Byte tamsayı olarak saklanmaktadır.

 

         Bu bilginin kodlaması şöyledir.

                   bit       anlamı

                  0 - 4       gün

                  5 - 8       ay

                 9 -15       yıl (+1970)

 

Böyle bir bilgiyi çözen program.

 

#include <dos.h>

main()

{

 unsigned int i;

 clrscr();

 scanf("%d", &i);

 printf("%2d", i&0x1f);

 i = i >> 5;

 printf("/%2d", i&0x1f);

 i = i >> 4;

 printf("/%4d", i+1970);

}

 

Örnek 8.1.7

 

unsigned swap(unsigned) : gönderilen tamsayının düşük ile yüksek sekizlisinin yerini değiştirilmişini  verir

unsigned max(unsigned)   : gönderilen tamsayının düşük sekizlisi ile yüksek sekizlisinden büyüğünü verir

 

main()

{

  unsigned i, j;

i = 0xAA11;

  clrscr();

  printf("%x   %x  %xn", i, swap(i), max(i));

  getch();

}

unsigned swap(unsigned a)

{

 return (a>>8) | (a<<8);

}

unsigned max(unsigned a)

{

  unsigned lo, hi, m;

  lo = a & 0x00FF;

  hi = a >> 8;

  m = (lo>hi) ? lo:hi;

  return m;

}

 

Örnek 8.1.8: Aşağıdaki işlevlerin gerçekleştirilmesi.

 

void binary_yaz(unsigned x); { x tamsayısının 2li düzendeki karşılığını yazar }

unsigned copybits(x, b, n)   { x sayısının sağdan b. bitinden itibaren n bitini verir}

unsigned ters(x, b, n):         { x sayısının sağdan b. bitinden itibaren n bitini tersini alır}

unsigned rdon(x,  n):          { x sayısını n bit sağa döndürür}

/* Programın başlangıcı */

typedef unsigned int word; /* kolaylık i.in */

void binary_yaz(word);

word copybits(word x, word b, word  n);

word ters(word x, word b, word n);

word rdon(word x, word n);

word sdon(word x, word n);

main()

{

  word  i, j;

   clrscr();

  for (i=16; i>0; i--)

      printf("%x", i-1);

  printf("n");

  i = 0xee;

  binary_yaz(i); printf("n");

  j = copybits(i, 5, 4);  binary_yaz(j); printf(" copybits(i, 5, 4) n");

  j = ters(i, 5, 4);  binary_yaz(j); printf(" ters(i, 5, 4)n");

j = rdon(i, 4);  binary_yaz(j); printf(" rdon(i, 4)n");

  getch();

}

word copybits(word x, word b, word  n)

/*  x sayısının sağdan b. bitinden itibaren n bitini verir.  */

/*  ilk bitin numarası 0  */

{

  word i;

  i = x >> (b + 1 - n);   /*  ilgili bit bloğunun sağa dayalı olacak  */

                            /*  biçimde kaydır.                         */

  i = i & ~(~(0) << n);   /*  sağdaki n bit için maske oluştur  */

  return i;

}   /*  End Of copybits  */

word ters(word x, word b, word n)

/*  x'in b. bitinden itibaren n bitin tersini alır  */

{

  word p, r;

  p = ~(x);

  r = ~(~(0) << n) << (b - n + 1);   /*  seçilen bitler için maske */

  p = p & r;

  x = x & ~(r);

 return x | p;

/*

8 bit için ters(. ,5,4)

      76543210

x = 0110 1000

p = 1001 0111  

r =  00111100    ~(~(0) << n) << (b - n + 1)

p = 00010100       p = p & r

x = 0100 0000      x & ~(r)

   = 01010100       x | p  dönen

}   /*  End of test  */

word rdon(word x, word n)

/*  x'i n bit sağa döndürür  */

{

  word i;

  for (i = 1; i <= n; i++)

    {

       if (x % 2 == 1)

          {

            x = x / 2;

            x = x | 0x8000;

          }

       else

          x = x / 2;

    }

  return x;

}   /*  End of rdon  */

word sdon(word x, word n)

/*  x'i n bit sağa kaydırır. RDon fonksiyonun başka biçimi */

{

  word i;

  i = copybits(x,n - 1,n);

  x = x >> n;

  i = i << (16 - n + 1);

  return x | i;

}   /*  End of RDon  */

void binary_yaz(word x)

  int i;

  word m;

  m = 0x8000;

  for (i = 0; i<16; i++) {

      if (x & m)

         printf("1");

      else

        printf("0");

      m = m >> 1;

  }

}

 
 
  Bugün 125 ziyaretçi (187 klik) www.bilisim-egitim.tr.gg  
 
Bu web sitesi ücretsiz olarak Bedava-Sitem.com ile oluşturulmuştur. Siz de kendi web sitenizi kurmak ister misiniz?
Ücretsiz kaydol