А.В. Столяров - Оформление программного кода (1108519), страница 10
Текст из файла (страница 10)
Ôàêòè÷åñêè, â íåêîòîðûõ ñëó÷àÿõ âû äàæå íåñìîæåòå ïîíÿòü, âûïîëíèëñÿ ëè öèêë õîòÿ áû îäèí ðàç èëè íåò! Âûâîä ïîëó÷àåòñÿ ïðîñòîé è îäíîçíà÷íûé:.  êîíöå êîíöîâ, çàïàñ ñòðîê âî Âñåëåííîé íè÷åì íå îãðàíè÷åí.Ðàññìîòðèì òåïåðü áîëåå ñëîæíûé ïðèìåð, êîãäà â òåëå öèêëà íóæíîâûïîëíèòü äâà äåéñòâèÿ (èëè áîëüøå), òàê ÷òî íåîáõîäèìî ïðèìåíåíèåñîñòàâíîãî îïåðàòîðà.  áîëüøèíñòâå ñëó÷àåâ ïðîôåññèîíàëüíûå ïðîãðàììèñòû ïèøóò ïðèìåðíî òàê:íèêîãäà íå îñòàâëÿéòå òåëîñëîæíîãî îïåðàòîðà íà îäíîé ñòðî÷êå ñ çàãîëîâêîìwhile p <> nil do begins := s + p^.data;p := p^.nextend;while (p) {s += p->data;p = p->next;}Îáðàòèòå âíèìàíèå, ÷òî îòêðûâàþùàÿ îïåðàòîðíàÿ ñêîáêà îñòàâëåíàíà îäíîé ñòðîêå ñ çàãîëîâêîì, òîãäà êàê çàêðûâàþùàÿ ñòîèò â òîé æå37êîëîíêå, â êîòîðîé íà÷èíàåòñÿ çàãîëîâîê (òî åñòü çàêðûâàþùóþ îïåðàòîðíóþ ñêîáêó ìû â îáîèõ ñëó÷àÿõ íàïèñàëè òî÷íî ïîä áóêâîé w ñëîâàwhile).Êàê ìû óæå óïîìèíàëè âî ââåäåíèè, îòêðûâàþùóþ îïåðàòîðíóþñêîáêó âïîëíå äîïóñòèìî ñíåñòè íà ñëåäóþùóþ ñòðî÷êó:while p <> nil dobegins := s + p^.data;p := p^.nextend;while (p){s += p->data;p = p->next;}Çàìåòèì, èìåííî òàêîé ñòèëü ÷àùå âñåãî âñòðå÷àåòñÿ â ó÷åáíèêàõ ïîÏàñêàëþ, íî âîò áîëüøèíñòâî ïðîãðàììèñòîâ, ïèøóùèõ íà Ñè è Ñè++,òàêîé ñòèëü íå ëþáÿò. îáîèõ ïðèâåä¼ííûõ âûøå ñëó÷àÿõ ñîñòàâíîé îïåðàòîð íå ñäâèãàåòñÿ îòíîñèòåëüíî çàãîëîâêà, ñäâèãó ïîäâåðãàåòñÿ òîëüêî åãî ñîäåðæèìîå.Êðàéíå ðåäêî ìîæíî âñòðåòèòü ñòèëü, ïðè êîòîðîì ñàì ñîñòàâíîé îïåðàòîð òîæå ñäâèãàåòñÿ:while p <> nil dobegins := s + p^.data;p := p^.nextend;while (p){s += p->data;p = p->next;}Îòìåòèì, ÷òî ïðè ýòîì ôàêòè÷åñêîå íàïîëíåíèå òåëà öèêëà îêàçûâàåòñÿ ñäâèíóòî íà óäâîåííûé îòñòóï, åñëè æå òåëî ñîñòîèò èç îäíîãîïðîñòîãî îïåðàòîðà, åãî ïî-ïðåæíåìó ñäâèãàþò íà îäèí îòñòóï.
Ñ ôîðìàëüíîé òî÷êè çðåíèÿ ýòî ìîæíî íàçâàòü ëîãè÷íûì, ïîñêîëüêó ñîñòàâíîé îïåðàòîð ýòî òîæå îïåðàòîð; íî íà ïðàêòèêå òàêîé äâîéíîé îòñòóïíèêàêèõ ïðåèìóùåñòâ íå äà¼ò, ñúåäàÿ ïðè ýòîì ëèøíåå ìåñòî ïî ãîðèçîíòàëè. Òåì íå ìåíåå, êàê ñêàçàíî âûøå2 , ýòîò ñòèëü ÿâëÿåòñÿ äîïóñòèìûì.Ðàññìîòðèì òåïåðü íåñêîëüêî âàðèàíòîâñòèëÿ. Ìûóæå óïîìèíàëè, ÷òî â ïðîãðàììàõ íîâè÷êîâ ÷àñòî âñòðå÷àåòñÿ ïðèìåðíîòàêîå:íåäîïóñòèìîãîwhile p <> nil do begins := s + p^.data;p := p^.nextend;while (p) {s += p->data;p = p->next;}Çàêðûâàþùàÿ îïåðàòîðíàÿ ñêîáêà ïðè ýòîì îêàçûâàåòñÿ ñäâèíóòà íàíåïîíÿòíîå êîëè÷åñòâî ïîçèöèé, çàâèñÿùåå, íàïðèìåð, îò òîãî, èç ñêîëüêè ñèìâîëîâ ñîñòîèò çàïèñü óñëîâíîãî âûðàæåíèÿ.
Íà òî, ÷òîáû ïðåñëîâóòóþ ñêîáêó íàéòè, óõîäèò ëèøíÿÿ äîëÿ ñåêóíäû ñõîäó å¼ â òåêñòå íåâèäíî, îíà ¾ñëèâàåòñÿ ñ îêðóæàþùèì ïåéçàæåì¿. Ñâîþ îñíîâíóþ çàäà2Ñì. cíîñêó íà ñòð. 14.38÷ó ñäåëàòü î÷åâèäíûì êîíåö ñëîæíîãî îïåðàòîðà äàæå äëÿ ðàñôîêóñèðîâàííîãî âçãëÿäà òàêîå ïîëîæåíèå çàêðûâàþùåé îïåðàòîðíîé ñêîáêèíå ðåøàåò.Àâòîð ïîñîáèÿ íåîäíîêðàòíî âñòðå÷àë â ñòóäåí÷åñêèõ ðàáîòàõ è âîòòàêîé, èçâèíèòå çà âûðàæåíèå, êîøìàð:while p <> nil do begins := s + p^.data;p := p^.nextend;Ïðè òàêîì ¾ñòèëå¿ ìåñòà íà ýêðàíå íå õâàòèò äàæå íà òðè óðîâíÿ âëîæåííîñòè, íî ýòî íå ñàìîå âàæíîå; ãîðàçäî õóæå òî, ÷òî ðàçìåð ñäâèãàîêàçûâàåòñÿ íå ïîñòîÿííûì, êàê ýòî äîëæíî áûòü, à çàâèñÿùèì îò øèðèíû çàãîëîâêà. ×èòàòü òàêóþ ïðîãðàììó ñîâåðøåííî íåâîçìîæíî.Êàòåãîðè÷åñêè íåäîïóñòèì òàêæå è ñëåäóþùèé âàðèàíò:while p <> nil do begins := s + p^.data;p := p^.next end;while (p) {s += p->data;p = p->next; }äëÿ çàêðûâàþùåé îïåðàòîðíîé ñêîáêè îáÿçàòåëüíî äîëæíà áûòü îòâåäåíà îòäåëüíàÿñòðîêà, èíà÷å, îïÿòü-òàêè, êîíåö ñëîæíîãî îïåðàòîðà áóäåò ñëîæíî óâèäåòü.
Ñ äðóãîé ñòîðîíû, ïîñëå îòêðûâàþùåé îïåðàòîðíîé ñêîáêèâ ñòðîêå íå äîëæíî áûòü íè÷åãî, çà èñêëþ÷åíèåì ðàçâå ÷òî êîììåíà ðàâíî è ëþáûå âàðèàöèè íà åãî òåìó;òàðèåâ, òàê ÷òî ñëåäóþùèé ïðèìåð òîæå íåäîïóñòèì:while p <> nil dobegin s := s + p^.data;p := p^.nextend;while (p){s += p->data;p = p->next;}Åñëè òðè âûøåïðèâåä¼ííûõ ïðèìåðà âçÿòû àâòîðîì èç ïðîãðàìì, íàïèñàííûõ ñòóäåíòàìè è äðóãèìè íîâè÷êàìè, òî ñëåäóþùèé ¾ñòèëü¿ áûë,êàê ýòî íè ñòðàííî, îáíàðóæåí â èñõîäíîì òåêñòå ïðîãðàììû, íàïèñàííîé ïðîôåññèîíàëüíûì ïðîãðàììèñòîì è, áîëåå òîãî, äîñòàòî÷íî øèðîêîèñïîëüçóåìîé. Òåì íå ìåíåå, îí òîæå íåäîïóñòèì:while p <> nil do begins := s + p^.data;p := p^.nextend;while (p) {s += p->data;p = p->next;}Êàê óæå, íåñîìíåííî, äîãàäàëñÿ ÷èòàòåëü, çäåñü çàêðûâàþùàÿ îïåðàòîðíàÿ ñêîáêà îïÿòü ñëèâàåòñÿ ñ îêðóæàþùèì òåêñòîì è íå äà¼ò âîçìîæíîñòè óâèäåòü êîíåö ñëîæíîãî îïåðàòîðà ðàñôîêóñèðîâàííûì âçãëÿäîì.Âîçâðàùàÿñü ê äîïóñòèìûì âàðèàíòàì ñî÷åòàíèÿ çàãîëîâêà îïåðàòîðà while è ñîñòàâíîãî îïåðàòîðà, èñïîëüçóåìîãî â êà÷åñòâå òåëà, ìû39ìîæåì çàìåòèòü, ÷òî ïðèíöèïèàëüíî ðàçëè÷íûõ âàðèàíòîâ ñóùåñòâóåòâñåãî òðè:1.
îòêðûâàþùàÿ îïåðàòîðíàÿ ñêîáêà ïèøåòñÿ íà îäíîé ñòðî÷êå ñ çàãîëîâêîì, çàêðûâàþùàÿ ðàçìåùàåòñÿ òî÷íî ïîä íà÷àëîì çàãîëîâêà,ñîäåðæèìîå ñîñòàâíîãî îïåðàòîðà ñäâèãàåòñÿ íà îäèí îòñòóï îòíîñèòåëüíî íà÷àëà çàãîëîâêà;2. îòêðûâàþùàÿ îïåðàòîðíàÿ ñêîáêà ñíîñèòñÿ íà ñëåäóþùóþ ñòðîêóïîñëå çàãîëîâêà è ñòàâèòñÿ òî÷íî ïîä íà÷àëîì çàãîëîâêà, çàêðûâàþùàÿ ïèøåòñÿ òî÷íî ïîä íåé (è ïîä íà÷àëîì çàãîëîâêà), ñîäåðæèìîå ñîñòàâíîãî îïåðàòîðà ñäâèãàåòñÿ íà îäèí îòñòóï;3. îòêðûâàþùàÿ îïåðàòîðíàÿ ñêîáêà ñíîñèòñÿ íà ñëåäóþùóþ ñòðîêóïîñëå çàãîëîâêà è ñäâèãàåòñÿ îòíîñèòåëüíî çàãîëîâêà íà îäèí îòñòóï, çàêðûâàþùàÿ ïèøåòñÿ òî÷íî ïîä íåé, ñîäåðæèìîå ñîñòàâíîãîîïåðàòîðà ñäâèãàåòñÿ åù¼ íà îäèí îòñòóï (òî åñòü íà äâà îòñòóïà îòíîñèòåëüíî çàãîëîâêà è íà îäèí îòíîñèòåëüíî îïåðàòîðíîéñêîáêè).Âûøå ìû ïðèâåëè ïðèìåðû êîäà äëÿ êàæäîãî èç ýòèõ âàðèàíòîâ. Êàêóæå ãîâîðèëîñü, âû ìîæåòå âûáðàòü äëÿ ñåáÿ ëþáîé èç íèõ (õîòÿ ïîñëåäíèé èç ïåðå÷èñëåííûõ ìû áû âñ¼ æå íå ðåêîìåíäîâàëè), âàæíî ëèøüïðèäåðæèâàòüñÿ îäíîãî ñòèëÿ íà ïðîòÿæåíèè âñåé ïðîãðàììû.
Îòìåòèì,÷òî âûáîð îäíîãî èç ýòèõ ñòèëåé âëèÿåò íå òîëüêî íà îôîðìëåíèå îïåðàòîðà while, íî è íà âñå îñòàëüíûå ñëîæíûå îïåðàòîðû, òåëîì êîòîðûõñëóæèò ñîñòàâíîé îïåðàòîð.Îòìåòèì åù¼ îäèí íåìàëîâàæíûé ìîìåíò. Èñõîäíî ñîñòàâíîé îïåðàòîð ïðåäíàçíà÷àëñÿ äëÿ îáúåäèíåíèÿ íåñêîëüêèõ îïåðàòîðîâ â îäèí, íîñóùåñòâóåò öåëûé ðÿä ñëó÷àåâ, â êîòîðûõ ðåêîìåíäóåòñÿ (à â íåêîòîðûõ âàðèàíòàõ ñòèëåé äàæå òðåáóåòñÿ ) îáðàìëåíèå ñîñòàâíûì îïåðàòîðîì îäíîãî îïåðàòîðà, èëè äàæå èñïîëüçîâàíèå ñîñòàâíîãî îïåðàòîðà,íå ñîäåðæàùåãî âíóòðè íè îäíîãî îïåðàòîðà.  ÷àñòíîñòè,åñëè òåëîìñëîæíîãî îïåðàòîðà ÿâëÿåòñÿ, â ñâîþ î÷åðåäü, ñëîæíûé îïåðàòîð, â îñîáåííîñòè if ñ âåòêîé else, òî â áîëüøèíñòâå ñëó÷àåâåãî æåëàòåëüíî ¾îáåðíóòü¿ â îïåðàòîðíûå ñêîáêè, äàæå åñëè îíîäèí; ÷èòàåìîñòü ïðîãðàììû ìîæåò ïðè ýòîì âîçðàñòè.
Ïîä÷åðêí¼ì, ÷òîâ áîëüøèíñòâå ñëó÷àåâ ýòî èìåííî ðåêîìåíäàöèÿ, à íå òðåáîâàíèå, è, áîëåå òîãî, âû ìîæåòå â íåêîòîðûõ ñëó÷àÿõ ñëåäîâàòü åé, à â íåêîòîðûõ íåò, â òîì ÷èñëå è â ðàìêàõ îäíîé ïðîãðàììû.×òî êàñàåòñÿ ïóñòûõ îïåðàòîðíûõ ñêîáîê, òî ýòî ñïåöèôè÷åñêàÿ ðàçíîâèäíîñòü ïóñòîãî îïåðàòîðà, êîòîðàÿ õîðîøî çàìåòíà â êîäå, è ýòîñâîéñòâî ìîæíî èñïîëüçîâàòü äëÿ ïîâûøåíèÿ ÷èòàåìîñòè âàøåãî òåêñòà.Êàê èçâåñòíî, â Ïàñêàëå è â Ñè ìîæíî ñäåëàòü ïóñòîé îïåðàòîð, ïðîñòî40ïîñòàâèâ ñèìâîë ¾;¿ (òî÷êó ñ çàïÿòîé), è êîãäà, íàïðèìåð, íóæíî ïîìåòèòü ìåòêîé êîíåö ñîñòàâíîãî îïåðàòîðà (äëÿ ÷åãî òðåáóåòñÿ ïóñòîéîïåðàòîð), òî èìåííî òàê è ïîñòóïàþò.
Íîåñëè òåëîì ñëîæíîãî îïåðàòîðà (îáû÷íî öèêëà) äîëæåí ñòàòü ïóñòîé îïåðàòîð, òî ëó÷øåèñïîëüçîâàòü ïóñòûå îïåðàòîðíûå ñêîáêè, íåæåëè òî÷êó ñ çàïÿòîé. Äåëî â òîì, ÷òî òî÷êó ñ çàïÿòîé î÷åíü ëåãêî íå çàìåòèòü, â îñîáåí-íîñòè ïðè áåãëîì ïðîñìîòðå ïðîãðàììû, è òîãäà âàì ìîæåò ïîêàçàòüñÿ,÷òî îïåðàòîð, ñëåäóþùèé íåïîñðåäñòâåííî çà ¾ïóñòîòåëûì¿ öèêëîì, ÿâëÿåòñÿ åãî òåëîì, à íà òî, ÷òîáû óñòàíîâèòü äåéñòâèòåëüíîå ïîëîæåíèåâåùåé, óéä¼ò íåñêîëüêî ëèøíèõ ñåêóíä óìñòâåííîãî íàïðÿæåíèÿ.
Íàïðèìåð, âìåñòîwhile wait(nil) <> -1 do;while (wait(NULL) != -1);ëó÷øå áóäåò íàïèñàòüwhile wait(nil) <> -1 dobeginend;while (wait(NULL) != -1){}Îòìåòèì, ÷òî ïóñòîå òåëî öèêëà ÷àñòî îñòàâëÿþò íà îäíîé ñòðîêå ñ çàãîëîâêîì. Ýòî äîïóñòèìî, õîòÿ ìû áû ðåêîìåíäîâàëè òàê íå äåëàòü, îñîáåííî åñëè ýòî òî÷êà ñ çàïÿòîé, à íå ïóñòûå ñêîáêè. Åñëè âû âîçüì¼òå ñåáå çàïðàâèëî íèêîãäà íå îñòàâëÿòü òåëî öèêëà â ñòðîêå çàãîëîâêà, äàæå êîãäàîíî ïóñòîå, ñëó÷àé ¾òî÷êà ñ çàïÿòîé â êîíöå çàãîëîâêà¿ áóäåò â âàøåéïðîãðàììå íåäîïóñòèìûì, è ýòî äîâîëüíî óäà÷íî, ïîñêîëüêó â áîëüøèíñòâå ñëó÷àåâ òàêàÿ òî÷êà ñ çàïÿòîé îêàçûâàåòñÿ ïîñòàâëåíà ïî îøèáêå,à ïîñêîëüêó çàìåòèòü å¼ òðóäíî, ýòî ïðèâîäèò ê íåïðèÿòíûì îøèáêàìâ ðàáîòå ïðîãðàììû.
Çàâåäîìàÿ íåäîïóñòèìîñòü òàêîé ñèòóàöèè ïîçâîëÿåò, óâèäåâ çàãîëîâîê ñ òî÷êîé ñ çàïÿòîé íà êîíöå (ïîâåðüòå, õîòÿ áûðàç âû ýòó îøèáêó ñäåëàåòå), íåìåäëåííî è áåç ðàçäóìèé ïðèñòóïèòü êèñïðàâëåíèþ îøèáêè.2.1.2. Îïåðàòîð if ñ âåòêîé elseÊàê Ïàñêàëü, òàê è Ñè/Ñè++ äîïóñêàþò èñïîëüçîâàíèå îïåðàòîðàâåòâëåíèÿ êàê â ïîëíîì âàðèàíòå ñ âåòêîé else, òàê è â ñîêðàù¼ííîì áåç íå¼. Åñëè âåòêà else îòñóòñòâóåò, òî îïåðàòîð if îôîðìëÿåòñÿàáñîëþòíî òàê æå, êàê è îïåðàòîð while, êîòîðûé ìû ïîäðîáíî îáñóäèëè â ïðåäûäóùåì ïàðàãðàôå.
Íèêàêîé ñâîáîäû íàì íå îñòàâëÿåò òàêæåè ñëó÷àé, êîãäà îáå âåòêè ïðèñóòñòâóþò, íî ñîñòîÿò èç îäíîãî ïðîñòîãîîïåðàòîðà, òî åñòü íå òðåáóþò èñïîëüçîâàíèÿ îïåðàòîðíûõ ñêîáîê:41if p <> nil thenres := p^.data;elseres := 0if (p)res = p->data;elseres = 0;Íóæíî òîëüêî íå çàáûâàòü, ÷òî òåëî âñåãäà ñëåäóåò ðàçìåùàòü íà îòäåëüíîé ñòðî÷êå, è â ñëó÷àå îïåðàòîðà if ýòî êàñàåòñÿ îáåèõ âåòâåé. Òàê,ñëåäóþùèå âàðèàíòû íåäîïóñòèìû:if p <> nil then res := p^.dataelse res := 0;if (p) res = p->data;else res = 0;Ðàññìîòðèì òåïåðü ñëó÷àé, êîãäà îáå âåòâè îïåðàòîðà if èñïîëüçó ýòîé ñèòóàöèè íóæíî ïðåæäå âñåãî âñïîìíèòü, êàêîé èç òð¼õ âàðèàíòîâ ðàçìåùåíèÿ îòêðûâàþùåé îïåðàòîðíîéñêîáêè, ïåðå÷èñëåííûõ â êîíöå ïðåäûäóùåãî ïàðàãðàôà, ìû âûáðàëè.Åñëè íàø âûáîð ïàë íà âòîðîé èëè òðåòèé âàðèàíò (â îáîèõ ñëó÷àÿõîòêðûâàþùàÿ îïåðàòîðíàÿ ñêîáêà ñíîñèòñÿ íà ñëåäóþùóþ ñòðîêó), òîâñ¼ îêàçûâàåòñÿ äîñòàòî÷íî ïðîñòî.
Åñëè ìû ðåøèëè íå ñäâèãàòü ñêîáêèñîñòàâíîãî îïåðàòîðà, à ñäâèãàòü òîëüêî åãî òåëî, if ïðèä¼òñÿ îôîðìèòüòàê:þò ñîñòàâíîé îïåðàòîð.if p <> nil thenbeginflag := true;x := p^.dataendelsebeginnew(p);p^.data := xendif (p){flag = true;x = p->data;}else{p = malloc(sizeof(*p));p->data = x;}Åñëè æå âû, íåâçèðàÿ íà âñå íàøè ñòàðàíèÿ, èçáðàëè âàðèàíò ñî ñäâèãîì îïåðàòîðíûõ ñêîáîê, òî if áóäåò âûãëÿäåòü òàê:if p <> nil thenbeginflag := true;x := p^.dataendelsebeginnew(p);p^.data := xendif (p){}else{}flag = true;x = p->data;p = malloc(sizeof(*p));p->data = x; îáîèõ ñëó÷àÿõ else âìåñòå ñî ñêîáêàìè çàíèìàåò òðè ñòðîêè, ÷òîíåñêîëüêî ìíîãîâàòî äëÿ ðàçäåëèòåëÿ.
Èìåííî ïîýòîìó ýòè âàðèàíòû(âòîðîé è òðåòèé) íå ñëèøêîì ïîïóëÿðíû ó ïðîôåññèîíàëîâ, õîòÿ, íåñîìíåííî, äîïóñòèìû. ×òî êàñàåòñÿ âàðèàíòà, ïðè êîòîðîì îòêðûâàþùàÿ42îïåðàòîðíàÿ ñêîáêà îñòàâëÿåòñÿ íà îäíîé ñòðîêå ñ çàãîëîâêîì, òî â ýòîìñëó÷àå äëÿ âåòêè else òàêæå îñòà¼òñÿ äâà âàðèàíòà, à èìåííî: ïîìåñòèòüñëîâî else íà îäíîé ñòðîêå ñ çàêðûâàþùåé îïåðàòîðíîé ñêîáêîé èëè æåïèñàòü else ñ íîâîé ñòðîêè.
Ïåðâûé âàðèàíò âûãëÿäèò òàê:if p <> nil then beginflag := true;x = p^.dataend else beginnew(p);p^.data := xendif (p) {flag = true;x = p->data;} else {p = malloc(sizeof(*p));p->data = x;}Íàäî îòìåòèòü, ÷òî èìåííî ýòîò âàðèàíò íàèáîëåå ïîïóëÿðåí ó ïðîôåññèîíàëüíûõ ïðîãðàììèñòîâ, íî è âòîðîé âàðèàíò âïîëíå äîïóñòèì (áîëååòîãî, ìîæíî íàéòè àðãóìåíòû â åãî ïîääåðæêó):if p <> nil then beginflag := true;x := p^.dataendelse beginnew(p);p^.data := xendif (p) {flag = true;x = p->data;}else {p = malloc(sizeof(*p));p->data = x;}Ðàññìîòðèì òåïåðü ñëó÷àé, êîãäà òîëüêî îäíà âåòêà êîíñòðóêöèèif-else òðåáóåò èñïîëüçîâàíèÿ ñîñòàâíîãî îïåðàòîðà, òîãäà êàê âòîðàÿñîñòîèò èç îäíîãî ïðîñòîãî îïåðàòîðà.