Dobrý den,
Učím se programovat podle knihy Karninghana a Ritchieho. Podle knihy jsem napsal kód (viz. níže). Program je vlastně jednoduchá kalkulačka podle obrácené polské notace (př.: 1 - 2 se musí zapisovat jako 1 2 -). K tomuto programu mám za úkol doplnit operátor zbytku dělení (%) a postarat se ještě o záporná čísla.
#include <stdio.h>
#include <stdlib.h> //pro atof()
#include <ctype.h> //pro isdigit()
#define MAXOP 100 //maximalni velikost operatoru nebo operandu
#define CISLO '0' //signal oznamujici nalezeni cisla
#define MAXHODNOTA 100 //maximalni hloubka zasobniku
#define VELVPAMETI 100 //velikost vyrovnavaci pameti ve funkci vratz
int rp = 0; //dalsi volna pozice na zasobniku
double zasobnik[MAXHODNOTA]; //zasobnik hodnot
char vpamet[VELVPAMETI]; //vyrovnavaci pamet pro vratz
int vpametp = 0;
int nactioperator(char []);
void vloz(double);
double vyjmi(void);
int nactiz(void);
void vratz(int);
/*Kazdy operand se umisti do zasobniku, jakmile se objevi operator
ze zasobniku vyjmeme spravny pocet operandu (dva), na ne aplikujeme
operator a vysledek se vrati zpet do zasobniku*/
main()
{
int typ;
double op2;
char s[MAXOP], r[] = "";
printf("\t****************************************\n");
printf("\t* Tento program je jednoducha kalkulac-*\n");
printf("\t* ka, podle obracene polske notace. *\n");
printf("\t* (1-2)*(4+5) zapisujte 1 2 - 4 5 + * *\n");
printf("\t* Program vytvoril Adam Lasak podle *\n");
printf("\t* algoritmu Kernighana a Ritchieho. *\n");
printf("\t* ver [1.0] *\n");
printf("\t****************************************\n");
scanf("%s", &r);
while ((typ = nactioperator(r)) != EOF){
switch(typ){
case CISLO:
vloz(atof(r));
break;
case '+':
vloz(vyjmi() + vyjmi());
break;
case '*':
vloz(vyjmi() * vyjmi());
break;
case '-':
/*zadani napr.: 1 2 - znamena, ze hodnota 2 se ulozi
pozdeji nez hodnota 1. => op2 = vyjmi() znamena
ze se od promenne rp odecte 1, a pri dalsim volani
vyjmi() bude jako prvni hodnota 1 (pri vypoctu)*/
op2 = vyjmi();
vloz(vyjmi() - op2);
break;
case '/':
//uplne to stejne, akorat je zde podminka kvuli deleni 0
op2 = vyjmi();
if (op2 != 0.0)
vloz(vyjmi() / op2);
else
printf("Chyba: deleno nulou\n");
break;
case '\n':
printf("\t%.8g\n", vyjmi());
break;
case '%':
//ZDE JE CELOCISELNE DELENI
vloz(vyjmi() % vyjmi());
break;
default:
printf("Chyba: neznamy prikaz %s\n", s);
break;
}
}
return 0;
}
//vloz: vlozi hodnoty do zasobniku
void vloz(double f)
{
if (rp < MAXHODNOTA)
zasobnik[rp++] = f;
else
printf("Chyba: plny zasobnik, nelze vlozit %g\n", f);
}
//vyjmi: vyjme hodnotu z vrcholu zasobniku
double vyjmi(void)
{
if (rp > 0)
return zasobnik[--rp];
else {
printf("Chyba: prazdny zasobnik\n");
return 0.0;
}
}
//nactioperator: ziska nasledujici operator nebo ciselny operand
int nactioperator(char r[])
{
int i, z;
while ((r[0] = z = nactiz()) == ' ' || z == '\t')
;
r[1] = '\0';
if (!isdigit(z) && z != '.')
return z; //neni cislem
i = 0;
if (isdigit(z)) //ziskej celociselnou cast
while (isdigit(r[++i] = z = nactiz()))
;
if (z == '.') //ziskej zlomkovou cast
while (isdigit(r[++i] = z = nactiz()))
;
r[i] = '\0';
if (z != EOF)
vratz(z);
return CISLO;
}
/*vratz vlozi vracene znaky do sdilene vyrovnavaci pameti - pole znaku. nactiz
vyjme znak z vyrovnavaci pameti, neni-li prazdna, jestli je, zavolame getchar()*/
//nactiz: vrati nasledujici znak na vstupu
int nactiz(void)
{
return (vpametp > 0) ? vpamet[--vpametp] : getchar();
}
//vratz: vrati znak zpet na vstup
void vratz(int z)
{
if (vpametp >= VELVPAMETI)
printf("Chyba: prilis mnoho znaku\n");
else
vpamet[vpametp++] = z;
}
HÁZÍ MI TO TUHLE CHYBU: 71 D:\Knihovny\Dokumenty\IT\C_C++\09_Externi_promenne\expromenne.cpp invalid operands of types `double' and `double' to binary `operator%'
takže jsem se pokoušel vracené hodnoty z funkce vyjmi() převést na celá čísla pomocí funkce atoi() z knihovny stdlib.h. Ale tohle bylo taky neúspěšné. Vubec nevim co s tim.