Kihagyás

11. előadás

A szoftver komponenseknek kiszámítható módon kell kommunikálnia az őt használó többi komponensel. A komponens ezen felületét interfésznek nevezzük.

A kliensek ezen a felületen keresztül érik el a szolgáltatásokat, melyeknek megvalósítása az implementáció.

Példa egy ilyen komponensre:

struct date
{
  int year;
  int month;
  int day;   
};

void f(void)
{
  /* inicializálás, ellenőrzi az egyes mezők értékeit */
  struct date exam = dateCreate(2019, 12, 17);
  dateNext(&exam);          /* egy nappal elhalasztva */
  dateAdd(&exam,40);        /* lekezeli a hónap végét */
}

Interfész definíció (header fájl):

/* date.h */
#ifndef DATE_H
#define DATE_H

#define EOK      0  /* ok                        */
#define ENOMEM   1  /* unable to allocate memory */ 
#define EINVALID 2  /* invalid date              */
#define ENEGDAY  3  /* negative day for dateAdd  */

struct DATE;

typedef struct DATE *date_t; /* forward deklaráció */

extern int dateError;  /* error handling */

date_t dateCreate( int y, int m, int d);
void   dateDestroy(date_t dp);

int    dateSet( date_t dp, int y, int m, int d);
void   dateNext( date_t dp);
int    dateAdd( date_t dp, int n);

int    dateGetYear(date_t dp); 
int    dateGetMonth(date_t dp); 
int    dateGetDay(date_t dp); 
#endif /* DATE_H */

Pointer lett átadva, aminek a mérete majd később lesz deffiniálva.

A függvények megfelelőek így, hiszen a pointer mérete konzisztens, viszont nem alkalmazható rá a pointer arithmetika, mert a típus nem teljes(mérete nem ismert)

Implementáció egy külön fájlba kerül:

/* date.c */
#include <stdio.h>
#include <stdlib.h>

#include "date.h"

struct DATE 
{
  int year;
  int month;
  int day;  
};

/* napok száma az adott hónapban, kiv. szökőév */
static const int dOfm[] = {
  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31                         
                          };
/* y szökőév? */
static int leapYear( int y)
{
  /* TODO implementálni!!! */
  return 0;
}
/* napok tényleges száma az év/hónapban */
static int daysOfMonth( int y, int m)
{
  int maxDay = dOfm[m-1]; /* tömb 0-tól indexelődik */

  if ( 2 == m && leapYear(y) )
    ++maxDay;  /* szökőév */

  return maxDay;  
}
/* helyes dátum-e az (y, m, d) hármas? */
static int checkDate(int y, int m, int d)
{
  return  0 != y  &&
          1 <= m  &&  m <= 12  &&
          1 <= d  &&  d <= daysOfMonth(y, m);  
}

/* interfész: hibakezelés */
int dateError = EOK;

/* interfész függvények */
date_t dateCreate( int y, int m, int d)
{
  date_t dp;

  if ( ! checkDate( y, m, d) )
  {
    dateError = EINVALID;
    return NULL;
  }
  if (NULL == (dp = (date_t) malloc(sizeof(struct DATE)) ))
  {
    dateError = ENOMEM;
    return NULL;
  }

  dp->year  = y;
  dp->month = m;
  dp->day   = d;

  dateError = EOK;
  return dp;
}
void dateDestroy( date_t dp)
{
  free(dp);
}
int dateSet( date_t dp, int y, int m, int d)
{
  if ( ! checkDate( y, m, d) )
  {
    dateError = EINVALID;
    return 0;
  }
  dp->year  = y;
  dp->month = m;
  dp->day   = d;

  dateError = EOK;
  return 1;
}
int dateGetYear( date_t dp)
{
  dateError = EOK;
  return dp->year;
}
int dateGetMonth( date_t dp)
{
  dateError = EOK;
  return dp->month;
}
int dateGetDay( date_t dp)
{
  dateError = EOK;
  return dp->day;
}
void dateNext( date_t dp)
{
  ++dp->day;

  if ( dp->day > daysOfMonth( dp->year, dp->month) )
  {
    dp->day = 1;
    ++dp->month;     

    if ( 13 == dp->month )
    {
      dp->month = 1;
      ++dp->year;
      if ( 0 == dp->year )
      {
        ++dp->year;
      }
    }
  }
  dateError = EOK;
}
int dateAdd( date_t dp, int n)
{
  int i;
  if ( n < 0 )
  {
    dateError = ENEGDAY;
    return 0;
  }
  for ( i = 0; i < n; ++i )
  {
    dateNext( dp);
  }
  dateError = EOK;
  return 1;
}