K&R ANSI C: Rozwiązanie ćwiczeń 5.3 i 5.4

Poprzednio zaprezentowałem rozwiązanie ćwiczenia 3.3. Teraz czas na kolejne.

Zadania są podobnego typu, ponieważ znów są na temat operacji na stringach, ale czy takie zadania nie są jednymi z najciekawszych?

Ćwiczenia 5.3. Napisz wskaźnikową wersję funkcji strcat z rozdziału 2. (strcat(s,t) kopiuje ciąg t na koniec ciągu s).

void strcat(char *s, char *t)
{
while(*s++);
s--;
while(*s++=*t++);
}

Pętle while wykorzystują fakt że symbol końca stringu '’ jest interpretowany jako wartość 0 czyli jako fałsz. Co powoduje, że wskaźnik związany z stringiem s po pętli ląduje o jeden dalej niż '’ przez co trzeba cofnąć się o jeden znak. Co ważne pętle while nie posiadają żadnych instukcji w sobie więc pętlę trzeba zakończyć średnikiem. 
Potem następuje kopiowanie danych przez drugiego while’a, kopiowany też jest znak zakończenia stringa z dodawanego stringa.
Przy korzystaniu z tej funkcji w swoim programie potrzebna jest zmiana nazwy funkcji, ponieważ funkcja jest jest już zdefiniowana w bibliotece standardowej. Błąd o istniejącej już funkcji będzie się pojawiał nawet gdy nie podamy w #include <string.h>.

Ćwiczenie 5.4 Napisz funkcję strend(s,t), która zwraca 1, jeżeli  ciąg t zostanie znaleziony na końcu ciągu s, lub 0.

int strend(char *s, char *t)
{
int t_len = strlen(t);
while(*s++); s--;
while(*t++); t--;
for(;(t_len >= 0)&&(*s--==*t--); t_len--);
if(t_len >= 0)
return 0;
else
return 1;
}
W tej funkcji wykorzystuje strlen (funkcja zdefiniowana w <string.h>) do pozyskania długości dodawanego stringu – ta wartość będzie użyteczna później.
Dwa while służą do przesunięcia wskaźnika na koniec stringu, ten sam trick co w poprzedniej funkcji.
Pętla for nie przypisuje żadnej wartości do żadnej zmiennej więc pierwsze pole jest puste. Warunek jest podzielony na dwa pod-warunki.

  1. t_len>=0 sprawdza czy został całkowicie sprawdzony ciąg t
  2. *s–==*t– sprawdzenie kolejnych znaków i jednocześnie przesunięcie wskaźnika o jedną pozycję do tyłu. Ponieważ sprawdzamy czy t znajduje się na końcu s, zaczynając od końca ciągu s.
Funkcja for nie posiada w sobie żadnych instrukcji więc potrzebny jest średnik na końcu linii z forem.
Prawidłowo zmienne t_len powinna być mniejsza od zera, gdy wskaźnik przeszedł przez cały ciąg t, w każdym innym przypadku gdzieś na drodze wystąpił błąd w porównywaniu.