Moduł stosu
Moduł czytania znaków z mo˙zliwo ´sci ˛
Moduł główny - kalkulator dla ONP
Kurs C z elementami C++
Marek Piotrów - Wykład 6 - Moduły i makrogenerator
6 listopada 2007
Marek Piotrów - Wykład 6
Moduł czytania znaków z mo˙zliwo ´sci ˛
Moduł główny - kalkulator dla ONP
stos.c -implementacja stosu liczb rzeczywistych
#include <stdio.h>
#define MAXSTOS 200
//
maksymalny rozmiar stosu
static double stos[MAXSTOS]; // stos liczb
static int
sp=0;
// wskaznik wierzcholka stosu
void init(void)
// inicjalizacja pustego stosu
{ sp=0; }
void push(double liczba) // umiesc liczbe na stosie
{
if (sp < MAXSTOS)
stos[sp++]=liczba;
else
fprintf(stderr,"push: stos pelen - nie mozna umiescic liczby %g\n",liczba);
}
double pop(void) // zwroc wartosc ze szczytu stosu zdejmujac ja
{
if (sp > 0)
return stos[--sp];
else {
fprintf(stderr,"pop: stos pusty - nie mozna pobrac liczby\n");
return 0.0;
}
}
Marek Piotrów - Wykład 6
Przykład - kalkulator ONP
Moduł stosu
Moduł czytania znaków z mo˙zliwo ´sci ˛
Moduł główny - kalkulator dla ONP
znak.c - czytanie z mo˙zliwo´sci ˛
a zwracania
#include <stdio.h>
#define MAXBUF 100
/*
maksymalny rozmiar bufora */
static char bufor[MAXBUF];
// bufor na znaki zwrocone przez ungetch
static int
wolne=0;
// nastepne wolne miejsce w boforze
int getch(void)
// zwroc znak, byc moze oddany na wejscie
{
return( wolne > 0 ? bufor[--wolne] : getchar());
}
void ungetch(int znak) // oddaj znak z powrotem na wejscie
{
if (wolne >= MAXBUF)
fprintf(stderr,"ungetch: za wiele zwrotow\n");
else
bufor[wolne++]=znak;
}
Marek Piotrów - Wykład 6
Przykład - kalkulator ONP
Moduł stosu
Moduł czytania znaków z mo˙zliwo ´sci ˛
Moduł główny - kalkulator dla ONP
oblicz2.c - kalkulator dla ONP
#include <stdio.h>
#include <ctype.h>
/*******
OBLICZ2: kalkulator dla odwrotnej notacji polskiej
**************
* Program czyta z wejscia ciag liczb rzeczywistych z operacjami podanymi
*
* za operandami (ONP - odwrotna notacja polska) i wykonuje je w podanej
*
* kolejnosci. Wynik wyswietlany jest po znaku =.
*
***************************************************************************/
#define LICZBA ’0’
/***************** PROTOTYPY FUNKCJI ********************/
int getch(void);
void ungetch(int z);
void init(void);
void push(double liczba);
double pop(void);
static double czytaj_liczbe(void);
static int czytaj_op(void);
/***************** DEFINICJE FUNKCJI ********************/
Marek Piotrów - Wykład 6
Przykład - kalkulator ONP
Moduł stosu
Moduł czytania znaków z mo˙zliwo ´sci ˛
Moduł główny - kalkulator dla ONP
oblicz2.c - funkcja: main
int main(void)
{
int op;
double arg2;
while ((op=czytaj_op()) != EOF) {
switch (op) {
case LICZBA:
push(czytaj_liczbe());
break;
case ’+’:
push(pop()+pop());
break;
case ’-’:
arg2=pop();
push(pop()-arg2);
break;
case ’*’:
push(pop()*pop());
break;
case ’/’:
arg2=pop();
if (arg2 != 0.0)
push(pop()/arg2);
else
fprintf(stderr,"BLAD: dzielenie przez zero\n");
break;
Marek Piotrów - Wykład 6
Przykład - kalkulator ONP
Moduł stosu
Moduł czytania znaków z mo˙zliwo ´sci ˛
Moduł główny - kalkulator dla ONP
case ’=’:
printf("WYNIK = %.8g\n",pop());
init();
break;
default:
printf("BLAD: nieznana operacja %c\n",(char)op);
}
}
return 0;
}
Marek Piotrów - Wykład 6
Przykład - kalkulator ONP
Moduł stosu
Moduł czytania znaków z mo˙zliwo ´sci ˛
Moduł główny - kalkulator dla ONP
oblicz2.c - funkcja: czytaj_op()
static int czytaj_op(void)
{
int z;
while ((z=getch()) != EOF && isspace(z)) ;
if (isdigit(z) || z == ’.’) {
ungetch(z);
return LICZBA;
}
return z;
}
Marek Piotrów - Wykład 6
Przykład - kalkulator ONP
Moduł stosu
Moduł czytania znaków z mo˙zliwo ´sci ˛
Moduł główny - kalkulator dla ONP
oblicz2.c - funkcja: czytaj_liczbe()
static double czytaj_liczbe(void)
{
int z;
double n=0.0, pot10=1.0;
while ((z=getch()) != EOF && isdigit(z))
n=10.0 * n + (z-’0’);
if (z == ’.’)
while ((z=getch()) != EOF && isdigit(z)) {
n=10.0 * n + (z-’0’);
pot10*=10.0;
}
if (z != EOF)
ungetch(z);
return n/pot10;
}
Marek Piotrów - Wykład 6
Moduł główny - czytanie danych i wypisanie wyników
Moduł szybkiego sortowania
Standardowa funkcja qsort
Sortowanie ci ˛
agów liczbowych
#include <stdio.h>
#define MAX
1000
void quicksort(double tab[],int dol,int gora);
static double a[MAX];
int main(void)
{
int i,n;
printf("Podaj dlugosc ciagu do posortowania (<= %d): ",MAX);
scanf("%d",&n);
if (n > MAX) n=MAX;
printf("Podaj %d elementow ciagu:\n",n);
for (i=0; i < n; ++i)
scanf("%lf",&a[i]);
quicksort(a,0,n-1);
for (i=0; i < n; ++i)
printf("%9.2lf%c",a[i],(i%8 == 7 ? ’\n’ : ’ ’));
putchar(’\n’);
return 0;
}
Marek Piotrów - Wykład 6
Moduł główny - czytanie danych i wypisanie wyników
sort.c - algorytmy sortowania
/************************
sort.c
*************************
* implementacja algorytmu szybkiego sortowania: quicksort *
* dla krotkich ciagow: sortowanie przez wstawiania
*
***********************************************************/
#define MALO 16
#define ZAMIEN(x,y,typ) {typ _5_6_; _5_6_=x; x=y; y=_5_6_; }
static int podziel(double tab[],int indeks,int dol,int gora);
static void sortuj(double tab[],int dol,int gora);
void quicksort(double tab[],int dol,int gora)
{
if (gora-dol+1 < MALO)
sortuj(tab,dol,gora);
else {
int srodek=podziel(tab,(dol+gora)/2,dol,gora);
if (dol < srodek)
quicksort(tab,dol,srodek-1);
if (srodek < gora)
quicksort(tab,srodek+1,gora);
}
}
Marek Piotrów - Wykład 6
Moduł główny - czytanie danych i wypisanie wyników
sort.c (c.d.) - sortowanie przez wstawianie
static void sortuj(double tab[],int dol,int gora)
{
register int i,j;
for (i=dol+1; i <= gora; ++i) {
double x=tab[i];
for (j=i-1;
j >= dol && tab[j] > x; --j)
tab[j+1]=tab[j];
tab[j+1]=x;
}
}
Marek Piotrów - Wykład 6
Moduł główny - czytanie danych i wypisanie wyników
sort.c (c.d.) - dzielenie ci ˛
agu
static int podziel(double tab[],int indeks,int dol,int gora)
{
register int i=dol,j=gora+1;
register double x=tab[indeks]
ZAMIEN(tab[dol],tab[indeks],double);
while (1) {
do ++i; while (tab[i] < x && i <= gora);
do --j; while (x < tab[j] && j >= dol);
if (i >= j) break;
ZAMIEN(tab[i],tab[j],double)
}
ZAMIEN(tab[dol],tab[j],double)
return j;
}
Marek Piotrów - Wykład 6
Moduł główny - czytanie danych i wypisanie wyników
Moduł szybkiego sortowania
qsort - standardowa funkcja w stdlib.h
/* Shorthand for type of comparison functions.
*/
#ifndef __COMPAR_FN_T
# define __COMPAR_FN_T
typedef int (*__compar_fn_t) (__const void *, __const void *);
# ifdef __USE_GNU
typedef __compar_fn_t comparison_fn_t;
# endif
#endif
/* Sort NMEMB elements of BASE, of SIZE bytes each,
using COMPAR to perform the comparisons.
*/
extern void qsort (void *__base, size_t __nmemb, size_t __size,
__compar_fn_t __compar) ;
Marek Piotrów - Wykład 6
Makrodefinicje i makrowywołania
Przykład definicji warunkowych z pliku nagłówkowego
stddef.h
- definicja typu size_t
#ifndef __SIZE_TYPE__
#define __SIZE_TYPE__ long unsigned int
#endif
#if !(defined (__GNUG__) && defined (size_t))
typedef __SIZE_TYPE__ size_t;
#ifdef __BEOS__
typedef long ssize_t;
#endif /* __BEOS__ */
#endif /* !(defined (__GNUG__) && defined (size_t)) */
Marek Piotrów - Wykład 6
Makrodefinicje i makrowywołania
Przykład kompilacji warunkowej - porównywanie
stałych
#if SYSTEM == SYSV
#define HDR "sysv.h"
#elif SYSTEM == BSD
#define HDR "bsd.h"
#elif SYSTEM == MSDOS
#define HDR "msdos.h"
#else
#define HDR "default.h"
#endif
#include HDR
/************************
msdos.h
************************/
#ifndef MSDOS_HDR
#define MSDOS_HDR
/* zawartosc pliku naglowkowego */
#endif
Marek Piotrów - Wykład 6
Makrodefinicje i makrowywołania
Przykłady makrodefinicji i makrowywoła ´n
#define MAX(a,b) ((a) > (b) ? (a) : (b))
x=MAX(p+q,r+s);
||
\/
x=((p+q) > (r+s) ? (p+q) : (r+s));
#define DPRINT(wyr) printf(#wyr " = %g\n",wyr)
DPRINT(x/y);
||
\/
printf("x/y" " = %g\n",x/y);
#define SKLEJ(przod,tyl)
przod ## tyl
SKLEJ(quick,sort)(a,0,n-1);
||
\/
quicksort(a,0,n-1);
Marek Piotrów - Wykład 6