Użycie funkcji rekurencyjnej do tworzenia tabeli i sprawdzania jej zawartości

0

Witajcie ;). Kontynuując moją przygodę z "Język C. Szkoła programowania" natknąłem się na funkcje rekurencyjne. Zdawało mi się, że wiem o co chodzi, no ale jak przyszło do ćwiczeń to nie mam pojęcia jak zmusić taki substytut pętli do poprawnego działania.

Za zadanie mam stworzyć program, który wczyta znaki do wystąpienia końca pliku, następnie ma informować, czy dany znak jest literą, jeśli tak to ma wyświetlić, którą literą alfabetu jest wpisana litera. Mam wykorzystać funkcję, która pobiera znak i zwraca jego numer w alfabecie, a jeśli znak nie jest literą zwraca wartość -1.
Powyższe polecenie(zad 6/388) wykonałem, załączam kod źródłowy:

 
#include <stdio.h>
#include <ctype.h>
int numalf(int ch);
int main(void)
{
    char table[512];
    int i, n, num;

for (i=0; (table[i]=getchar())!=EOF && i<512; i++)
        continue;
    for (n=0; n<i; n++)
    {
        num=numalf(table[n]);
        if (num >0 )
            {
                putchar(table[n]);
                printf(" - numer tej litery w alfabecie to: %d\n", num);
            }
        else if (num ==-1)
        {
            putchar(table[n]);
            printf(" nie jest litera\n");
        }
    }
return 0;
}

int numalf(int ch)
{
    int num;
    if (isalpha(ch))
        {
            ch=toupper(ch);
            num=ch-64;
        }
    else if(isspace(ch))
        num=0;
    else num=-1;
    return num;
}

I tu problemów żadnych nie było, natomiast problem pojawił się przy zadaniu 8, które nakazuje zrobić to samo zadanie z wykorzystaniem funkcji rekurencyjnych. Zadanie 'wykonałem', ale program zachowuje się dziwnie. Po wpisaniu np. ABCdeF zamiast wypisac F nr... A nr wypisuje mi dodatkowe " " - numer 8 (czyli, teoretycznie, ekwiwalent "h" lub "H"). Zamieszczam poniżej kod takiego programu:

#include <stdio.h>
#include <ctype.h>
int numalf(int ch);
void tabela(int i);
int main(void)
{
    int i=0;
    tabela(i);
    return 0;
}

int numalf(int ch)
{
    int num;
    if (isalpha(ch))
        {
            ch=toupper(ch);
            num=ch-64;
        }
    else if(isspace(ch))
        num=0;
    else num=-1;
}

void tabela(int i)
{
   int ch, num;
   if(((ch=getchar()) != EOF) && i <64)
    {
        i++;
        tabela(i);
    }
    if (ch!=EOF)
    {
   num=numalf(ch);
    if (num >0 )
        {
            putchar(ch);
            printf(" - numer tej litery w alfabecie to: %d\n", num);
        }
    else if (num ==-1)
        {
            putchar(ch);
            printf(" nie jest litera\n");
        }
    }
}

Proszę, pomóżcie, nie wiem co mam zrobić, żeby program pracował normalnie... Z góry dzięki :)

@Edit - wymyśliłem rozwiązanie(któryś już raz, od razu po kliknięciu 'wyślij' na forum...) jednak nie mam pojęcia co w programie wyżej idzie nie tak. Rozwiązałem to w następujący sposób: zamiast warunku if (ch != EOF) wpisałem if (isgraph(ch)) i problem niechcianej ósemki zniknął.
Skąd się brała ta ósemka - i dlaczego ZAWSZE ósemka? Jakby była to losowa wartość to ok, nie pomyślałem o losowej wartości, która utworzyła się w ostatnim wywołaniu funkcji, ale... Skąd to się wzięło?
Dzięki jeszcze raz.

1

num=numalf(ch);

Jaka jest wartość num po wykonaniu tej instrukcji? W drugim listingu funkcja numalfa() nic nie zwraca.

0

Dzięki wielkie, głupie przeoczenie, nie pisałem drugi raz tej funkcji tylko skopiowałem z "ćw.6", jakimś dziwnym trafem - bez ostatniej linijki.

Nie powinien ostrzegać mnie kompilator o tym, że funkcja typu int nie zwraca żadnej wartości?

1

Być może i powinien. W każdym razie, według standardu nie jest to nielegalne, ale wynik to "undefined behaviour". Dzięki temu np. w Visual C++ można poprzez wstawkę asmową ustawić wartość zwracaną przez rejestr eax i nie martwić się o brak return w kodzie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1