Twój zapis: wyraz[ i ] nie ma nic wspólnego z wyraz.length(). Troszkę pomyliłeś pojęcia. Twój zapis jest oczywiście błędny, a swoje działanie zawdzięcza szczęściu :-D
Spróbuję Ci wytłumaczyć dlaczego to działa i dlaczego na farcie.
Powiedzmy, że wprowadzasz tekst "abc". W takim razie Twój string "wyraz" zawiera następujące dane:
wyraz[ 0 ] = 'a';
wyraz[ 1 ] = 'b';
wyraz[ 2 ] = 'c';
I Twoja pętla wygląda tak:
for (int i=0; i<wyraz[i]; i++)
Skupię się na warunku kończącym tę pętlę. Czyli: i < wyraz[ i ]. Zadam kilka pytań, na które sam odpowiem:
Czym jest "i"? To jest int, który będzie przyjmował kolejne wartości 0, 1, 2, 3, 4....
Czym jest wyraz[ i ]? To jest konkretny znak o indeksie kolejno: 0, 1, 2, 3, 4...
Czym jest w takim razie: i < wyraz[ i ]? Jest to porównanie int'a ze znakiem char. W takim przypadku zachodzi niejawna konwersja. To znaczy, ze znak char jest traktowany jak liczba int i wtedy program sobie porównuje te wartości.
Co to dla nas oznacza? To oznacza, że litera 'a' jest zamieniona na liczbę. Jaką? Zgodnie z tablicą ASCII 'a' = 97. W takim razie:
W pierwszej iteracji pętli: porównujemy i = 0 oraz wyraz[ 0 ] = 'a' = 97. W efekcie mamy: 0 < 97. To jest prawda, więc pętla sie wykonuje.
Druga iteracja: i = 1 oraz wyraz[ 1 ] = 'b' = 98. Czyli teraz mamy sprawdzenie: 1 < 98. Prawda. Pętla się wykonuje, zwiększamy i++ i jedziemy dalej.
Trzecia iteracja: i = 2 oraz wyraz[ 2 ] = 'c' = 99. Czyli sprawdzamy czy: 2 < 99. Prawda. Lecimy dalej. Teraz uwaga.
Czwarta iteracja: i = 3 oraz wyraz[ 3 ] = ? No właśnie! CO teraz? Nie ma trzeciego elementu. Jak się zachowa nasz string? Wywali błąd i program się scrashuje? Otóż nie. Jeżeli odniesiemy się do elementu o indeksie o jeden większym niż rozmiar tablicy, to wtedy string zwraca NULL, czyli znak '\0'. Ten znak ma numer 0. Teraz konkluzja moich rozważań:
porównujemy czy i = 3 jest mniejsze od wyraz[ 3 ] = '\0' = 0. Czyli czy: 3 < 0.
To jest nieprawda, pętla się kończy.
Myślę, że po tym wszystkim rozumiesz dlaczego to działa. A teraz wyjaśnię Ci dlaczego to źle działa.
Program jest niestabilny, to znaczy, ze są przypadki, dla których może podać niepoprawny wynik albo O ZGROZO, wypluć błąd (u Ciebie akurat nie będzie błędu). Litera 'a' ma numer 97. W związku z czym, aby Twój wspaniały algorytm nie zadziałał wystarczy podać 98 liter 'a'. Coś takiego:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... i tak do 98 literek.
Wtedy Twój program policzy tylko 97 liter i zakończy pętle. A to dlatego, że podczas 98 iteracji zajdzie taki warunek:
Iteracja 98: W 98 iteracji i = 97 (numerowaliśmy od 0), natomiast wyraz[ 97 ] = 'a' = 97. Czyli sprawdzamy czy:
97 < 97. Fałsz, koniec pętli pomimo tego, że są jeszcze litery do wczytania!
Teraz powinieneś rozumieć, że czasami to, że coś działa, wcale nie oznacza, że to działa :-)
Pozdrawiam.