FizWeb

Porkoláb Zoltán - C programozás 2017.11.20. előadás jegyzet

8. előadás:

//MÉG NÉHÁNY TÍPUSKONSTRUKCIÓ:
// typedef, struct, union, enum;

typedef long distance_t;  // _t konvencio

double sin(double);
double (*fptr)(double) = sin;

double cos(double);
fprt = cos;

//EZEKET: egyszerűbb ha fptr helyére: trigfv típust hozok létre

typedef double (*trigfv_t)(double);
trigfv_t fptr_2;
trigfv_t f(trigfv_t); //ilyet is lehet: pl. inverz függvényekre

//////////////////
enum days {mon, tue, wen, thu, fri, sat, sun};
//ha leírom h mon, az 0-t, sun pedig 6-ot fog jelenteni stb.; ez a default számozás
//ezt használhatom  IF-ben, SWITCH-ben
if(curr_day==mon){...}

//felülírhatom a  számozást:
enum days {mon=1, tue, wed, thr=9, fri, sat=12, sun};

//--> beszédesebb nevek, string használata nélkül; később egyszerűen bővíthető

enum days curr_day; //a curr_day változó a mon, tue... értékeket veheti fel, valójában int

////////////////////

//struct: pl. hallgató adatai --> ne különböző tömbben legyenek
struct student
{
  int id;           //itt deklarációkat írtam, ez egy új típus (így nem foglal memóriát)
  char name[50];
  char neptun[6];
  //...
};

struct student hallgato1; //a többféle adat egy tárterületen van
//értéket adhatok neki
struct student h2;
hallgato1 = h2;

//ha nem szeretném mindig kiírni a struct-ot

typedef struct student student_t;
//VAGY: lehet egy lépéSWITCH-ben
typedef struct
{
  int id;
  char name[50];
  char neptun[6];
  //...
} student_t;


//Mit lehet ezzel csinálni?
    //Python: a class végülis olyan, mint egy C struct és a metódusok
student_t h3;
h3.id = ...;
h3.name[0] = ...;

//Ha C-ben szeretnék "metódust"
void init_student(student_t *p){   //egy ilyen student structra mutató pointer
  p->id = getNewId();               //p-> ugyanaz, mint (*p).id
  ...
}

//ezeket ugyanúgy berakhatom tömbbe...
//amit NEM lehet: egyenlőségvizsgálat

//C++-ban lehet!!
x.initStudent()
//ebben benne van a void fv., a p->id megfelel a magára mutató pointernek: DIS

/////////////////

//union: akkora, mint a legnagyobb member, egy időben csak az egyiket tudja tárolni
// <-> struct: az egyes tagok plusz a gapek EGYSZERREtárolódnak

union number
{
  int i;
  long l;
  double d;
};

//egy baj: az unió csak az utolsónak beírt érték típusát tudja
//ezért pl.

enum numkind{int kind, long kind, double kind};
//egy ilyen numkind változóba beírom h milyen volt a legutóbbit
//de így sok globális változót kéne tárolni

//megoldás }}} eddigiek együtt:

typedef struct num{
  enum type{i_t, l_t, d_t} type;
  union{
    int i;
    long l;
    double d;
  } number;
} number_t;

void addint(number_t *p, int value){
  p -> type = i_t;
  p -> number.i = value;
}

void gettype{ //... stb.
}

//pl. egyetemi polgárok struct, oktató ill. hallgató union --> megy az öröklődás is

//////////////

//Egy gyakorlatias példa --> érdemes megírni otthon!!!


//egyszerűsítés: ne kezdődjön számjeggyel a string, erre: strtol, strtod

//a számokat írjuk vissza először, sorrendben, a szavakat lexikografikusan

//bináris rendezőfa --> rekurzív in fix algoritmussal rendezve írhatjuk ki a számokat
//kell a változótól egy jobbra és balra mutató ptr

#include 
#include 
#include 
#include   //character type

typedef struct INODE
{
  int value;
  INODE *left;
  INODE *right;
}
inode_t;

  //stringnél: karakterre mutató ptr, és malloccal foglalok neki tárhelyet
typedef struct SNODE
{
  char *s;
  SNODE *left;
  SNODE *right;
}
snode_t;

void insertInt(inode_t **ip, int v);  //később megírom


int main()
{
  char b[100];
  inode_t *ip = NULL;
  snode_t *sp = NULL;
  while(fgets(b, 100, stdin))
  {
    if(isnumber(b[0]))   //ehhez kell a ctype.h header
      insertInt(&ip, atoi(b));  //ascii to int
    else
      insertString(&sp, b);
  }
  printInt(ip);
  printString(sp);
  return 0;
}

void insertInt(inode_t **ip, int v)    //ez olyan, mint scanf, a *ip által mutatott értéket szeretném átírni
{
  if(*ip == NULL)
  {
    *ip = (inode_t*)malloc(sizeof(inode_t));
    *ip -> value = v;
    (*ip)->left = (*ip)->right = NULL;
  }
  else
  {
    if((*ip)->value > v)
      insertInt(&(*ip)->left, v);   //rekurzíííív
    else
      insertInt(&(*ip)->right, v);
  }
}

//stringnél: bemásolás strcpy, összehasonlítás strcmp > helyett --> értéke 0, negatív vagy pozitív;   value=malloc(strlen(sp+1))  (??)
//honlapon fent van az intes verzió
void printInt(inode_t, *p) //itt már nem kell átírni p-t!!
{
  if(p!=NULL)   //ez ugyanaz: if(p){};   ez a NULL void *p-vé konvertált nulla, egy makró
  {
    printInt(p->left);
    printf("%d ", p->value);
    printInt(p->right);
  }
}