4 FUNKCJE I STRUKTURA PROGRAMU
wykonywalnego pliku zwanego a.out. Jeśli wystąpi błąd, np. w main.c, to plik ten można ponownie przetłumaczyć oddzielnie i wynik załadować razem z pozostałymi plikami pośrednimi za pomocą polecenia
cc main.c getline.o strindex.o
Polecenie cc rozróżnia pliki zgodnie z przyjętą konwencją oznaczania plików źródło-wych końcówką ,,.c”, a plików pośrednich końcówką „.o”.
Ćwiczenie 4.1. Napisz funkcję strrindex(s,t) zwracającą pozycję pierwszego od końca wystąpienia wzorca t w s lub -1, jeśli wzorzec nie występuje w s.
Dotychczas w naszych przykładach funkcje albo nie zwracały żadnej wartości (void), albo zwracały wartości typu int. Ale co się dzieje wówczas, gdy funkcja musi zwrócić wartość jakiegoś innego typu? Wiele funkcji numerycznych, jak sqrt, sin czy cos, zwraca wartości typu double; inne wyspecjalizowane funkcje zwracają wartości innych typów. W celu zilustrowania metody postępowania napiszemy i za* stosujemy funkcję atof(s), przekształcającą ciąg cyfr zawarty w s na jego zmiennopozycyjny odpowiednik w podwójnej precyzji. Funkcja atof jest rozszerzeniem funkcji atoi, której dwie wersje przedstawiliśmy w rozdz. 2 i 3. Funkcja obsługuje nieobowiązkowy znak liczby i kropkę dziesiętną, a także wykrywa obecność lub brak zarówno części całkowitej, jak i ułamkowej. Nasza wersja nie jest najwyższej jakości; taka zajmowałaby dużo więcej miejsca, niż możemy jej poświęcić. Funkcja ato< występuje w bibliotece standardowej; plik nagłówkowy <stdlib.h> zawiera jej deklarację.
Po pierwsze, funkcja atof musi sama zadeklarować typ zwracanej przez siebie wartości, gdyż typem tym nie jest int. Nazwa typu poprzedza nazwę funkcji:
#include <ctype.h>
/* atof: przekształć ciąg cyfr s na wartość zmiennopozycyjną */
double atof(char s[ 1)
{
double val, power; int i, sign;
t
sign = (s[i] == ? -1 : 1;
if (s[i] == V || s[i] ==’-’) i++;
for (val = 0.0; isdigit(s[i]); i++) val = 10.0 * val + (s[i] - ’0’); if (s[i] == 7) i++;
for (power = 1.0; isdigit(s[i]); i++) { val = 10.0 * val + (s[i] - ’0’); power *= 10.0;
returp sign * val / power;
Po drugie, i równie ważne, funkcja wywołująca musi wiedzieć, że atof zwraca wartość niecałkowitą. Jednym ze sposobów, które to zapewniają, jest jawne zadeklarowanie funkcji atof w funkcji wywołującej. Taką deklarację pokazano w programie prymitywnego kalkulatora biurowego (nadaje się zaledwie do bilansowania książeczki czekowej). Program czyta liczby, każdą w oddzielnym wierszu, być może poprzedzone znakiem liczby, dodaje je i wypisuje bieżącą sumę po każdej przeczytanej liczbie.
#include <stdio.h>
#define MAXLINE 100
I* prymitywny kalkulator biurowy */ main()
double sum, atof(char []);
char line[MAXLINE];
int getline(char line[], int max);
sum = 0;
while (getline(line, MAXLINE) > 0) printf(”\t%g\n”, sum += atof (linę)); return 0;
105