Utilizando os arquivos da pilha genérica, as rotinas a seguir apresentam a passagem do algoritmo para código em
“C” da avaliação feita anteriormente, bastando alterar o tipo de dado que será
usado pela analise de expressão no arquivo stackapp.
h, a informação do valor inserido.
...
typedef struct tagDATA
{
float
fVal;
} SDATA;
...
|
Novamente o arquivo stackdrv.c é utilizado para a aplicação,
a rotina recebe como entrada a expressão que foi passada através da linha de
comando, o que torna toda a expressão em caracteres de uma string com dígitos e
símbolos, a única novidade em relação ao texto anterior sobre a avaliação de
uma expressão fica por conta da conversão do valor de entrada, argc tem o total de argumentos que foi
passado e cada elemento de argv
aponta para uma string com o operador ou símbolo, usando as funções IsNumber e IsOperator para identificar e decidir qual tratamento, abaixo segue
a versão da rotina simplificada para facilitar o entendimento, a rotina completa
incluída os comentários e tratamentos de erro estão disponíveis no
github.
int
StackDriver(int argc, char *argv[])
{
SDATA sdEl; // dado
temporario,
SSTACK *stk; // a pilha que
serah usada
int
iCnt; //
para ser usado como contador de loop
float fRes;
stk = appCreateStack(argc); // cria e
inicializa a pilha
for (iCnt =
1; iCnt < argc; ++iCnt)
{
if ( IsNumber(argv[iCnt]) )
{
sdEl.fVal
= (float) Atoi(argv[iCnt]);
appPushData(stk,
&sdEl);
}
else if (
IsOperator(argv[iCnt][0]) )
{
float fVal1, fVal2;
appPopData(stk, &fVal2);
appPopData(stk, &fVal1);
switch (argv[iCnt][0])
{
case '+':
sdEl.fVal = fVal1 + fVal2;
break;
case '-':
sdEl.fVal = fVal1 - fVal2;
break;
case '/':
sdEl.fVal = fVal1 / fVal2;
break;
case '*':
sdEl.fVal = fVal1 * fVal2;
break;
case '$':
sdEl.fVal = Expon(fVal1, (int)fVal2);
break;
}
//
salva o resultado na pilha
appPushData(stk, &sdEl);
}
}
appPopData(stk, &fRes);
return
(EXIT_SUCCESS);
}
|
Para a
nossa aplicação foram adicionadas uma série de rotinas para ajudar no suporte
da avaliação, apesar de varias delas terem equivalentes na biblioteca padrão do“C”, a opção de incluir serve para ilustrar os passos necessários para a
resolução e perceber as limitações que o programa possui, a principal em si é a
incapacidade de detectar e corrigir um erro, caso seja digitada uma expressão invalida,
que não respeite o espaçamento entre símbolos e dígitos. Outros problemas que
podem acontecer como a operação para converter string em um valor numérico
suporta apenas números inteiros e a função exponencial não aceita expoente
negativo.
LOCAL BOOL IsDigit(char c)
{
return (c >= '0'
&& c <= '9');
}
LOCAL BOOL IsNumber(char
*pStr)
{
while (*pStr) {
if (!IsDigit(*pStr)) {
return FALSE;
}
pStr++;
}
return TRUE;
}
LOCAL int Atoi(char *pStr)
{
int iRet = 0;
while (*pStr) {
iRet *= 10;
iRet +=
(*pStr++ & 0xF);
}
return (iRet);
}
LOCAL BOOL IsOperator(char
c)
{
char cOp[] = {"+-/*$"};
char *ptr;
ptr = cOp;
while (*ptr) {
if (*ptr++ == c)
return TRUE;
}
return FALSE;
}
LOCAL float Expon(float fBas, int iExp)
{
float fRes;
fRes = fBas;
while (--iExp)
fRes *=
fBas;
return fRes;
}
|
Nenhum comentário:
Postar um comentário