22: The expense of spirit
Ïðîãðàìàòà
âå÷å å ïðàâèëíà. Îò ãëåäíà òî÷êà íà ñòèëà íà ïðîãðàìèðàíå, îáà÷å, òàçè ïðîãðàìà
âñå îùå íå å ñúâúðøåíà. Îïåðàòîðúò
st -= len + 1;
áåøå äîáàâåí ñ
öåë êîðèãèðàíå íà ãðåøêàòà îò äèðåêòíîòî óâåëè÷àâàíå íà st. Ïîâòîðíîòî äàâàíå íà
ñòîéíîñò íà st íå ñå âìåñòâà â ëîãèêàòà íà ïðîãðàìàòà, êàòî ïðè òîâà ïðîãðàìàòà
å ìàëêî ïî-òðóäíà çà ðàçáèðàíå.
Ðàçáèðà ñå, â ïðîãðàìà êàòî òàçè,
íàëè÷èåòî íà åäèí íåÿñåí îïåðàòîð íå èçãëåæäà îñîáåíî îïàñíî. Ïðåäñòàâåòå ñè,
îáà÷å, ÷å òåçè îïåðàòîðè ïðåäñòàâëÿâàò 20% îò èçïúëíèìèòå îïåðàòîðè íà
ïðîãðàìàòà. Äîáàâåòå, ÷å ïðîãðàìàòà ìîæå äà ñå ñúñòîè îò 10,000 ðåäà è
ðåøàâàíèÿò ïðîáëåì íå å òðèâèàëåí. ×àñò îò ïðîãðàìà, ïîäîáíà íà òàçè, ÷åñòî ñå
íàðè÷à êðúïêà – íåùî, äîáàâåíî âúðõó òåêñòà íà ñúùåñòâóâàùàòà
ïðîãðàìà.
Íèå çàêúðïâàìå íàøàòà ïðîãðàìà çà äà êîðèãèðàìå ëîãè÷åñêà
ãðåøêà â ïðîåêòà é. Ïî-äîáðî ðåøåíèå å äà ñå êîðèãèðà íåäîñòàòúêà íà
ïúðâîíà÷àëíèÿ ïðîåêò. Åäíî âúçìîæíî ðåøåíèå å äà ñå äåôèíèðà âòîðè ñèìâîëåí
óêàçàòåë è äà ñå èíèöèàëèçèðà ñúñ st. Íàïðèìåð,
char *p = st;
À
ñåãà ìîæå äà ñå èçïîëçóâà ïðè èç÷èñëåíèåòî íà äúúëæèíàòà íà st, äîêàòî st îñòàâà
íåïðîìåíåíà.
while ( *p++ != ‘�’ )
Íåêà ðàçãëåäàìå è åäíî äðóãî
ïîäîáðåíèå íà íàøàòà ïðîãðàìà - òî ïîçâîëÿâà ðàáîòàòà íè äà áúäå èçïîëçóâàíà è
îò äðóãè ïðîãðàìè. Ñïîðåä çàïèñàíîòî äî ìîìåíòà, íÿìà íà÷èí äðóãà ïðîãðàìà äà
èç÷èñëè äúëæèíàòà íà íèç, îñâåí àêî íå äîáàâè ãîðåñïîìåíàòèÿ òåêñò. Òàçè
àëòåðíàòèâà å îñîáåíî ðàçòî÷èòåëíà. Ïî-äîáðàòà àëòåðíàòèâà å äà áúäå îáîñîáåíà
÷àñòòà, èç÷èñëÿâàùà äúëæèíàòà íà íèç è ïîñòàâåíà â îòäåëíà ôóíêöèÿ. Òÿ âå÷å ìîæå
äà áúäå íà ðàçïîëîæåíèå íà âñè÷êè ïðîãðàìèñòè, èçïîëçâàùè ñèñòåìàòà. Åòî åäíà
ïðèìåðíà äåôèíèöèÿ íà ôóíêöèÿòà stringLength():
#include
<stream.h>
void stringLength( char *st ) {
// calculate length
of st_int len = 0;
char *p = st;
while ( *p++ ) ++len;
cout <<
len << ": " << st;
}
Äåôèíèöèÿòà
char *p =
st;
íåäîñòàòúêà íà ïðîåêòà íà îðèãèíàëíàòà ïðîãðàìà. Îïåðàòîðúò while (
*p++ )
ïðåäñòàâÿ êðàòúê çàïèñ íà ñëåäíîòî:
while ( *p++ != ‘�’
)
Ñåãà ìîæåì äà ïðîìåíèì ïðîãðàìàòà main() êàòî èçïîëçóâàìå íîâàòà
ôóíêöèÿ:
extern void stringLength ( char* );
char *st = "The expense
of spiritn";
main() {
stringLength( st );
return
0;
}
Ôóíêöèÿòà stringLength() å çàïèñàíà âúâ ôàéëà string.C.
Êîìïèëèðàíåòî è èçïúëíåíèåòî íà òàçè ïðîãðàìà ìîæå äà áúäå íàïðàâåíî
òàêà:
$ CC main.C string.C
$ a.out
Ïðîåêòúò íà stringLength() e
òÿñíî ñâúðçàí ñ ïðåäíàçíà÷åíèåòî íà íàøàòà îðèãèíàëíà ïðîãðàìà. Íàïèñàíàòà
ôóíêöèÿ íå å äîñòàòú÷íî îáùà çà äà îáñëóæâà ìíîãî ïðîãðàìè. Íàïðèìåð,
ïðåäñòàâåòå ñè, ÷å ñòå ïîìîëåíè äà íàïèøåòå ôóíêöèÿ, êîÿòî îïðåäåëÿ äàëè äâà
íèçà ñà åäíàêâè. Íèå áèõìå ìîãëè äà ïðîåêòèðàìå íàøèÿ àëãîðèòúì òàêà:
-
Äà ïðîâåðèì äàëè äâàòà óêàçàòåëÿ àäðåñèðàò åäèí è ñúù íèç. Àêî å òàêà, íèçîâåòå
ñà åäíàêâè.
- Èíà÷å, äà ïðîâåðèì äàëè äúëæèíèòå íà äâàòà íèçà ñà ðàâíè. Àêî
íå ñà, äâàòà íèçà íå ñà åäíàêâè.
- Èíà÷å, äà ïðîâåðèì äàëè ñèìâîëèòå íà äâàòà
íèçà ñà åäíàêâè. Àêî å òàêà, íèçîâåòå ñà åäíàêâè. Èíà÷å, òå íå ñà åäíàêâè.
stringLength(), êàêòî å ïðîåêòèðàíà, íå ìîæå äà áúäå èçïîëçóâàíà ñ òåçè íîâè
ôóíêöèè. Åäèí ïî-îáù ïðîåêò áè ñëåäâàëî ïðîñòî äà ïðåäâèäè âðúùàíåòî íà
äúëæèíàòà íà íèçà. À êàêâîòî è äà áèëî èçâåæäàíå íà ñàìèÿ íèç òðÿáâà äà áúäå
îñòàâåíî íà ïðîãðàìàòà, èçâèêâàùà stringLength(). Åòî åäíî íîâî ðåøåíèå íà
ïðîáëåìà:
int stringLength( char *st ) {
// return length of st
int
len = 0;
while ( *st++ )
++len;
}
×èòàòåëÿò ìîæå äà áúäå
èçíåíàäàí êàòî âèäè, ÷å â òàçè âåðñèÿ íà stringLength() îòíîâî st ñå óâåëè÷àâà
äèðåêòíî. Òîâà íå ïðåäñòàâëÿâà íèêàêúâ ïðîáëåì ïðè íîâàòà ðåàëèçàöèÿ ïîðàäè
ñëåäíèòå äâå ïðè÷èíè:
1. Çà ðàçëèêà îò ïî-ðàííèòå âåðñèè, òàçè ðåàëèçàöèÿ
íà ôóíêöèÿòà stringLength() íå ñå íóæäàå îò äîñòúï äî st ñëåä êàòî st å áèëà
ïðîìåíÿíà, òàêà ÷å ïðîìåíèòå íÿìàò çíà÷åíèå.
2. Âñè÷êè ïðîìåíè, èçâúðøåíè
íàä ñòîéíîñòòà íà st âúâ stringLength() èç÷åçâàò êîãàòî ïðèêëþ÷è èçïúëíåíèåòî é.
Çà st ñå êàçâà, ÷å å èçïðàòåíà ïî ñòîéíîñò êúì ôóíêöèÿòà stringLength(). Òîâà
îçíà÷àâà, ôàêòè÷åñêè, ÷å òîâà, êîåòî stringLength() îáðàáîòâà å ñàìî êîïèå íà
st. (Ðàçäåë 4.6 ðàçãëåæäà ïîäðîáíî îáðúùåíèåòî ïî
ñòîéíîñò).
stringLength() âå÷å ìîæå äà áúäå âèêàíà îò âñÿêà ïðîãðàìà,
êîÿòî èñêà äà èç÷èñëè äúëæèíà íà íèç. Çà öåëèòå íà ïðîãðàìàòà íè ôóíêöèÿòà
main() áè ìîãëà äà áúäå ðåàëèçèðàíà òàêà:
...
main() {
int len =
stringLength( st );
cout << len << ": " << st;
return
0;
}
stringLength() ïðàâè ñúùîòî, êîåòî ïðàâè è áèáëèîòå÷íàòà ôóíêöèÿ
strlen(). ×ðåç âêëþ÷âàíå íà ñòàíäàðòíèÿ çàãëàâåí ôàéë string.h ïðîãðàìèñòúò ìîæå
äà èçïîëçóâà ãîëÿì áðîé ïîëåçíè ôóíêöèè çà îáðàáàòêà íà íèçîâå, êàòî
íàïðèìåð:
char *strcpy ( char *dst, char *scr );// êîïèðà scr â
dst.
int strcmp ( char *s1, char *s2 );
// ñðàâíÿâà äâà íèçà. âðúùà 0
àêî ñà ðàâíè.
int strlen( char *st );// âðúùà äúëæèíàòà íà st.
Çà
ïîâå÷å ïîäðîáíîñòè è ïúëåí ñïèñúê íà áèáëèîòå÷íèòå ôóíêöèè, îáðàáîòâàùè íèçîâå,
íàïðàâåòå ñïðàâêà â ñïðàâî÷íèêà íà áèáëèîòåêèòå.
Óïðàæíåíèå 1-5. Îáÿñíåòå
ðàçëèêàòà ìåæäó 0, ‘0’ è “0”.
Óïðàæíåíèå 1-6. Äàäåíî å ñëåäíîòî ìíîæåñòâî îò
äåôèíèöèè íà ïðîìåíëèâè:
int *ip1, ip2;
char ch, *cp;
êàêòî è
íÿêîëêî îïåðàòàðà çà ïðèñâîÿâàíå, êîèòî ñà êîíôëèêò ñ îïèñàíèòå òèïîâå. Îáÿñíåòå
çàùî?
(a) ipl = "All happy families are alike";
(b) cp = 0; (c) cp =
‘�’;
(d) ip1 = 0; (e) ip1 = ‘�’;
(f) cp = &’a’; (g) cp =
&ch;
(h) ip1 = ip2; (i) *ip1 = ip2;