Rodzaje błędów w programach Wykład9.UWAGIOGÓLNE,str.1 Błąd leksykalny pojedyncza jednostka leksykalna(operator, słowo kluczowe, liczba itp.), której nie przewiduje definicja języka. Mn:=1; Sygn. błędu w C: expected expression before = token M foor(i=0; i<100; i=i+1) s=s+i; Traktowany przez C jak identyfikator. Mx=6.02F-23; Działanie nieokreślone: ignoruje F. Błędy leksykalne są na ogół nietrudne do znalezienia. Rodzaje błędów w programach Wykład9.UWAGIOGÓLNE,str.2 Błąd składniowy poprawne jednostki leksykalne są niepoprawnie zestawione. Mx=(x+1)/2); Sygn.błęduwC:expected ; before ) token Mx+1=x; Sygn. błędu w C: lvalue required as left operand of assignment M for(i=0, i<100, i=i+1); Sygn.błęduwC:expected ; before ) token Błędy składniowe są na ogół niezbyt trudne do znalezienia ale błąd może występować wcześniej, niż sygnalizuje kompilator.
Rodzaje błędów w programach Wykład9.UWAGIOGÓLNE,str.3 Błąd typowania wyrażenie użyte w kontekście, w którym potrzebne jest wyr. innego typu. Mdoublex; x=x%2; Sygn. błędu w C: invalidoperandstobinary%(have double and int ) Mdoublea[10]; a=0.1; Sygn. błędu w C: incompatible types in assignment M char tab[10]; tab[0] ="czesc"; Ostrzeżenie w C: assignment makes integer from pointer without a cast Błędy typu są niezbyt trudne do znalezienia, jeśli są sygnalizowane. Czasem niesąiwtedyjestźle... Rodzaje błędów w programach Wykład9.UWAGIOGÓLNE,str.4 Błąd semantyczny niezadeklarowanie identyfikatora, lub pomylenie zakresu jego deklaracji. Mmain() {i=0; Sygn. błędu w C: i undeclared Mdoublex; int qq(intx) {returnx; main() {x=x%2; Sygn. błędu w C: invalidoperandstobinary%(have double and int ) Brak deklaracji jest łatwy do znalezienia, jeśli jest sygnalizowany. Pomylenie zakresu może dać trudny do znalezienia błąd logiczny(patrz dalej).
Rodzaje błędów w programach Wykład9.UWAGIOGÓLNE,str.5 Błąd działania skompilowany program natrafia na niemożność dalszego działania. Mn=n/(2*n/2-n); W C zatrzymanie z komunikatem: Floating point exception M i=0; while(i<=0) { a[i]=0; i=i-1; W C zatrzymanie z komunikatem: Segmentation fault Znalezienie utrudnia fakt, że błąd może wystąpić lub nie, zależnie od danych. Przyczyną może być błąd logiczny(patrz dalej). Rodzaje błędów w programach Wykład9.UWAGIOGÓLNE,str.6 Nieskończone obliczenie obliczenie nigdy się nie kończy. Mk=0;q=0; while(n>0) {n=n-k;q=q+1; M void qq(int n) { int k; k=n/2; if(n>0){qq(k); qq(n-k); main() {qq(5); Przyczyna nieskończonego obliczenia może być trudna do znalezienia; może nią być błąd logiczny(patrz dalej).
Rodzaje błędów w programach Wykład9.UWAGIOGÓLNE,str.7 Błąd logiczny programliczynieto,cotrzeba. Mint pot2(intw) { int p,p2,x; p=2;x=1; while(w%2==0) {p=p*p;w=w/2; p2=p*p; while(w>3) {x=x*p2;w=w-2; return x*p*p2; pot2(w)=2 w jeśliwniejestpotęgą2 alejeśliwjestpotęgą2,topot2(w)=2 3w Może być bardzo trudno ustalić, dlaczego program liczy dobrze dla jednych danychaźledlainnych. Rodzaje błędów w programach Wykład9.UWAGIOGÓLNE,str.8 łatwe błąd leksykalny błąd składniowy błąd typowania błąd semantyczny błąd działania nieskończone obliczenie trudne błąd logiczny Przy programowaniu bezpośrednio w języku maszyny przeważająca większość błędów to błędy logiczne trudne do znalezienia. We współczesnych językach programowania wysokiego poziomu programista rzadziej popełnia błędy logiczne, a częściej błędy należące do łatwiejszych rodzajów.
Wykład9.UWAGIOGÓLNE,str.9 Niebezpieczne konstrukcje w jęz. programowania Brak sygnalizacji przekroczenia zakresu tablicy komenda po jej wykonaniu int a[5],b[5],i; for(i=0; i<5; i=i+1) a[i]=1; for(i=0; i<10; i=i+1) b[i]=2; a[0]=2 a[1]=2 a[2]=2 a[3]=2 a[4]=2 b[0]=2 b[1]=2 b[2]=2 b[3]=2 b[4]=2 Nadanie wartości tablicy b, wyjechane poza jej zakres, niejawnie zmieniło wartości tablicy a. Taksiędziejem.in.wC. Wykład 9. UWAGI OGÓLNE, str. 10 Niebezpieczne konstrukcje w jęz. programowania Brak jawnych deklaracji Mi=0; ikwadr=0; while(i<n) { ikwadrat=ikwadr+2*i+1; i=i+1; Błąd w nazwie zmiennej powoduje błędny wynik, zamiast komunikatu. Taksiędziejem.in.wjęzykubasha,wPHP,...,wwieluinnych.
Wykład 9. UWAGI OGÓLNE, str. 11 Niebezpieczne konstrukcje w jęz. programowania Brak dyscypliny typowania Mmain() { intn; if(n=2* a ) printf("%s\n","pierwszy rok informatyki"+1); Pomnożenie znaku przez 2, przypisanie w warunku if, dodanie liczby do napisu nie są sygnalizowane jako błąd. To jest autentyczny przykład w C. Wykład 9. UWAGI OGÓLNE, str. 12 Niebezpieczne konstrukcje w jęz. programowania Skoki(i breaki) schemat i 0 ikwad 0 L i<n i N ikwad ikwad+2 i+1 i i+1 E program ze skokami program bez skoków i=0; i kwad=0; L: if(i>=n) goto E; L:ikwad= L:ikwad+ L:2*i+1; L:i=i+1; L:gotoL; E: i=0; i kwad=0; while(i<n) { ikwad= ikwad+ 2*i+1; i=i+1; Skoki umożliwiają realizację dowolnego schematu, nawet bardzo nieporządnego. Ale schemat i program ze skokami są narażone na błędy logiczne związane np. z możliwością skoku w nieprawidłowe miejsce. SkokiibreakisądopuszczonewC.
Styl programowania Wykład 9. UWAGI OGÓLNE, str. 13 Podział programu na(względnie) niezależne moduły funkcje, program w wielu plikach(dyrektywa#include"..."), inne narzędzia. Przekazywanie informacji między modułami powinno odbywać się jawnie, raczej przez parametry niż przez zmienne globalne. Czytelność kodu źródłowego mnemotechniczne nazwy identyfikatorów, przemyślane komentarze, wcięcia. Styl programowania Wykład 9. UWAGI OGÓLNE, str. 14 Unikanie sztuczek zwykłe kopiowanie void kopiuj1 (charcel[],charzrodlo[]) { inti; i=0; while(zrodlo[i]!= \0 ) { cel[i] = zrodlo[i]; i=i+1; cel[i]= \0 ; trikowe kopiowanie void kopiuj2 (charcel[],charzrodlo[]) { while ((*cel++=*zrodlo++)!= \0 ); Program czytelny jest lepszy od kryptycznego, nawet jeśli jest dłuższy!
Granice informatyki Wykład 9. UWAGI OGÓLNE, str. 15 Czy komputery potrafią wszystko? Jakoż zbudowali inżynierowie królewscy wyborną maszynę cyfrową na Księżycu[...].Królzrazutakiowakdzielnośćmaszynypróbował;razzaśnakazał jej telegraficznie, aby elektroskoku dokonała: był bowiem ciekaw, czy prawdą jest, co mówili inżynierowie, że machina ta umie wszystko. Jeśli wszystkoumie takmyślał toniechskacze.wszelakotreśćdepeszy uległa drobnemu zniekształceniu i maszyna otrzymała rozkaz, iż nie elektroskok, lecz elektrosmok ma przez nią zostać wykonany; i jak najlepiej umiała wypełniła polecenie. Stanisław Lem. Bajka o maszynie cyfrowej, co ze smokiem walczyła. Bajki robotów. Wydawnictwo Literackie, Kraków 1978, str. 63. Granice informatyki Wykład 9. UWAGI OGÓLNE, str. 16 Czy komputery potrafią wszystko? TWIERDZENIE: (nierozstrzygalność problemu stopu) MNie istnieje(meta)program komputerowy, który potrafiłby wczytać dowolny program P i dane D, a następnie w skończonym czasie prawidłowo przewidzieć, czy P zatrzyma się na D. TWIERDZENIE: (nierozstrzygalność poprawności) MNie istnieje(meta)program komputerowy, który potrafiłby wczytać dowolnyprogrampidwieasercjeaib,anastępniewskończonymczasie prawidłowo orzec, czy P jest częściowo poprawny względem A i B. Hipoteza: (P NP) MNieistniejeprogramkomputerowyPiwielomianW,takiżePpotrafiłby wczytać dowolną formułę logiczną i prawidłowo orzec w czasie W(n), gdzie n jest długością formuły, czy jest ona tautologią.