HTML

Proghelp

Programozási tutorial-ok és feladat kidolgozások főleg Debreceni Egyetem Mérnök Informatikus hallgatóinak számára!

Friss topikok

Linkblog

C gyors talpaló V. lecke

szimih 2011.03.27. 16:44

Felhasználó által definiált típusok

A tömbök minden eleme azonos típusú kell hogy legyen. Gyakran szükségünk van azonban olyan egymással összetartozó elemek tárolására is, melyek nem azonos típusúak, mégis egy egyedre jellemzők. Ezeket leggyakrabban adatbázisokban találjuk meg. Gondoljunk itt egy személy kereszt és vezetéknevére, születési idejére, alapfizetésére. Ezek különböző típusú adatok mégis ugyanarra a személyre vonatkoznak. C-ben ilyenek a struktúrák. Struktúrában tetszőleges típusú adattagjai lehetnek. ( Pascalban record-nak neveztük)

Struktúrák

   Struktúra felépítése:
      struct név   {
      típus1 tag1;
      típus2 tag2;
      ………….
      }
   
   egy példa:
      struct szemely   {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         }

 

 

Példabeli struktúra tartalmaz egy vnev 20 elemű tömböt, knev 15 elemű tömböt, szev integer típusú változót és egy fizetés nevű float típusú változót.

Ha ilyen típusú változót akarunk létrehozni, akkor annak módja:
struct szemely sz;

Erre a változóra a nevével és a struktúrán belüli tag nevének megadásával hivatkozhatunk a .(pont) operátor segítségével:
sz.vnev=”Kiss”;

tehát az 'sz' változó struktúrán belüli vnev változónak értéket adtunk.

I. Példaprogram:

#include <stdio.h>

struct szemely   {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         };

int main(){
      struct szemely dolgozo;
      
      printf("Dolgozo vezetek neve: ");
      scanf("%s",&dolgozo.vnev);
   
      printf("Dolgozo kereszt neve: ");
      scanf("%s",&dolgozo.knev);
      
      printf("Dolgozo szuletesenek eve: ");
      scanf("%d",&dolgozo.szev);
      
      printf("Dolgozo fizetese: ");
      scanf("%f",&dolgozo.fizetes);
      
      printf("---------------------------------------\n");
      
      printf("%s %s nevu dolgozo %d szuletett es %.1fFt a fizetese.",dolgozo.vnev,dolgozo.knev,dolgozo.szev,dolgozo.fizetes);
}

 

Struktúrákat típusként ( typedef ) is definiálhatjuk. Ilyenkor a struct utáni azonosító el is maradhat, és csak utána kerül a a típust azonosító név:

typedef struct {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         } SZEM;

A létrehozott típusunk nevét a kapcsoz zárójel végére kell írnunk!

II. Példaprogram:

#include <stdio.h>

typedef struct {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         } SZEM;

int main(){
      SZEM dolgozo;
      
      printf("Dolgozo vezetek neve: ");
      scanf("%s",&dolgozo.vnev);
   
      printf("Dolgozo kereszt neve: ");
      scanf("%s",&dolgozo.knev);
      
      printf("Dolgozo szuletesenek eve: ");
      scanf("%d",&dolgozo.szev);
      
      printf("Dolgozo fizetese: ");
      scanf("%f",&dolgozo.fizetes);
      
      printf("---------------------------------------\n");
      
      printf("%s %s nevu dolgozo %d szuletett es %.1fFt a fizetese.",dolgozo.vnev,dolgozo.knev,dolgozo.szev,dolgozo.fizetes);
}

Typedeffel mindkét deklarációs módot használhatjuk:

typedef struct szemely {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         } SZEM;

int main(){
      SZEM dolgozo;
      struct szemely masikdolgozo;
      .
      .
      .
      }

Kezdőértékadás a struktúrának

Mint a tömböknek a struktúráknak is adhatunk kezdőértéket. Az egyes adattagokat a struktúrában megfogalmazott sorrendbe kapcsos zárójelek között vesszővel elválasztva kell megadnunk.

pl.:
struct szemely dolgozo= {"Kiss", "Pista", 1985, 57084.5};

III. Példaprogramunk:

#include <stdio.h>

struct szemely   {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         };

int main(){
      struct szemely dolgozo= {"Kiss", "Pista", 1985, 57084.5};
      
      printf("%s %s nevu dolgozo %d szuletett es %.1fFt a fizetese.",dolgozo.vnev,dolgozo.knev,dolgozo.szev,dolgozo.fizetes);
      }

Egymásba ágyazott struktúrák, avagy struktúra a struktúrába

Az elején említettem, hogy a struktúra bármilyen adattípust tartalmazhat így egy másik struktúrát is.
Például egy síkbeli geometriai objektumot akarunk ábrázolni mint például a kör.

Kör középpontját így tárolnánk:

struct kozep{
               int x;
               int y;
            }

Körnek középpontján kívül még szüksége van sugarának az értékére is:

struct kor{
               struct kozep kp;
               int sugar;
            }

   struct kor kor1 = {{50,75},80}; // kör x=50 y=75 sugara=80
   struct kor kor2;
   
   kor2.kp.x = 45;  // második körünk x koordinátája 45
   kor2.kp.y = 34;  // második körünk y koordinátája 34
   kor2.sugar = 12; // második körünk sugara 12

Struktúrát tartalmazó tömbök

Ha egy struktúra típusú változót létrehoztunk, akkor annak segítségével csak egyetlen egyed jellemzőit tudjuk tárolni. Mit tehetünk, ha több egyedről is ugyanazokat a jellemzőket szeretnénk raktározni? Kézenfekvő megoldás olyan tömbök alkalmazása, melynek minden egyes eleme az adott struktúra típusú.

IV. Példaprogramunk:

#include <stdio.h>

#define DOLGOZO 5

struct szemely   {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         };

int main(){
      struct szemely dolgozo[DOLGOZO], seged;
      int i, j, min;
      
      // adatok beolvasása
      for( i = 0 ; i < DOLGOZO ; i++)
         {
            printf("%d. dolgozo adatai:\n",i+1);
            printf("Dolgozo vezetek neve: ");
            scanf("%s",&dolgozo[i].vnev);
         
            printf("Dolgozo kereszt neve: ");
            scanf("%s",&dolgozo[i].knev);
            
            printf("Dolgozo szuletesenek eve: ");
            scanf("%d",&dolgozo[i].szev);
            
            printf("Dolgozo fizetese: ");
            scanf("%f",&dolgozo[i].fizetes);
            
            printf("--------------------------\n");
         }
      
      printf("\n\n");
      
      // adatok rendezése születésük éve szerint      
      for( i = 0 ; i < DOLGOZO-1 ; i++)
         {
            min = i;
                        
            for( j = i+1 ; j < DOLGOZO ; j++)
               if(dolgozo[min].szev > dolgozo[j].szev)
                  min = j;
                  
            seged = dolgozo[i];
            dolgozo[i] = dolgozo[min];
            dolgozo[min] = seged;
         }
      
      // adatok kiírása
      for( i = 0 ; i < DOLGOZO ; i++)
      printf("%d. %s %s nevu dolgozo %d szuletett es %.1fFt a fizetese.\n",i+1,dolgozo[i].vnev,dolgozo[i].knev,dolgozo[i].szev,dolgozo[i].fizetes);
      
      return 0;      
      }

Példaprogramunk 5 dolgozó adatait kezeli. Először bekérjük az 5 dolgozó adatait, majd rendezzük őket születési évük szerinti növekvő sorrendbe, és végül kiírjuk a képernyőre.

V. Példaprogramunk:

 

#include <stdio.h>

struct szemely   {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         };

int main(){
      struct szemely * dolgozo, seged;
      int i, j, dolgszam, min;
      
      printf("Hany dolgozo adatat akarjabeolvasni?: ");
      scanf("%d", &dolgszam);
      
      dolgozo = (struct szemely *) malloc (sizeof(struct szemely) * dolgszam); // dolgozo = (struct szemely) calloc (dolgszam, sizeof(struct szemely)) ugyan ez calloc függvénnyel
      
      // hely lefoglalásásnak ellenőrzése
      if(!dolgozo)
         {
            printf("Nem sikerult lefoglani a helyet!\n");
            return -1;
         }
      
      // adatok beolvasása
      for( i = 0 ; i < dolgszam ; i++)
         {
            printf("%d. dolgozo adatai:\n",i+1);
            printf("Dolgozo vezetek neve: ");
            scanf("%s",&dolgozo[i]->vnev);
         
            printf("Dolgozo kereszt neve: ");
            scanf("%s",&dolgozo[i]->knev);
            
            printf("Dolgozo szuletesenek eve: ");
            scanf("%d",&dolgozo[i]->szev);
            
            printf("Dolgozo fizetese: ");
            scanf("%f",&dolgozo[i]->fizetes);
            
            printf("--------------------------\n");
         }
      
      printf("\n\n");
      
      // adatok rendezése születésük éve szerint      
      for( i = 0 ; i < dolgszam-1 ; i++)
         {
            min = i;
                        
            for( j = i+1 ; j < DOLGOZO ; j++)
               if(dolgozo[min].szev > dolgozo[j].szev)
                  min = j;
                  
            seged = dolgozo[i];
            dolgozo[i] = dolgozo[min];
            dolgozo[min] = seged;
         }
      
      // adatok kiírása
      for( i = 0 ; i < dolgszam ; i++)
      printf("%d. %s %s nevu dolgozo %d szuletett es %.1fFt a fizetese.\n",i+1,dolgozo[i].vnev,dolgozo[i].knev,dolgozo[i].szev,dolgozo[i].fizetes);
      
      free(dolgozo);
      
      return 0;      
      }

Példaprogramunk ugyan azokat a műveleteket hajtaja végre mint a IV. annyi különbséggel hogy itt dinamikusan foglaljuk le a helyet a dolgozóknak majd fel is szabadítjuk. Mivel dinamikusan foglalunk nekik helyet mi mondjuk meg ekkora legyen a tömbünk.

Önhivatkozó struktúrák:

Gyakran használatos adatstruktúrák például láncolt listák. A láncolt lista nem más mint egy önhivatkozó struktúra.
 

struct szemely   {
         char vnev[20];
         char knev[15];
         int szev;
         float fizetes;
         struct szemely * kovetkezo;
         };

Ezzel az önhivatkozó struktúrával felépíthetünk egy egy irányba láncolt listát. Következő mindig a következő lista elemre fog mutatni vagy NULL vagyis lista vége.
Példák: progpater.blog.hu, prog órákon, struktúra műveletei adatszerk & algoritmus órákon.

4 komment

A bejegyzés trackback címe:

https://proghelp.blog.hu/api/trackback/id/tr912775990

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

nb · http://fersml.blog.hu 2011.03.31. 10:05:49

A struktúrában csak char*-ot tartanék és átírnám (hogy a struktúrával csak címének előállítása és tagjának hozzáférése legyen) hogy a tömbindexek helyett mutatókat használok.

taratata (törölt) 2017.01.12. 15:56:38

a

taratata (törölt) 2017.01.13. 10:14:44

int egy(int tomb[],int n){

int index=tomb[0];
int hely;
int i;
for (i = 0; i < n; i++) {
if(tomb[i]>index) index=tomb[i];
}

int j;
for (j = 0; j < n; j++) {
if(tomb[j]==index)
{
hely=j;
}

}

printf("Legnagyobb elem: %d\n", index);
printf("Hely: %d", hely);

}

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

int t[]={1,4,1,3,15,2,55};
int n=sizeof(t)/sizeof(t[0]);

egy(t,n);

}

taratata (törölt) 2017.01.13. 11:09:34

int db=0;
int i=0;
int tomb[db];
int n=sizeof(tomb)/sizeof(tomb[0]);
int szam;
int sum;

printf("Irjon be szamokat 0 vegjelig");
scanf("%d", &szam);
tomb[i]=szam;
i++;

do{
db++;
printf("Irjon be szamokat 0 vegjelig");
scanf("%d", &szam);
tomb[i]=szam;
i++;

}

while(szam!=0);
int j;
for (j = 0; j < db; j++) {
if(tomb[j]<tomb[j+1])sum++;
printf("%d ", tomb[j]);

}
printf("\ndarab: %d ", sum);
printf("\n");
süti beállítások módosítása