Back to site
Since 2004, our University project has become the Internet's most widespread web hosting directory. Here we like to talk a lot about web servers, web development, networking and security services. It is, after all, our expertise. To make things better we've launched this science section with the free access to educational resources and important scientific material translated to different languages.

Kako Kodirati: Pascal

Stan Sieler

sieler@allegro.com



0. Uvod

Ovaj rad se bavi time, kako napisati dobar Pascal kod. Fokus je na aspektima kodiranja Pascal koda.

Uzorak programa: roman.p.txt program koji konvertuje rimske brojeve u arapske brojke.

Uzorak lošeg koda: iseći, pravi deo lošeg koda u realnom svetu.

Kako da tražite pomoć: ovde

Napomena: Ovaj rad koristi Pascal/IX, Pascal na HP 3000 kompjuteru, ali skoro sve tačke važe za bilo koju verziju Pascala, a većina se može primeniti i na ostale programske jezike.

Želeo bih da rasprave u ovom radu pokriju četiri stavke programiranja: filozofiju, performanse, probleme i prenosivost. Razmatrao sam da podelim ovaj rad u četiri poglavlja, jedno za svaku stavku, ali sam shvatio da mnoge teme koje bi stavio u jedno poglavlje mogao usled podjednako dobrih argumenata da se stave u drugo. Dakle, umesto ta četiri, organizovali smo ovaj rad u ova poglavlja: Stil, izbori pri kodiranju, problemi sa performansama, i prenosivost.

U svakom poglavlju, četiri principa se koristi kao principi na kojima se zasniva skup smernica. Ova predložena pravila ne treba posmatrati kao da su 10 (ili 12 ) zapovesti. To su moja pravila, ona koja sam koristio (u različitim oblicima za različite jezike), u pisanoj formi sa preko milion linija koda. Smernice treba da rastu kao ljudi. Da se osvrnemo na programe koje sam pisao u 1970 i da vidimo promene u stilu u godinama koje dolaze. Uprkos promenama, ukupni izgled je i dalje isti.

Osnovna svrha ovog rada je da podstakne čitaoce da razmišljaju o različitim aspektima stila i formiraju sopstveno kodiranje. Ovo je važno za pisanje programa u osnovi... u Pascal ili bilo kom jeziku.

Ja sam napisao preko milion linija koda, jezika visokog nivoa u 1970. Ovo naravno uključuje i neke prazne redove, linije komentara i linije koje su klonirane iz drugih datoteka. Međutim, ova veza me je naučila da je "izgled" programa veoma važan za razumevanje šta čini kod.


Sadržaj

Glavne sekcije su: 0.1 Kodovi za bacanje:

Smernice:

# 1-1. Ne postoji stvar kao što su Kodovi za bacanje. Dakle, vaše smernice se odnose na sve što pišete. Posebno "throwaway" ili "one-shot"

Komentar:

#1-1. Primetio sam da skoro uvek ponovo koristim svoj program koje je za bacanje. I ako mi uštedi na korišćenju smernica, ja uvek moram da platim za to kasnije.

(Povratak na Sadržaj ).

1. Stil

Stil,ili nedostatak istog, može dramatično da utiče na kvalitet programa. Kvalitetan kod mora biti napisan na način koji je tačan, efikasan i održiv. Izbor, a posle i doslednost stilu može povećati verovatnoću da je svaki od ova tri cilja postignut. Ovaj odeljak će raspravljati prvo o promenljivim, a onda o ostatku programa:

(Povratak na Sadržaj )

1.1 Ime: Prvi koraci

Jedan od ključeva uspešnog programa je pravi izbor imena.

Pascal-ov ključ uspeha leži u boljem razumevanju podataka za rukovanje programom. Ovo razumevanje se ogleda u izboru strukture podataka i promenljivih koje koristi program.

U ovom radu termin "ime", kada se koristi bez kvalifikacija, odnosi se na imena promenljivih, konstanti, tipova, procedura, i funkcija.

Smernice

# 1-11. Koristite imenice za promenljive, konstante i vrste, koristeći procedure i funkcije.

#1-12 Vrste treba da imaju ""_type" na kraju svog imena

#1-13 Ime bi trebalo da u potpunosti bude napisano malim slovima, sa podvlakom ("_"), koja razdvaja reči (npr. card_counter)

Komentari

#1-11 Sledeći primer, mora da bude dovoljan da pokaže važnost ovog vodiča:
   if card_count = 52 then
Da li je "card_count" celobrojna promenljiva ili funkcija? Razlika je od suštinskog značaja za razumevanje programa. Orijentacija je moguća samo ako čitalac razume engleski jezik. (Pravilo kapitalizacije nije bilo dovoljno!)

Važno je da zapamtite da će drugi ljudi čitati kod jednog dana. ("Drugi" obuhvata i vas, jedan dan nakon pisanja koda!) Oni će morati da imaju "tragove" koji će im pomoći da pravilno interpretiraju očitavanje kodova.

Prema uputstvu # 1-11 "Card_count" je promenljiva . Ako je to trebalo da bude funkcija, onda je njegovo ime trebalo biti nešto poput "count_the_cards" ..

#1-12 Neki programeri dodaju "t_", "typ_", or "type. Drugi dodaju "_t", "_typ", or "_type". Neke izgubljene duše su toliko opčinjene idejom da se d "t_" I "_type za svaku vrstu.

Osnovna ideja je da se napravi jasno definisana razlika imena koja definiše korisnik i promenljivih i procedura. (ili funkcija)

# 1-13. Ovaj vodič odražava činjenicu da govorimo engleski. Da smo govorili nemački, naši programi bi najverovatnije koristili velika slova na početku svake promenljive. Obratite pažnju koliko je manje čitljivo.

Pronađite tri razloga za kapitalizaciju prvog slova (ili svih) nekih vrsta. Ni jedan to ne zaslužuje: .. ( Povratak na Sadržaj)

1,2 Ime: Više detalja

Imena tipova treba da budu opisna i jasno prepoznatljiva kao vrsta, i da se izdvajaju kada se koriste.

smernice:

# 1-21 opšti tip koji pakuje niz treba da se zove "pac" sa brojem slova.
   type
      pac8        = packed array [1..8] of char;
      pac80       = packed array [1..80] of char;
# 1-22. Vrste koje su nizovi moraju da imaju "niz" u njihovim imenima. (Izuzetak: PAC## Ime tipa (vidi # 1-21).)

# 1-23. Vrste indikacije treba da imaju "PTR" u svojim imenima. Vrste koje su dugi pokazivači (64-bitni) treba da imaju "lptr" u njihovim imenima. (U Pascal/IX, obični pokazivači su 32-bitni ... "dug" indikator je onaj koji može da pokaže bilo gde u memoriji.)

# 1-24. Trebalo bi da imate zapis domena sa prefiksom koji odražava kome oni pripadaju..

# 1-25 Prosti tipovi ne bi trebalo da odražavaju "veličinu"..

# 1-26 Pokušajte da izbegavate "tačno" i "lažno" za funkcionalne rezultate. Umesto toga koristite tip "good_failed_type"

Primedba:

# 1-21 Pascal jezik ima posebna pravila za određene varijable koje su pakovane u nizu, sa donjom granicom 1. Ova posebna pravila su dodata u pokušaju da se napravi korisna Pascal standardna manipulacija teksta. Kao rezultat toga, većina implementacije Pascal odnosi se na "CAP" kao promenljivu (ili tip), koji je niz pakovan sa manjim limitom od 1. Zato je zgodno da odražava ovu standardizaciju u našim tipovima.

Imajte na umu da ovo uputstvo pominje generičke tipove. Kada koristim TurboIMAGE (a DBMS na HP 3000), i kada želim da stvorim neku vrstu koja odgovara elementu slike, ja ću pokušati da dam ime, koji je slično elementu:
         {IMAGE items:     }
         {   cust_name x20;}

   type
      cust_name_type          = packed array [1..20] of char;
U gore navedenom primeru, koristio sam "20" u deklaraciji tipa samo zato što je vrednost bila neposredno očigledna (s obzirom naIMAGE ). Stalno se koristi "20", kasnije u programu. Ako treba da se odnosi na "20", koristio bi Pascal/IX konstrukciju "sizeof (cust_name_type)" ili bih dodao "const = cust_name_len 20" i koristi tu konstantu da proglasim snimanje.

# 1 -24. Ovaj vodič čini polje snimanja odmah prepoznatljivim kada se koristi sa "sa" izjavom. Primer:
Loše:
   type
      hpe_status  = record  {name matches MPE/iX's usage}
         info : shortint;
         subsys : shortint;
         end;
      hpe_status_ptr_type = ^ hpe_status;
      ...
   var
      hs_status_ptr : hpe_status_ptr_type;
   ...
   with hs_status_ptr^ do
      begin
      info := my_info;
      subsys := my_subsys;
      end;
Dobro:
   type
      hpe_status              = record       {name matches MPE/iX's usage}
         hs_info              : shortint;
         hs_subsys            : shortint;
         end;

   ...
   with hs_status_ptr^ do
      begin
      hs_info := my_info;
      hs_subsys := my_subsys;
      end;
U lošem primeru, čitalac koji je upoznat sa ovim kodom će znati da se menjaju pokazivači polja. U ovom primeru, to je očigledno.

#1-25 U SPL (slično programskom jeziku Algol) sasvim je uobičajeno da se koriste sufiks ili prefiks da bi se ukazalo na "tip" promenljive. (Primer: Dvostruko ktr'd). Pošto je Pascal ograničen na isti tip, ovo je mnogo manje potrebno..

# 1-26 "Tačno" i "lažno", malo znači samo po sebi. Primeri:
Loš:
   function open_files : boolean;
      ...
      open_files := false;
   ...
   if open_files then
      ...
Dobro
   type
      good_failed_type        = (failed, good);

   function open_files : good_failed_type;
      ...
      open_files := good;
   ...
   if open_files = failed then
      ...
U lošem primeru, čitalac nema pojma da li ili ne "open_files" vraćaju dobre vrednosti ili loše.

Ovo je posebno važno kada se programira u okruženju sa različitim jezicima ( i različitim operativnim sistemima) jer imaju čudne ideje o tome da li "0" (ili "netačno"), znači dobro ili loše.

(Povratak na Sadržaj )

1.3 Sređivanje izvora

Sređivanje izvornih kodova može dramatično uticati na čitljivost programa. Smernice su podeljene u tri polja. Vrste i konstante, promenljive, procedure i funkcije

Smernice:

# 1-31. Jednostavne konstante treba postaviti na početak deklaracije oblasti, zatim vrste, strukturne konstante i onda promenljive. U okviru svake grupe, identifikatore treba organizovati po nekom redu. Ako ne, onda po abecednom redu. Primer:
   const
      max_queues              = 10;

   type
      aardvark_quantity_type  = 0..9;
      queue_name_type         = packed array [1..8] of char;
      queue_names_type        = array [1..max_queues] of queue_name_type;
      zoo_fed_arrdvarks_type  = array [aardvark_quantity_type] of integer;
# 1-32. Ne više od jedne instance "Tip", i "var" je potrebno, i do dve instance "const" (jedna za jednostavne konstante, i jedan za strukturnu konstantu)..

# 1-33 Identifikatore u deklaraciji (konstante, tipovi, promenljive) treba proglasiti jednog po liniji, nekim redosledom. Abeceda je podrazumevana. Ako se koristi drugi poredak, treba objasniti komentarom.

# 1-34. Identifikatore u deklaraciji treba postaviti tako da je "=" karakter u ravni sa konstantama i vrstama, a ":" karakteri su poravnati sa promenljivim i poljima snimanja

#1-35 Vrste zapisa koji sadrži evidenciju ne bi trebalo da bude proglašena kao "anonimna vrsta". Primeri dobre i loše prakse su:
Loše:
   type payment_record_type = record
         pay_date : date_type;
         pay_time : time_type;
         pay_style : (paid_cash, paid_check, paid_charge);
         end;
Dobro
   type
      payment_style_type      = (paid_cash, paid_check, paid_charge);

      payment_record_type     = record
         pay_date             : date_type;
         pay_time             : time_type;
         pay_style            : payment_style_type;
         end;
# 1-36. "Crunched" evidenciju treba izbegavati, osim ako je potrebno čvrsto pakovanje oblasti prevazilazi gubitak performansi koje uzrokuju.

"Pascal/IX podržava "Crunched evidenciju" produžetak jednostavnog "punog zapisa". U crunched zapisu * ne * postoje neiskorišćeni bitovi. Ako proglasite crunched zapis u 1bit-nom, a zatim 8-bitnom polju, gde sledi 1-bitno polje, ceo zapis će zauzeti 10-bita, a 8-bitno polje će zahtevati dodatne kodove za učitavanje/čuvanje.

# 1-37. Velika spoljna promenljiva (> 256 bajta) treba da bude proglašena poslednjom, čak i ako to narušava orijentaciju # 1-33. (Slično tome, velike lokalne promenljive trebaju biti prve proglašene.) (Napomena: ovo je savet Pascal/IX za performanse... ostali kompajleri na drugim mašinama verovatno rade stvari drugačije!)

# 1-38. Procedure i funkcije su mešovite (npr. ne odvajati funkcije od postupka) ..

#1-39 Procedure (i funkcije) bi trebalo da budu proglašene po nekom redosledu (abecedno je podrazumevano)

# 1-40 Procedure više od jednog nivoa treba izbegavati.

# 1-41 Unutrašnje treba jednom prijaviti, na spoljnom nivou, posle svih konstanti, tipova, i promenljivih, i pre nego što bilo koje"external", "forward", ili stvarne procedure. (“intrinsic"je referenca na nekoj vrsti unapred sastavljene izjave "spoljnim" postupkom, uz podršku većine jezika na HP 3000.)

# 1-42. Unutrašnje treba organizovati po abecedi Unutrašnjih datoteka. Primer:
   Function ascii    : shortint;  intrinsic;
   Function binary   : shortint;  intrinsic;
   Procedure quit;                intrinsic;
U gore navedenom primeru, dva mesta su ostavili posle reči: "funkcija", tako da će imena Unutrašnjih biti usklađena, bez obzira da li su funkcije ili procedure. Otežavajuće je što nam Pascal kompajler traži da dokažemo da znamo tip svake suštinske funkcije.

Obratite pažnju na "P" i "F" u gornjem primeru. Ovo je veoma dobar primer discipline kodiranja koja je objašnjena u vodiču #1-45 ispod

#1-43..Sve procedure i funkcije moraju biti deklarisane sa izjavom "pre" koje su po abecednom redosledu..

# 1-44 Vrste koje su "punile" treba da se izjasne kao "celina" ili "bajt" (gde je "bajt" proglašen 0 .. 255), umesto "char" za njihove osnovne vrste.

# 1-45. Deklaracije procedura "pre", "spoljni" i "unutrašnji" (i funkcije) treba da imaju veliko prvo slovo u "Procedure" i"Funkcija"

Komentari

# 1-34.. Ja uglavnom poravnam "=" za tipove i konstante u koloni 31; ":" polja u okviru vrste, takođe u koloni 31, i ":" za promenljive u koloni 19. Ako promenljive imaju dovoljno duga imena , često jednostavno poravnam ":" u koloni 31. Ja primenjujem ovo ravnanje na ":" koje se koristi u izjavama parametara, tako da ime promenljive počinje u koloni??:
   procedure parse_gribbitz (
                  a_token     : str80;
              var status      : boolean;
           anyvar stuff       : char)
         option default_parms (
                  stuff       := nil);
U gore navedenom primeru, imajte na umu da su poravnati parametri imena. (Naravno, ovo nije uvek moguće, naročito ako je parametar $poravnat$ sa određenim informacijama.) (Napomena: "anyvar" će se ponovo videti u nastavku 2-9)

# 1-35. Promenljive (evidencija i polja) koji su anonimne vrste, ne mogu biti zaobiđene (kao "var" parametar) normalnim procedurama. Zaista, anonimne evidencije obično ne mogu da se prenose po vrednosti u procedurama.

# 1-36. Pristup polju "crunched" zapisa može da potraje i do tri puta više od instrukcija koje će biti potrebne ukoliko zapis nije crunched. Razmotrite sledeća dva tipa:
   type
      bad_type                = crunched record
         bad_misc             : shortint;    {Bytes 0, 1}
         bad_status           : integer;     {Bytes 2, 3, 4, 5}
         end;  {Total size: 6 bytes}

      good_type               = record
         good_misc            : shortint;    {Bytes 0, 1}
         good_status          : integer;     {Bytes 4, 5, 6, 7}
         end;  {Total size: 8 bytes}
Kada se pristupilo "bad_status" polju, Pascal/IX je izdao tri pravila (LDH, LDH i DEP). Kada se pristupi "good_status" polju, Pascal/IX izdaje jedno uputstvo (LDV)..

# 1-37 Pascal/IX može efikasno pristupiti samo u prvih 8192 bajtova globalno ili * 8192 * poslednjih bajtova lokalno promenljivih. Pascal/IX dodeljuje promenljive (približno) prvi put viđene, na prvi način dodeljivanja . Tako je, na globalnoj varijabli, stavljanje male prvo, a velike na kraju, efikasnije. Za lokalne promenljive, stavljanje najvećih prvo, a manjih posle, ima tendenciju da budu efikasnije.

Jer Pascal/IX dodeljuje spoljni blok ("globalno") promenljive u obrnutom redosledu nego lokalne promenljive. Razmotriti sledeće primere
Loše:
   var                                 {outer-block variables}
      big_array   : array [0..9999] of integer;  {40,000 bytes}
      ktr : integer;
   ...
   procedure foo;
      var
         ktr2     : integer;
         big_array_2 : array [0..9999] of integer; {40K bytes}
Dobro
   var                                 {outer-block variables}
            {small variables...}
      ktr         : integer;

            {big variables...}
      big_array   : array [0..9999] of integer;
   ...
   procedure foo;
      var
               {big variables...}
         big_array_2 : array [0..9999] of integer; {40K bytes}

               {small variables...}
         ktr2     : integer;
U lošem primeru, Pascal/IX će koristiti dva uputstva za pristup "KTR" i "ktr2". U dobrom primeru Pascal/IX će koristiti jednu instrukciju da pristupi "KTR" i "ktr2"..

# 1-38 Pascalova diferencijacija funkcija naspram procedura nije najsređnija, u najboljem slučaju. Ne treba da podstičemo dizajnere jezika da ovekovečuju ovaj kvar..

# 1-39 Pascal/IX $ocialiti", izjava može da se koristi da kaže Linker-u da grupiše određene procedure zajedno, bez obzira na njihov redosled u izvornom kodu..

# 1-40 Pascal dozvoljava procedurama da se proglase unutar procedura koji su proglašene unutar procedura.....

Procedure plaćaju kaznu za run-time performanse kada se pristupa globalnim varijablama koje su lokalne okružujućim procedurama.

Procedure koje imaju više od ukupno dva duboka slučaja ( Primer: "spoljna" procedura i interni postupak) obično podrazumevaju da postoje i drugi problemi dizajna ...

Neke debageri imaju poteškoća u postavljanju tački zaustavljanja procedura.

# 1-43 ovaj dodatni rad se isplati kada se piše "modul" koji će biti povezan sa drugim programima. često sam stavio sve svoje "Forward" izjave u datoteku, a zatim koristim sledeće komande da generišem QEDIT komande da generišem fajl eksterne deklaracije za druge module:
   t myfile.forward
   c "forward"(S)"external"@
   k myfile.external
(QEDIT je editor koji se naširoko koristi na HP 3000.)

# 1-44 Debug/iX format virtual command (FV) će proizvoditi mnogo čitljiviji izlaz slučajnih podataka kada je numerički tip umesto karaktera (Debug/IX je debugger u paketu sa MPE/IX na HP 3000.)

# 1-45..Sa ovim vodičem, i jednim u sledećem odeljku, QEDIT naredba će navesti:
   l "procedure" (s)
l "procedure" (s) će izlistati prvu liniju svake deklaracije procedure. Imajte na umu da će samo stvarna izjava biti navedena, nema "napred" i "spoljne" izjave, jer bi bila proglašena sa velikim "P" u "proceduri".

Napomena: ne govorite editoru da automatski diže sav tekst koji tražite(npr. Set Window (UP) in QEDIT), to bi porazilo svrhu ovog vodiča.

(nazad )

1.4 Izvršni kod Ovaj odeljak razmatra stilove kodiranja za neke izvršni kodove za Pascal

Smernice:

# 1-50 Svi kodovi treba da budu malim slovima

# 1-51 moraju biti na engleskom, i treba da se kombinuju, kao što se radi na engleskom

# 1-52 Komentari se mogu pojaviti u jednoj od dva stila, u zavisnosti od njihove veličine Primer:
         {the following loop looks for a null character}

   null_index := -1;                   {-1 will mean "not found"}
   test_inx := 0;                      {index of first char}
   done := (len = 0);                  {don't loop if no data}

   while not done do
      begin
            {see if current character is null...}
      if buf [test_inx] = chr (0) then
         begin                         {found a null!}
         null_index := test_inx;       {remember location}
         done := true;                 {terminate loop}
         end

      else
         begin                         {incr inx, check end}
         test_inx := test_inx + 1;
         if test_inx >= len then       {inx is 0-based}
            done := true;
         end;
      end;                             {while not done}
# 1-53. Multi-line komentari mogu biti napisani sa "{" i "}" na svakoj liniji, ili "{" i "}" se pojavljuju samo jednom, na linijama za sebe.

# 1-54 "{" i "}" karakteri se koriste da se počne i završi komentar, nikad za"(*" i "*") parove.

# 1-55 '{' obično ne prati razmak, niti je "}" obično prethodi razmaku (osim ako se poravnava uz prethodnu liniju "}").

# 1-56 Linije ne bi trebalo da budu duže od 72 bajta, iako Pascal/IX dozvoljava duže ulazne linije .

# 1-57 Za prazne linije nema troškova za vreme izvođenja, i treba da se koriste za posebne delove koda Primer:
   if ktr > max_ktr then
      max_ktr := ktr;                  {remember new high water}

   done := false;
   while not done do
      begin
      ...
# 1-58. 'Kraj' izjavu ne treba komentarisati. Pascal ne proverava da li vaš komentar odgovara stvarnosti.

# 1-59 Osnovna jedinica uvlačenja je 3, a ne 4 ili 2.

# 1-60 Uvući liniju "start" za više od 3 mesta na početku prethodne linije. Kod nakon "start" (do i uključujući i "kraj") je na istom nivou kao "početak".

# 1-61 Nastavak linije je uvučen 6 mesta više nego na početku prve linije.

# 1-62 "Tada" od "ako/onda" izjava je obično na istoj liniji kao i ostatak Boolean izraza, a ne na sledećoj liniji (osim ako je neophodno za razmak, a zatim uvučeno 6), a ne na istoj liniji kao i izjave da prati "onda"..

# 1-63 "Ako" se može tretirati kao nova konstrukcija Pascal: "elseif". (Npr: "Ako" je "nešto drugo" u redu.)

# 1-64. "Goto 999" je prihvatljiv metod grananja na kraju postupka (ili funkcija)..

# 1-65 Ne postoje i drugi "goto" koji su neophodni..

# 1-66 Pokušajte da procedura bude ispod pet strana (300 linija)..

# 1-67 Nikada ne koristite reč "postupak" i "funkcija" u recenziji, u svim slučajevima su manje tačni. Umesto toga, koristite "rutinu" ili "POstupak" ili "FUnkcija"..

# 1-68 Uvek završili proceduru ili funkciju, sa komentarom kao što je:
      end {nameofroutine proc};
# 1-69. Ostavite prazno između imena postupka/funkcija i '(' parametra liste.

# 1-70 Stavite prazno posle svakog zareza u parametar listi

# 1-71 Stavite prazno oko operatera (primer: "," "+ "," - ")., a ispred leve zagrade (" [")

Komentari:

# 1-52 Poravnati komentari čine da komentar izgleda urednije. Ova praksa omogućava kod čitaču da sa lakoćom čita kod ili komentare.

# 1-55 Praksa da se uvek prati "{" sa space, a prethodi '}' gubi dragoceni prostor na liniji.

# 1-56 Duge linije neće se dobro listati na nekim terminalima, niti su prihvatljive za sve editore.

# 1-58 Dati komentar na "kraj" kada je dalje od oko 10 linija od "počni".

# 1-60. Vrednost "3" i zabrane "dvostrukog uvlačenja" štedi prostor i omogućava lako čitanje rezultata. Razmotrite sledeća dva primera:
Loš:
   for i := 1 to 10 do
       begin
           buf [i] := 0;
           foo [i] := 0;
       end;
   if ktr = 0 then
       begin
           if not done then
               begin
                   ...
Dobar:
   for i := 1 to 10 do
      begin
      buf [i] := 0;
      foo [i] := 0;
      end;

   if ktr = 0 then
      begin
      if not done then
         begin
         ...
Mnogi Pascal programeri su videli stil "duplo uvlačenje", jer ga je nastavnik zadužen za Ucsd Pascal (početkom 1970) koristio. Imajte na umu da je on pre svega bio učitelj, a ne programer.. # 1-61 Primer:
   if (card_counter = max_card_counter) and
         all_cards_accounted_for then
      begin
      ...
Cilj uvlačenja linija je da se napravi da čitaocu bude jasno da je prethodna linija otišla do naredne. Ako nema dodatnih udubljenje, onda postaje teško odrediti razliku između sledeće izjavu i nastavka trenutne izjave.

Kada imam kompleksno "i/ili" pokušavam da napravim da se lako čita, kada radite nastavak linije:
Loše:
   if ((card_counter = prior_card_counter) and ((number_of_cards_left
      > cards_for_book)) then
      begin
Dobro:
   if (      (card_counter = prior_card_counter)
         and (number_of_cards_left > cards_for_book) ) then
      begin
U lošem primeru, primetite kako je "početak" zamagljena sa "i" koji polazi od iste kolone..

# 1-62 Reč "onda" je sintaksički šećer: goji listing, i nema vrednost izbavljanja. Kada čitalac vidi "ako", on ili ona zna da "onda" automatski dolazi na kraju. Uvlačenje bi samo bilo dovoljno da kaže čitaocu da je "ako" izjava je pronađena Primeri:
Loše:
   if card_counter = max_card_counter
      then done := true
      else ...
Dobro:
   if card_counter = max_card_counter then
      done := true
   else
      ...
U gore navedenom lošem primeru, um čitaoca mora pregledati višak praznih slova.("tada") pre "urađeno: =" u cilju da se razume uticaj na "pravi" boolean izraz. U dobrom primeru, čitajući levu stranu, dovoljno ostaje..

# 1-63"If" konstrukcije se obično nalaze u jednoj od dve situacije: Primer of the "run-on" "ako/onda/ili:
   if token_check ('EXIT') then
      wrapup
   else if token_check ('LIST') then
      do_list
   else if token_check ('PRINT') then
      do_print
   else
      writeln ('Unknown command: ', token);
Napomena: u stilu kao što je gore, često sam stavljao pet razmaka pre prve "token_check ", pa komandu kao što je" LIST QEDIT token_check "će prikazati sve tri" token_check "fraze lepo poređane.

Primer "ako/onda/ili:
   if card_counter = max_card_counter then
      if done then
         ...
      else
         discard_current_card
   else
      if current_card = joker then
         try_best_wildcard
      else
         calculate_score;
Stil preporucujem prema sledecim opcijama:
   if token_check ('EXIT') then
      wrapup
   else
   if token_check ('LIST') then
      do_list
   else
   ...
Stil gore primenjen ima drastičnih posledica po čitljivost ako neblagovremeno "strana izbaci" između "drugačiji" i "ako" linije.

# 1-64 Pascal nema "Izlaz" izjavu. C i SPL imaju neki oblik "povratka iz ovog postupka "sada" izjavom. Ovo je jedino mesto gde sam koristio "Idi" u Pascal..

# 1-67 Ova smernica znači da je urednikova "naći" i "lista komandi" u potrazi za "procedura" i "funkcija" i da neće slučajno pronaći redove komentara (Vidi takođe # 1-45)..

# 1-68. Ovo čini da se vrlo lako nađe kraj svake procedure (ili sve) (e) sa "Find" komandom.

# 1-69/70/71 Praznine čini kod lakšim za čitanje, kao i Engleski. Obratite pažnju na prazno posle zareza u prethodnoj rečenici Primer:
Loš
   fid:=fopen(filename,3,0);
Dobro
   fid := fopen (filename, 3, 0);

( Povratak na Sadržaj)


2. IZBOR u kodiranju

Ovaj odeljak se bavi izborom u pisanju izvršnih kodova.

Smernice

# 2-1 Odlučite da li je vaš stil je da imate funkcije koje vrše povratak greške, ili procedure koje imaju statusa parametara (ili oboje), a zatim se pridržavajte toga.

# 2-2. Ne koristite "sa" za deferencijaciju jednostavnih indikatora. Samo koristite 'sa', gde matrica indeksira.

# 2-3 Pokušajte da izbegnete "repeat" kruga koristeći "while" umesto kruga.

# 2-4 Pokušajte da izbegavate "escape" van opsega od "pokušati/catch" bloka..

# 2-5 Izbegavajte "string" je u korist CAP. PAK je niz char opremljen sa manjim limitom od 1.

# 2-6 Koristite Pascal/IX ekstenzije god je to moguće, osim ako je prenosivost primarni cilj.

# 2-7 Za "try/recover" izradu u Pascal / IKS je vrlo korisno hvatanje grešaka: neočekivane i namerno izazvane. (Pokušaj/oporavi je mehanizam za hvatanje grešaka donekle sličan uhvati/baci u nekim drugim jezicima)

# 2-8. Koristite $type_coercion 'representation'$. Nikada ne koristite nekompatibilni tip ograničenja.

# 2-9 "Anyvar" tip parametra je koristan. Razmislite da ga koristite kada želite da dobijete različite vrste promenljivih u jednoj proceduri..

# 2-10 "uncheckable_anyvar" opcija za postupak treba da se koristi kad god je "anyvar" parametar deklarisan, pogotovo ako ne želiš Pascal/IX da prođe skriven u odnosu na "actual size" veličinu parametra.

# 2-11 Kada koristite "anyvar", uverite se da formalni parametar tipa odgovara tipu koji očekuje poravnanje ograničenja. Tj ako je formalni parametar deklarisan kao "integer", onda će Pascal/IX pretpostaviti da sve adrese navedene u ovom parametru su veće od 4. Koristite "char" (ili neki drugi tip) kao formalni parametar tipa ako želite da dobijete bilo kakvu bezbednu adresu.

# 2-12 "Default_parms" opciju postupka treba smatrati kao sredstvo da bi se skratili parametri(za obične slučajeve)

Komentari: # 2-1 Ponekad sam vratim rezultat postavljen brzo sa "good_failed_type", kao i detaljan status greške parametra. Primer:
   function open_files (var status : hpe_status) : good_failed_type;
   ...
   if open_files (status) = failed then
      report_status (status);
# 2-2. Pascal pruža "with" izjavu koja, u nekim slučajevima, može da obezbedi kompajleru trag o tome kako da optimizuje uputstva da izda kod.Plus, "with" izjava može uštedeti kucanje

Primer beskorisnog "with" je:
   var
      ptr : hpe_status_ptr_type;
   ...
   with ptr^ do
      begin
      hs_info := 0;
      hs_subsys := 0;
      end;
Ovo je "beskorisno", jer kompajler i optimizer verovatno imaju tako dobar posao da isporuči optimalan kod da sam rekao:
      ptr^.hs_info := 0;
      ptr^.hs_subsys := 0;
Imajte na umu da ovaj kod ima pet linija koristeći "with" izjavu, i dve linije bez njega.

Konačno, činjenica da su"hs_info" i "hs_subsis" zapravo polja zapisa ukazuje da je "PTR" donekle sakriven kada se "sa" koristi

Koristan primer "with" je:
   var
      statuses : array [0..9] of hpe_status_type;
   ...
   with statuses [k] do       {optimize hs_@ fields}
      begin
      hs_info := 0;
      hs_subsys := 0;
      end;
Mislim da je ovaj primer "korisan", jer bi optimizatori imali više posla pokušavajući da sastave šifru za ne-optimalne ekvivalentne izjave:
   statuses [k].hs_info := 0;
   statuses [k].hs_subsys := 0;
U gore navedenim primerima, primamljivo je da se uskladi "=" s desnom ": =" radi dodeljivanja izjave u bloku. Nekada sam često ovo radio kad sam imao četiri ili više sličnih projekata za redom.

Prednost je što je povećana čitljivost jer je jasno na šta se podaci odnose (zbog poravnatih "=" ) Loše je što će jednostavan dizajn QEDIT komande na listu gde se "hs_info" menja (npr.: SPISAK "hs_info: =") propasti. Otkrili smo da je moguće da se search-for-assignments ofset koristi kao informacija vezana za mene.

# 2-3. Kada se naiđe na "repeat", čitač neće znati šta je status prestajanja, dok ne pročita još linija programskog izvora.. To znači da on ili ona neće biti u stanju da provere tačan uslov konfiguracije prestanka. "while" krug izbegava ovaj problem, jer uslov prekida je jasno definisan na vrhu kruga.

Ponovni krug se obično može obraditi u “repeat” krug:
Pre
   repeat
      begin
      ...
      end
   until
      buf [inx] = 0;

Posle
   done := false;
   while not done do
      begin
      ...
      done := (buf [inx] = 0);
      end;          {while not done}
# 2-4. "non-local escape", košta hiljade CPU ciklusa izvršenja. Ukratko, nikada ne mislite o korišćenju ove konstrukcije kao normalnog načina da se vrati iz procedure. Primeri:
   procedure do_work;         {note:  no status parameter!}
      ...
      if problem then
         escape (i_failed);
      ...
Lose
Dobro
   procedure do_work (var status : hpe_status_type);
      label
         999;
      ...
      if problem then
         begin
         status := my_failure_status;
         goto 999;            {exit}
         end;
      ...
   999:

      end {do_work proc};
# 2-5. Krije se ogromna količina sporog i donekle pogrešnog koda koji kompajler generiše. Spajanje posebno može dovesti do "curenja memorije", ako vašem procesu ponestane heap prostora. PAC su neuredniji, ali efikasniji. Ovo je estetski učinak naspram performansi.

# 2-6. Pascal/IX je veoma korisan jezik zato što ima veliko telo ekstenzija u odnosu na standardni Pascal. Ako pazite kako ih koristite, trebalo bi da programiranje bude bolje u ANSI C ili C +

# 2-7 “Try/recover" ne garantuje da će uhvatiti sve greške koje se pojavljuju. Neočekivane greške (npr. neispravan indeks, loša virtuelna adresa) pozivaju rutinski operativni sistem nazvan trap_handler, da "ide" unazad kroz markere u potrazi za najnovijim "try/catch" blokom. Ova "šetnja" može uspeti ako je vaš štek oštećen i " Try/recover" neće biti pronađen. Ako se to desi, i ako odgovarajuća klopka (npr. XCODETRAP) nije naoružana, proces će biti obustavljen.

# 2-8 Ispravka kucanja je jedna od najboljih ekstenzija u Pascal/IX. Ona pruža kontrolisano premošćivanje Pascal tipa verifikacije. Direktiva $ type_coercion kaže Pascal/IX koji nivo ograničenja tipa želite da dozvolite u vašem programu. Postoji oko pet različitih nivoa. Nivo koji preporučujem je reprezentacija. Ovaj nivo omogućava da tip izraza bude ograničen (tretiran kao) drugačiji tip ako i samo ako su dve potpuno iste veličine (u jedinicama bitova, a ne bajtova).

Nekompatibilni nivo kaže da Pascal/IX ne bi trebao biti ograničen vrstom ispravke. Ovo dovodi do interesantnih grešaka u programima. Neki MPE/iKs padovi sistema mogu se pratiti korišćenjem ove vrste ograničenja pogrešnog tipa. Sledeći primeri pokazuju kako da se sakriju nekompatibilne greške.
pretpostavljajući:
   var
      big_ptr     : globalanyptr;
      my_address  : integer;
      small_ptr   : localanyptr;
Lose
   $type_coercion 'noncompatible'$
   my_address := integer (big_ptr);   {will get half of data!}
   my_address := integer (small_ptr); {will get 32 bit value}
Dobro
   $type_coercion 'representation'$
   my_address := integer (big_ptr);   {will get syntax error}
   my_address := integer (small_ptr); {will get 32 bit value}
U lošem primeru ograničenja big_ptr rezultati u postavljanju 32-bitne mi_address gornji big_ptr (npr. id prostor), gubitak u donjih 32 bita adrese. U primeru Pascal/IX će generisati sintaksičku grešku o pokušaju da primora neki 64bit izraz (big_ptr) u 32-bitnom vrednost (integer).

# 2-9. "Anyvar" je produžetak Pascal/IX "var". Kada je formalni parametar deklarisan kao "anyvar" kompajler dozvoljava bilo kojoj promenljivoj da bude doneta kao stvarni parametar. Bez takve funkcije, i bez objektno orijentisanog Pascal-a, nisi mogao napisati nijedan postupak koji bi obrisao proizvoljnu promenljivu (vidi dole za primer).

Kada je parametar deklarisan kao anyvar, Pascal/IX će proći stvarnu adresu parametra *i* celi skriven-po-vrednosti parametar stvarne veličine. Sledeći primer pokazuje šta je prošlo u formalnom parametar kao "foo anyvar: integer" i efekat na "sizeof (FOO)" u postupku:
Actual parameter type Hidden size field sizeof (foo)
char 1 1
shortint 2 2
integer 4 4
longint 8 8
real 4 4
longreal 8 8
hpe_status (see #1-24) 4 4
packed array [1..80] of char 80 80
# 2-10. Ja koristim "anyvar" prilično često. Primer je:
   procedure zero_var (anyvar foo : char);
         {Purpose: zero every byte in the parameter}
      var
         bytes_left           : integer;
         byte_ptr             : ^char;

      begin

   $push, range off$
      byte_ptr := addr (foo);
      bytes_left := sizeof (foo);  {Note: gets actual size!}

      while bytes_left > 0 do
         begin                     {zero one byte}
         byte_ptr^ := chr (0);
         bytes_left := bytes_left - 1;
         byte_ptr := addtopointer (byte_ptr, 1);
         end;
   $pop$          {range}

      end {zero_var proc};
Napomena komentara na $pop$ dozvoljavajući mi da se setim koje opcije $pop$ snima. Pascal/IX, $push$ čuva stanje opcija kompajlera, a $pop$ ih oporavlja. Tako $push, range of$ ... $pop$ privremeno gasi opciju "range", a zatim ga vraćaju u staro stanje... što je znatno drugačije nego da jednostavno uključite "done"!

Naravno, Pascal/IX omogućava brži način da se obriše promenljiva koja će dobro raditi sa anyvar proverljivim parametrima. Ceo kod iznad procedure (između "početak" i "kraj") može biti zamenjen:
   fast_fill (addr (foo), 0, sizeof (foo));
# 2-12. Sledeći primer, postupak koji će većina korisnika nazvati, "lažni" u drugom parametru, pokazuje korisnost "default_parms" Imajte na umu da ne bi koristili "default_parm" za parametar koji je izostavljeno manje od oko 75% vremena.
   const
      print_with_cr      = 0;
      print_without_cr   = 1;

   procedure print_msg (
                  msg                  : str80;
                  cr_or_no_cr          : integer)
         option default_parms (
                  cr_or_no_cr          := print_with_cr);

      var
         cctl_val   : shortint;

      begin

      if cr_or_no_cr = print_without_cr then
         cctl_val := octal ('320')
      else
         cctl_val := 0;

      print (msg, -strlen (msg), cctl_val);
            {Note: ignoring errors from print intrinsic}

      end {print_msg};
   ...
   print_msg ('Starting...', print_without_cr);
   print_msg ('Ending');               {does a CR/LF at end}

(Povratak na Sadržaj )


3. Problemi u performansama

Dva najveća problema performansama u Pascal/IX programa su što koriste ugrađene I/O i što koriste konce.

Smernice:

# 3-1. Izbegavajte Pascal I/O. Koristite intrinsics umesto toga.

# 3-2. Izbegavajte Pascal I/O. Koristite intrinsics umesto toga. Ovo vredi reći dva puta!

# 3-3. Izbegavajte konce u područjima kritičnim za performanse.

# 3-4. Isključite proveru opsega (opseg $off$) samo kada ste sigurni da vaš program ispravno radi.

# 3-5. Koristite Pascal/IX Optimizer ($optimize on$).

Komentar:

# 3-1. Ako uhvatite svoje I/O pozive, onda njihova osnovna implementacija može lako promeniti da koriste MPE intrinsics. Ovo takođe pomaže u prenosivosti preko operativnih sistema i preko jezika. "Print_msg" postupak u komentaru # 2-12 je primer.

Drugi razlog za izbegavanje Pascal I/O konstrukcije je efikasnost. Pascal/IX i I/O rutine su izuzetno neefikasne. Ovo uputstvo važi za većinu jezika.

# 3-3. Izrazi niti, veze izazvaju kompajler da emituje mnogo rutina poziva u "pomoć". Umesto dodele jednu radnu površinu, oni izdvajaju rutine mnogih radnih oblasti na vašoj gomili. Ovo može biti skupa aktivnost, a može dovesti do gubitka heap prostora, i eventualno prekida procesa.

# 3-5. Ako vaš program radi korektno neoptimizovan, a ima problem optimizovan, onda verovatno postoji jedna (ili više) neinicijalizovanih promenljivih. Drugi najčešći problem je korišćenje pokazivača na način koji optimizer ne očekuja (naročito kada se pristupa lokalnim promenljivim preko pokazivača).

(Povratak na Sadržaj )


4. Prenosivost

Prenosivosti programa pisanih u Pascal/IX se može dodati nekoliko tehnika. Imajte na umu, međutim, da većina drugih Pascal implementacija nisu bogate kao Pascal/IX. Delfi i Turbo Pascal (na IBM PC kompatibilnim) pružaju neke iste karakteristike kao Pascal/IX.

# 4-1. Izbegavajte ove Pascal/IX ekstenzije: proširivanje, čitanje, anyvar, opcija, uncheckable_anyvar, default_parms, globalaniptr.

# 4-2. Izbegavajte $ direktive (npr.: $ektnaddr$).

# 4-3. Koristite ispravku samo za tipove identičnih dimenzija. (Dobar savet, čak i ako nikada ne nameravate da prenesete svoj kod!) Većina PC-based Pascal-a imaju oblik ispravljanja kucanja. Oni se mogu odnositi na njega kao "type casting".

# 4-4. Izbegavajte "crunched" evidenciju. Čak većina C jezika nema funkcionalni ekvivalent. Ovo uključuje izbegavanje "$HP3000_16$ ".

# 4-5. Uhvati "čudne" konstrukcije gde je to moguće.

# 4-6. Obuhvati I/O pozive. Ovo nije toliko pitanje prenosivosti jezika, koliko pitanje performansi operativnih sistema.

# 4-7. Držite izvorni kod linija kratak (72 znaka ili manje po liniji).

# 4-8. Koristite korisnički definisane tipove poput "int16" i "Int32" umesto "shortint" ili "integer". Napomena: ovo je izuzetno važno za C programere!

# 4-9. Budite svesni da polja u zapisima mogu biti drugačije pakovana na različitim mašinama.

# 4-10. Standardni Pascal ne dozvoljava pokazivačima da ukažu na promenljive. (Oni mogu samo da ukaže gomilu.)

(Povratak na Sadržaj)


5. Rezime:

Najkraći rezime ovog rada je verovatno: možete suditi knjizi po koricama. Ako program izgleda lepo, verovatno je lep.

(Povratak na Sadržaj )



Published (Last edited): 07-09-2012 , source: http://www.allegro.com/papers/htpp.html