Prośba o wytłumaczenie zadania z książki ANSI C

0

Cześć!
To mój pierwszy post na forum więc witam wszystkich użytkowników :)

Mam prośbę: czy ktoś mógłby mi wytłumaczyć jak działa element kodu programu, którego listing wklejam poniżej?

#include <stdio.h>

int main()
{
	int c, i, nwhite, nother;
	int ndigit[10];

	nwhite = nother = 0;
	for(i = 0; i < 10; ++i)
		ndigit[i] = 0;

	while((c = getchar()) != EOF)
	{
		if(c >= '0' && c <= '9')
			++ndigit[c - '0'];
		else if(c == ' ' || c == '\n' || c == '\t')
			++nwhite;
		else
			++nother;
	}
	printf("Cyfry = ");
	for(i = 0; i < 10; ++i)
		printf(" %d", ndigit[i]);
	printf(", białe znaki = %d, inne = %d.\n", nwhite, nother);
}

Mianowicie chodzi mi o fragment:

++ndigit[c - '0'];

Co się dzieje w tej linijce kodu? Program pochodzi z książki "Język ANSI C", ale nie potrafię zrozumieć tłumaczenia, które jest tam zamieszczone. Element "c" - 0 w formie tekstowej...?

0
 ++ndigit[c - '0'];

nie jestem specem od C, ale to inkrementacja elementu tablicy ndigit o indeksie równym wprowadzonej cyfrze

0

Dalej próbuję to rozkminić i stworzyłem takie coś:

#include <stdio.h>

int main()
{
	int c;
	c = 15;
	printf("%d\n", c - '0');
	return 0;
}

Konsola wypluwa wynik: -33
???
Nie mam pojęcia co tu się dzieje..

0

c=15
kod asci dla znaku '0' wynosi 48
po odjęciu masz minus 33

0

Spróbuj d..a debbugging:

#include <stdio.h>

#define ARRAY_SIZE 10

int main(void) {
    int ndigit[ARRAY_SIZE];
    int i;
    char c;
	
    for(i = 0; i < ARRAY_SIZE; ++i)
        ndigit[i] = 0;
        
    c = '2';
    ++ndigit[c - '0'];

    c = '7';
    ++ndigit[c - '0'];
    
    printf("Cyfry = ");
    
    for(i = 0; i < ARRAY_SIZE; ++i)
        printf("%d: %d\n", i, ndigit[i]);
        
	return 0;
}

Wynik:
Cyfry = 0: 0
1: 0
2: 1
3: 0
4: 0
5: 0
6: 0
7: 1
8: 0
9: 0

https://ideone.com/2SacZ2

Teraz rozumiesz?

0

Okej!
Czyli w:

++ndigit[c - '0']

dodajemy 1 do elementu tablicy o indeksie c, w zakresie znaku od '0' do '9' czyli od 48 do 57 odejmujemy 48, które jest równe '0' i w ten sposób otrzymujemy indeks.
Ale abstrakcyjna operacja!
Serdeczne dzięki za naprowadzenie grzegorz_so!

0

dodajemy 1 do elementu tablicy o indeksie c, .....

dodajemy 1 do elementu tablicy o indeksie c minus '0'

EDT...
ok , jeśli c to liczba INT reprezentowana przez znak "c" to tak będzie

0

Pamiętaj kolego, że funkcja getchar() pobiera znak z klawiatury i zwraca go jako int:
int
getchar(void);

czyli Twoją problematyczny fragment kodu:

if(c >= '0' && c <= '9')
            ++ndigit[c - '0'];

trzeba zrozumieć tak: Jeżeli wpisany na klawiaturze znak jest z zakresu ASCII '0' (dziesiętnie 48) do '9' (dziesiętnie 57), to inkrementuj element tablicy pod indeksem c-'0'.
Weźmy przykład, podałeś np. '7'. Czyli dziesiętnie dostałeś 55. 55(dec) - '0' w ASCII, to inaczej 55(dec) - 48(dec) = 7(dec). Czyli wszystko się zgadza bo podałeś 7 :) No to zwiększ o 1 ndigit[7]. O co chodzi? Po prostu liczysz w tym programie ile podałeś z klawiatury białych znaków, ile cyfr (ndigit[0] - liczba zer, ndigit[1] - liczba jedynek, ndigit[2] - liczba dwójek itd) oraz ile innych znaków. Wbrew pozorom bardzo prosty program.

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