język ansi c. programowanie. Ćwiczenia. wydanie ii helion.pdf

(4567 KB) Pobierz
887658676.002.png
Rozdzia 4.
Funkcje
i struktura programu
wiczenie 4.1 (str. 89)
Napisz funkcj strrindex(s,t) , która zwraca pozycj ostatniego wystpienia t w s lub -1 ,
jeeli wyszukiwany cig nie zosta znaleziony.
/* strrindex: zwraca index ostatniego wystpienia t w s lub –1, jeeli nie wystpuje */
int strrindex(char s[], char t[])
{
int i, j, k, pos;
pos = -1;
for (i = 0; s[i] != '\0'; i++) {
for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++)
;
if (k > 0 && t[k] == '\0')
pos = i;
}
return pos;
}
Funkcja strrindex jest podobna do strindex , przedstawionej w podrozdziale 4.1 pod-
rcznika K&R. Gdy funkcja strindex znajduje dopasowany podcig, zwraca jego pozycj,
która jest pozycj pierwszego wystpienia t w s . Funkcja strrindex nie zwraca pozycji
znalezionego podcigu, ale kontynuuje wyszukiwanie, poniewa jej zadaniem jest okre-
lenie pooenia ostatniego wystpienia t w s :
if (k > 0 && t[k] == '\0')
pos = i;
 
Jzyk ANSI C. Programowanie. wiczenia
Ten sam problem mona rozwiza take nastpujco:
#include <string.h>
/* strrindex: zwraca index ostatniego wystpienia t w s lub –1, jeeli nie wystpuje */
int strrindex(char s[], char t[])
{
int i, j, k;
for (i = strlen(s) – strlen(t); i >= 0; i--) {
for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++)
;
if (k > 0 && t[k] == '\0')
return i;
}
return -1;
}
Jest to rozwizanie efektywniejsze. Przegldanie cigu rozpoczyna si od koca cigu
s minus dugo cigu t . Brak dopasowania powoduje przesunicie wyszukiwania o jedn
pozycj w stron pocztku cigu. Gdy tylko funkcja znajduje t w s , zwraca biec
pozycj, i . Jest to ostatnie wystpienie t w s .
wiczenie 4.2 (str. 91)
Dodaj do funkcji atof moliwo obsugi notacji wykadniczej, postaci:
123.45e-6
gdzie po liczbie zmiennoprzecinkowej moe wystpi litera e lub E i wykadnik, z opcjo-
nalnym znakiem.
#include <ctype.h>
/* atof: konwertuje cig znaków s na liczb double */
double atof(char s[])
{
double val, power;
int exp, i, sign;
for (i = 0; isspace(s[i]); i++) /* pomi biae znaki */
;
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
if (s[i] == '.')
i++;
for (power = 1.0; isdigit(s[i]); i++) {
58
887658676.003.png
 
Rozdzia 4. • Funkcje i struktura programu
val = 10.0 * val + (s[i] - '0');
power *= 10;
}
val = sign * val / power;
if (s[i] == 'e' || s[i] == 'E') {
sign = (s[++i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
for (exp = 0; isdigit(s[i]); i++)
exp = 10 * exp + (s[i] – '0');
if (sign == 1)
while (exp-- > 0) /* wykadnik dodatni */
val *= 10;
else
while (exp-- > 0) /* wykadnik ujemny */
val /= 10;
}
return val;
}
Pierwsza cz funkcji to powtórzenie funkcji atof z podrozdziau 4.2 podrcznika K&R.
Funkcja pomija biae znaki, zapisuje znak i oblicza liczb. Pobieranie liczby z kropk
dziesitn wymaga identycznej procedury niezalenie od tego, czy w dalszej czci
pojawi si wykadnik.
Druga cz funkcji odpowiada za konwersj opcjonalnego wykadnika. Jeeli ta cz
liczby nie wystpuje, funkcja zwraca warto zapisan w val . Jeeli wykadnik jest obecny,
to jego znak zostaje zapisany w zmiennej sign , po czym warto zostaje obliczona
i zapisana w zmiennej exp .
Kocowa operacja
if (sign == 1)
while (exp-- > 0)
val *= 10;
else
while (exp-- > 0)
val /= 10;
modyfikuje liczb odpowiednio do ustalonej wczeniej wartoci wykadnika. Jeeli
wykadnik jest dodatni, liczba zostaje pomnoona exp razy przez 10. Jeeli wykadnik
jest ujemny, liczba zostaje podzielona exp razy przez 10. W zmiennej val zostaje za-
pisany wynik, który jest zwracany do programu wywoujcego funkcj.
Zmienna val jest dzielona przez 10, a nie mnoona przez 0.1 , poniewa liczba 0,1 nie
jest w zapisie binarnym dokadna. Na wikszoci komputerów warto 0,1 jest repre-
zentowana jako nieco mniejsza ni 0,1. W efekcie mnoenie 10.0*0.1 rzadko daje
wynik 1.0 . Powtarzanie dzielenia przez 10 jest wic lepszym rozwizaniem ni po-
wtarzanie mnoenia przez 0,1, cho utrata dokadnoci wci wystpuje.
59
 
Jzyk ANSI C. Programowanie. wiczenia
wiczenie 4.3 (str. 97)
W oparciu o schemat przedstawiony w przykadach program kalkulatora mona atwo
rozbudowywa. Dodaj obsug operatora modulo ( % ) i obsug liczb ujemnych.
#include <stdio.h>
#include <math.h> /* dla atof() */
#define MAXOP 100 /* dopuszczalny rozmiar operandu lub operatora */
#define NUMBER '0' /* sygna, e pobrano liczb */
int getop(char []);
void push(double);
double pop(void);
/* kalkulator z odwrotn notacj polsk */
main()
{
int type;
double op2;
char s[MAXOP];
while ((type = getop(s)) != EOF) {
switch (type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
if (op2 != 0.0)
push(pop() / op2);
else
printf("error: zero divisor\n");
break;
case '%':
op2 = pop();
if (op2 != 0.0)
push(fmod(pop(), op2));
else
printf("error: zero divisor\n");
60
887658676.001.png
Zgłoś jeśli naruszono regulamin