Seminar Programmierstil: Codierungsstandards Ein Vortrag von Kurt Prünner
Kurt Prünner: Codierungsstandards Eine Einigung auf einen Codierungsstandard ist notwendig sobald mehr als eine Person denselben Code bearbeiten soll bei Programmen, die zwar nur von einer Person geschrieben werden, aber irgendwann einmal von jemandem anderen gewartet werden sollen wenn man ein Programm auch ein paar Wochen, nachdem man es geschrieben hat, noch selber verstehen möchte 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Jeder Codierungsstandard ist besser als gar keiner DEN Codierungsstandard gibt es nicht - es ist daher oft erforderlich, sich an einen anderen, oft schon von außen vorgegebenen Standard anzupassen Die folgenden Folien sollen daher hauptsächlich als Denkanstoß verstanden werden und nicht als ein in Stein gemeisselter Codierungsstandard 06.12.2018 Kurt Prünner: Codierungsstandards
Wie man es nicht machen sollte... #include <stdio.h> #define PO(o,t)\ (((o>64)&&(o<91))?(((t>96)&&(t<123))?(t-32):(t)):(((t>64)&&(t<91))?(t+32):(t))) void main() { char *poo= "poot", *Poo="pootpoot" ,O[9];int o,t,T,p;(t=p =0)||(*O='\0');while ((o= getc( stdin ))!=( EOF))if ((p== 0)&& (((o>64 )&& ( o<91 )) || ((o> 96 ) &&(o< 123) ))) ( t!=8 )&&(O [t]= o)&& (O[++ t] = '\0') ;else {if (t>7) {for (T = 0 ; T <=7; T++ ) printf("%c", PO(*( O+T), *(Poo+ T))); printf ("%c", o);}else if (t>3){for (T =0;T<= 3;T++) printf ("%c", PO(*(O +T),*( poo+T) ) ) ; printf( "%c" , o ) ; } else printf ( "%s%c" , O , o ) ; ( t = 0 ) || ( * O = '\0' ) ; ( o == 60 ) && ( ++p ) ; ( o == 62 ) && (p!=0) && ( --p ) ; } } http://ioccc.org/1998/dlowe.c 06.12.2018 Kurt Prünner: Codierungsstandards
Allgemeine Stilkriterien Schreibe Programme, die andere Leute lesen können, nicht nur der Compiler (siehe letzte Folie) Ersetze "Magische Zahlen" durch Konstanten - fast alle in einem Programm vorkommende Zahlen werden leichter verständlich, wenn man sie durch eine Konstante mit sprechendem Namen ersetzt M if ((ch == 37) || (ch == 42) || (ch == 47)) vs. if ((ch == '%') || (ch == '*') || (ch == '/')) 06.12.2018 Kurt Prünner: Codierungsstandards
Allgemeine Stilkriterien Zerlege komplexe Ausdrücke in kleinere Teilausdrücke, um diese besser verstehen zu können M *x += (*xp=(2*k < (n-m) ? c[k+1] : d[k--])); vs. if (2*k < (n-m)) *xp = c[k+1]; else *xp = d[k--]; *x += *xp; 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Namensgebung Wähle sprechende Namen kurze Namen nur für lokale Variablen (num, i, cur) längere Namen für nicht-lokale Variablen (firstName, totalPoints, databaseConnection) Worte trennen PascalCasing (Große Wortanfänge) camelCasing (Erster Wortanfang klein) Konstanten kennzeichnen (MAX_VALUE) aktive Funktionsnamen (getTime(), isDigit()) 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Namensgebung Achte auf konsistente Namensgebung M class UserQueue { int noOfItemsInQ, frontOfTheQueue, queueCapacity; public int noOfUsersInQueue() {...} } Wähle passende Namen M boolean isDigit(char i) { return (i == ' '); } M boolean checkDigit(char i) { ... } 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Hungarian Notation Name bestehend aus: Prefixes: a (Array) h (Handle) c (Count) i (Array-Index) d (Difference) m (Modul-global) e (Array-Element) p (Pointer) g (Global) Base Type (programmspezifisch): wn (Window), scr (Screen), ch (Character) 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Hungarian Notation Name bestehend aus: Qualifier: beschreibender Teil des namens, z.B. pwnMain, ghscrUserWorkspace, chRead Standard-Qualifier: Min Array-Anfang First Erstes zu bearbeitendes Element Last Letztes zu bearbeitendes Element Lim Oberes Limit, das nicht erreicht wird (Last+1) Max Array-Ende 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Whitespace Verwende Leerzeilen, um zusammengehörige Codezeilen von anderen abzutrennen StringBuffer buf = new StringBuffer(); int i = 0; int j; while ((j = st.indexOf(s,i)) >= 0) { buf.append(st.substring(i,j)); buf.append(r); i = j+s.length(); } 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Whitespace Verwende Leerzeichen, um Operanden und Operatoren in Ausdrücken zu gruppieren - unter Beachtung der Vorrangregeln M x = y+4 * z-3 vs. x = y + 4*z - 3 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Einrückungen Einrückungen sollen die logische Struktur des Codes genau und konsistent wiedergeben M for (int i = 1; i < 10; i++) score[i] = 0; name[i] = ""; date[i] = null; M if (i != 0) i--; else return i; 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Einrückungen Einrückungen sollen den Code lesbarer machen M if (x == 0) if (y == 0) x++; else y--; Einrückungen sollen Änderungen gegenüber robust sein M void doSomething(String firstName, String lastName, String company) 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Klammerung Klammerung soll Ausdrücke für den, der den Code liest, eindeutig machen Setze bei komplizierteren Ausdrücken auch dann Klammern, wenn es durch die Vorrangregeln der Programmiersprache nicht unbedingt nötig wäre leapYear = y%4 == 0 && y%100 != 0 || y%400 == 0; vs. leapYear = ((y%4 == 0) && (y%100 != 0)) || (y%400 == 0); 06.12.2018 Kurt Prünner: Codierungsstandards
Kurt Prünner: Codierungsstandards Klammerung Vor allem bei der Verwendung von Operatoren, die nicht in direktem Zusammenhang stehen, ist es sinnvoll, auf jeden Fall Klammern zu setzen M if (x&MASK == BITS) bedeutet in Wahrheit if (x & (MASK == BITS)) Gemeint war aber wohl if ((x & MASK) == BITS)) 06.12.2018 Kurt Prünner: Codierungsstandards