Hallo ich wollte mal ein allgemeines Brainstorming anstoßen. Also ich
werde im Ausland(Vietnam) eine Vorlesungsreihe(30 vl und 30 Workshops)
an der Uni zum Thema Programmier Einführung in C geben. Das Thema ist so
vorgegeben(also lohnt eine Diskussion über den Sinn nicht). Aber ich
wollte mal in die Runde nach Ideen fragen was ihr mal gerne in so einer
Vorlesung an Themen gehört hättet, gute Zitate oder Beispiele,
Klausuraufgaben die ihr besonders gut fandet, tips zum allgemeinen
Studium(was man den Studenten mitgeben kann z.B. von Anfang an in
Gruppen zu arbeiten) oder praktische Programmieraufgaben die Ihr gut und
lehrreich fandet. Ich bereite gerade die VL vor und hab schon ein paar
Sachen aber es gibt bestimmt viele Sachen die Ich noch nicht habe.
"Ich bereite gerade die VL vor und hab schon ein paar Sachen"
-> Dann zeig mal? Wieso sollen wir deine Vorlesung vorbereiten?
Sonst sag ich mal als Antwort: Einführung in C -> google -> da hast 'ne
Einführung.
"z.B. von Anfang an in Gruppen zu arbeiten"
-> und sich auf den Arsch zu sitzen. Studienerfolg ~ Fleiß.
Die letzten Vorlesungen dem undefined behaviour widmen. Warum es
ueberhaupt existiert (ermoeglicht starke Compileroptimierungen, in C
nimmt der Compiler an, dass der Programmierer es besser als der Compiler
weiss.). Welche Konstruktionen UB sind. Z.b. ist
Printf ("%s", p);
If (p) *p=1;
Mit p pointer auf char UB fall p NULL ist, und der Compiler optimiert
somit das if(p) weg.
;-) Sollt ihr ja garnicht. Ich such nur Ideen. Ich hatte ein paar
während langweiliger Vorlesungen wo ich mir gedacht hätte das wäre toll
das mal zu hören. Du musst ja auch nix dazu sagen. Wenn du aber nicht
was hilfreiches in nem Forum sagen willst warum bist du dann hier?
Dumdi D. schrieb:> Mit p pointer auf char UB fall p NULL ist,> und der Compiler optimiert somit das if(p) weg.
Das kann der Compiler aber nur, wenn p ein konstanter Nullpointer ist.
In diesem Fall ist einfach die if-Abfrage immer false und wird nie
ausgeführt. Deshalb optimiert der Compiler die Abfrage weg (er könnte
sie auch drin lassen, aber wozu? der darin befindliche Code wird ja nie
angesprungen). "Undefiniert" ist an diesem Verhalten gar nichts. Es ist
lediglich "optimiert".
Aber gerade die Optimierungsstrategien des Compilers und warum z.B. eine
for(int i=0; i<1000; i++);
Schleife einfach ungefragt wegoptimiert werden kann, das sollte schon
erwähnt werden.
Und natürlich die ganze volatile-Geschichte und Zugriffe auf globale
Variablen im Interrupt sind ein Wort wert.
Wobei natürlich "eine VL in C" wesentlich unhandlicher und abstrakter
ist, als "eine VL in C für Mikrocontroller"...
Dumdi D. schrieb:> Printf ("%s", p);> If (p) *p=1;
Ist tatsächlich irgendwo festgelegt, dass man printf("%s") keinen
NULL-Pointer mitgeben darf? Ich hätte da eher erwartet, dass printf
sowas wie <NULL> ausgibt und das if nicht wegoptimiert wird.
MaWin schrieb:> Ist tatsächlich irgendwo festgelegt, dass man printf("%s") keinen> NULL-Pointer mitgeben darf?> Ich hätte da eher erwartet, dass printf sowas wie <NULL> ausgibt
So ist es:
http://codepad.org/OKkBSpww
Nicht unerwähnt bleiben sollte auch, dass eine einzelne Programmzeile
beliebig lang oder kurz dauern kann. Denn manche meinen tatsächlich 1
Zeile = 1 Befehl = 1 CPU-Takt. Hier wäre ein Fingerzeig auf den
erzeugten Assemblercode und eine kurze Analyse der dortigen Befehle
sicher interessant. Für manche Programmierer wird das zwar das einzige
Mal im Leben sein, dass sie sowas sehen, aber es ist dann schon mal im
Hinterkopf verankert, dass da noch mehr ist...
Bei mir damals, in den Vorlesungen, fing es mit der Geschichte von C an
und ging dann über Zahlensysteme zum ersten "Hello-World"-Programm...
Und dann würde ich versuchen die Studys viel selber machen zu lassen.
Prgrammieren ist wie ein Handwerk...vom Zugucken lernt man es nicht...
Gruss
@Jeff Portnoy
“First, solve the problem. Then, write the code.”
(John Johnson)
um mal eins der klugen Zitate meiner Vorlesung zu zitieren.
Aber danke schon mal für die guten Ideen bis jetzt.
Ich ratter mal die Übungsaufgaben runter die ich früher gestellt habe.
Das war für eine Fortgeschrittenenkurs und die Leute wollten gefordert
werden, statt nur Kinderkram zuimplementieren. Allerdings war ich bei
den Aufgaben ziemlich einfallslos. Hinzukommt dass die Algorithmen nicht
direkt auf die später zu schreibenden Programme abgestimmt waren.
- Implementiere eine Priority-Queue mit Red-Black Trees
- Implementiere Arbitrary Precision Arithmetik: Addition und Subtraktion
- Implementiere Arbitrary Precision Arithmetik: Multiplikation
- Implementiere Arbitrary Precision Arithmetik: Division
- Implementiere eine Skip-Liste.
- Schreibe eine eigene Version von make
- Schreibe eine eigene Version von more
- Schreibe eine eigene Version von sort
- Schreibe eine eigene Version von grep
- Schreibe ein Plotprogramm (ASCII Ausgabe)
- Schreibe einen Peephole-Optimizer für Z80 Assembler
- Schreibe einen Simulator für kontinuierliche Systeme (DGLs)
Mach die Vorlesung nicht zu stark auf C fixiert. Man kann Besonderheiten
von C erwaehnen, aber erst sollte das Problem geloest werden. Denn sonst
ist der Code falsch bevor zu Programmieren begonnen wurde. Nur sollte
dies auch nicht zu ausfuehrlich geschehen, sonst klebt man an
"Algorithmen und Datentypen - von N.Wirth" fest.
@MetaTroll da bin ich leider nicht frei in der Wahl. Ich habe ja
vorgaben was sie können sollen
@Hannes Jaeger Ich habe Erstes Semester :-)
@Lothar Miller I like
“Computers are useless. They can only give you answers.”
(Pablo Picasso)
“19 Jan 2038 at 3:14:07 AM”
(End of the word according to Unix–2^32 seconds after January 1, 1970)
Hannes J. schrieb:> - Implementiere eine Priority-Queue mit Red-Black Trees> - Implementiere Arbitrary Precision Arithmetik: Addition und Subtraktion> - Implementiere Arbitrary Precision Arithmetik: Multiplikation> - Implementiere Arbitrary Precision Arithmetik: Division> - Implementiere eine Skip-Liste.>> - Schreibe eine eigene Version von /make/> - Schreibe eine eigene Version von /more/> - Schreibe eine eigene Version von /sort/> - Schreibe eine eigene Version von /grep/>> - Schreibe ein Plotprogramm (ASCII Ausgabe)> - Schreibe einen Peephole-Optimizer für Z80 Assembler> - Schreibe einen Simulator für kontinuierliche Systeme (DGLs)
Und damit lernt man C? Oder Programmieren im allgemeinen?
Cyblord -. schrieb:> Und damit lernt man C? Oder Programmieren im allgemeinen?
Ich stelle da gern andere Aufgaben, die man sowohl mit Brute Force als
auch mit einem "schlauen" Algorithmus lösen kann und/oder soll.
So z.B. die Sache mit den Zügen, die von zwei Bahnhöfen losfahren und
sich irgendwo treffen.
Frage 1: wo
Frage 2: wann
Und die Antwort darauf dann mit der klassischen Algebra in Form einer
Quadratischen Gleichung. Oder als sukzessive Approximation durch
Aufaddieren von kurzen Wegstrecken in kleinen Zeitabständen und
Vergleich der Position.
Oder das Herausfinden der Anzahl von unterschiedlichen Kombinationen der
Farbstreifen einer Flagge z.B. mit rot, grün und blau mit 3
geschachtelten Schleifen oder mit einem lange laufenden
Zufallsgenerator.
Also Aufgaben, die schon in Gedanken bzw. auf einem Blatt Papier leicht
zu lösen sind und deren Antwort bekannt ist. Solche also, an denen nur
die Umsetzung in die neue Programmiersprache neu ist.
@Felix
Kannst du noch was dazu sagen, wie du an die Stelle gekommen bist und
in welchen Rahmen das stattfinden soll? Bist du PostDoc?
Ich würde mich grundsätzlich an Büchern und Folien orientieren und
sinnvolle Schwerpunkte setzen, einiges wurde ja schon genannt.
- Bring den Leuten bitte moderneres C bei. Es gibt eigentlich keinen
vernünftigen Grund, warum man heute noch K&R oder C89 verwendet.
- Best Practice, wie Unit-Tests kann man sicher auch bereits ganz am
Anfang erfolgreich einsetzen.
- Erkläre ihnen den Unterschied zwischen Compiler und Linker und halte
sie erst einmal von einer IDE fern! ;-)
Die erste Frage sollte sein, was die Leute fuer eine Vorbildung haben.
Ist ihnen programmieren schon bekannt, und nun sollen sie eine
Schnellbleiche in C bekommen ? Dann muss man erst mal gegenueberstellen.
Wenn sie gar nichts koennen, muss man sich mit Definition, Deklaration,
Zuweisung, Vergleich, Kontrolstrukturen, usw aufhalten.
Was an Mathematik haben sie schon drauf ?
Ist eine Integration schon bekannt ?
An einer technischen Uni wuerde ich erwarten sie kennen Programmieren,
und benoetigen eine Schnellbleiche in C. Mathe haben sie auf einer
einfachen Ebene drauf. Also nichts mit mehrdimensionale Optimierung.
Rauschen wegfitten, und so.
Eine VL-Einheit vielleicht typischen Fehlern widmen, die man in C
macht/machen kann. Jeder von uns ist schon mal sicher über was
gestolpert. Coding-Style (Guide) wäre u.U. auch ein Thema
Es stellt sich auch die Frage ob du Wissen über C oder Wissen über
Programmierung allgemein vermitteln willst. Das sind zwei paar Schuhe
und man kann nur davor warnen beides zu vermischen.
Nicht umsonst fängt so mancher Programmierkurs an der Uni mit
ungeliebten (und praktisch unnützen) Sprachen an. Man kann aber gar
nicht früh genug anfangen, den Studenten den Unterschied zwischen
Konzepten und konkreten Programmiersprachen zu vermitteln.
Algorithmen und Datenstrukturen sind dann IMO nochmal ein drittes
Gebiet, welches von den zwei Obigen auch etwas abgesetzt betrachtet
werden sollte.
Ich äußer mich mal kurz zu ein paar Sachen.
Also vielleicht ist das nicht so rüber gekommen. Ich stehe jetzt nicht
mit dem Rücken zur Wand und suche verzweifelt nach Antworten. Ich habe
die Vorlesung fast fertig und suche nach ein paar Gewürzen um die noch
ein bisschen zu verbessern. Ich lebe seit drei Jahren hier und kenne die
vietnamesische Kultur schon etwas. Außerdem haben sie mich ja gerade
wegen der deutschen Lernart. Ich habe die komplette Vorlesung meines
Vorgängers und kann mich an der orientieren. Also kein Blindflug. Nein
hab noch keinen Doktor. Kommt vielleicht noch. Dafür kam das Angebot zu
überraschend. Zu den Lerngruppen ich finde die werden zu unrecht
abgetan. Bei den Klausuren und Aufgaben ist jeder alleine. Nur die
Vorbereitung kann zusammen gemacht werden. Ich habe erst richtig
angefangen zu lernen nachdem wir uns gegenseitig motiviert haben. Für
mich war das das beste was ich machen konnte in der Uni. Bei meinen
Kommilitonen war es ähnlich. Wir haben nur leider viel zu spät
zueinander gefunden.
Felix schrieb:> Ich äußer mich mal kurz zu ein paar Sachen.> Also vielleicht ist das nicht so rüber gekommen. Ich stehe jetzt nicht> mit dem Rücken zur Wand und suche verzweifelt nach Antworten. Ich habe> die Vorlesung fast fertig und suche nach ein paar Gewürzen um die noch> ein bisschen zu verbessern.
Undefined Behavior wurde schon genannt.
Secure Coding
https://wiki.sei.cmu.edu/confluence/display/c/SEI+CERT+C+Coding+Standard
Dazu könnte man auch noch optional Reversing machen, um zu zeigen wie
man solche Bugs ausnutzen kann (natürlich nicht gleich gegen moderne
Systeme und Compiler also erstmal ASLR aus, mit -fno-stack-protector
übersetzen, 32-Bit usw. einfache Challenges: Buffer-Overflows ausnutzen,
Format Strings, da gibt's genug zum Austoben)
Ich würde noch einige Allgemeine Dinge einfliesen lassen:
* Man sollte keinen Code kopieren, den man nicht versteht
* Beispiele und best practices sind nicht der Weisheits letzter
schluss, je nach Problemstellung und Situation können unterschiedliche
Herangehensweisen sinn machen. Letztendlich füren immer viele wege nach
Rom. Ich habe schon Leute getroffen die gefragt haben wie man etwas
umsetzt, und eine art absolute Antwort gesucht haben, statt sich
verschiedene Herngehensweisen und deren Implikationen zu überlegen.
* C fehlen komplexere Sprachkonstrukte und Konzepte die viele andere
Programiersprachen haben, die Sprachkonstrukte sind recht Primitiv, aber
den anderen Sprachen keineswegs unterlegen. Häufig hat man mehr
Kontrolle darüber was der code alles tut und wie man es umsetzen will,
aber man kann fast alle komplexeren Konzepte wie OOP auch in C recht
einfach nachbilden. Das Daten und Funktionen getrennt sind betrachte ich
als grossen Vorteil von C gegenüber vielen anderen sprachen.
Der C Präprozessor ist sehr mächtig, aber nur wenige trauen sich diesen
zunutze zu machen. Ein paar Anwendungsszenarien können nicht schaden:
* Include guards
* Kleine Templates
* Mehrere korrelierende Listen:
1
#define SOME_CONSTANTS \
2
X(TEST) \
3
X(PIZZA)
4
5
#define X(Y) #Y,
6
constchar*constant_names[]={SOME_CONSTANTS};
7
#undef X
8
9
#define X(Y) CONSTANT_ ## Y,
10
enumconstant_list{
11
SOME_CONSTANTS
12
CONSTANT_COUNT
13
};
14
#undef X
* Hinzufügen von Funktionsnamen usw. bei Logging funktionen
* Häufig verwendete non-standard Macros, z.B. Arraygrösse bestimmen,
container_of, MIN/MAX, etc.
* Conditional compilation
etc.
Auch interressant sind Methoden dinge ohne Heap allocationen zu tun, und
deren Grenzen. Die linked list Implementierung im Linux Kernel zum
Beispiel ist faszinierend, keine Dynamischen allocationen, und die
einzige Limitation ist das ein Element nicht doppelt in der Liste sein
kann.
Das sind aber leider die letzten Probleme die Vietnamesen mit Ausländern
erörtern wollen. Vielleicht auch gut so weil sie das eigentlich selber
besser hand haben als man das Ausländer kann. Was bringt einem eine
Vorlesung in Vietnamesisch wenn 95% der Wissenschaft in Englisch ist.
Englisch ist halt eine gute Möglichkeit hier etwas zu erreichen.
Kurz gesagt ich bin weder hier um Probleme zu lösen noch ist das bei der
jetzigen Wirtschaft nötig.
@Daniel Abrecht
danke. Vielleicht nur zum code kopieren den man nicht kennt. Dann dürfte
man strenggenommen auch keine librarys nutzen ohne den Source Code zu
kennen.
Also wenn es um eine generelle Programmiereinführung anhand der
Programmiersprache C geht, würde ich folgendes vorschlagen:
- Rekursion:
Viele Programmieranfänger haben Probleme Rekursionen anzuwenden oder
überhaupt nachzuvollziehen.
Es würde auf jeden Fall Sinn machen etwas zu Rekursionen zu sagen, wie
man diese implementiert und wann diese eingesetzt werden können. Am
besten an ein paar Beispielcodeschnipseln.
- Kreative Programmieraufgaben:
Bei der Einführung von Schleifen z.B. ein Brute Force Programm für
einfache Passwörter.
Beim Ein- und Auslesen von Dateien z.B. die Caeser/Vignere
Verschlüsselung programmieren.
Beim Arbeiten mit Strings vllt einen einfachen Esolang-Interpreter wie
MiniStringFck oder ähnliches.
Interessante Programmieraufgaben spornen die Studenten mehr an und sie
haben nicht das Gefühl etwas komplett nutzloses herunterzucoden.
Dumdi D. schrieb:> Na los, felix erklaer den hier doch mal warum das printf mit nullpointer> UB ist.
Ich warte auch noch.
Vielleicht war so etwas gemeint:
1
strcpy(x, p);
2
If (p) *p=1;
strcpy dereferenziert in jedem Fall p[0]. Deshalb darf if(p) durch if(1)
ersetzt werden.
MaWin schrieb:> Dumdi D. schrieb:>> Na los, felix erklaer den hier doch mal warum das printf mit nullpointer>> UB ist.>> Ich warte auch noch.>> Vielleicht war so etwas gemeint:>>
1
> strcpy(x, p);
2
> If (p) *p=1;
3
>
>> strcpy dereferenziert in jedem Fall p[0]. Deshalb darf if(p) durch if(1)> ersetzt werden.
7.21.1 String function conventions
1
... in all cases a char * or void * argument points to the initial (lowest addressed) character of the array. If an array is accessed beyond the end of an object, the behavior is undefined.
Also wie immer: ist x oder p oder sind beide Null, darf da alles
rauskommen. Beim printf genauso:
7.19.6.1 The fprintf function
1
... the argument shall be a pointer to the initial element of an array of character type
Felix schrieb:> @Jeff Portnoy> “First, solve the problem. Then, write the code.”> (John Johnson)>> um mal eins der klugen Zitate meiner Vorlesung zu zitieren.> Aber danke schon mal für die guten Ideen bis jetzt.
Da hat er nicht Unrecht, der Mann. Und wenn Du schon bei Zitaten bist,
hier gleich noch zwei: "Premature optimization is the root of all evil."
(Donald E. Knuth) und "Measure, don't guess." (Kirk Pepperdine).
Torsten R. schrieb:> - Bring den Leuten bitte moderneres C bei. Es gibt eigentlich keinen> vernünftigen Grund, warum man heute noch K&R oder C89 verwendet.>> - Best Practice, wie Unit-Tests kann man sicher auch bereits ganz am> Anfang erfolgreich einsetzen.>> - Erkläre ihnen den Unterschied zwischen Compiler und Linker und halte> sie erst einmal von einer IDE fern! ;-)
Leider kann ich hier nur ein "lesenswert" vergeben. Ich wollte, es wären
tausend!
NochEiner schrieb:> Ach ja im Zusammenhang mit Coding-Style könnte man den hier bringen (als> Negativ-Beispiel) http://www.ioccc.org/
Negativbeispiele sind für Anfänger schlecht. Die prägen sich das ein und
Du bekommst es nur mit einem riesigen Aufwand wieder heraus.
Sheeva Plug danke für das optimization das wollte ich immer mal
anwenden.
ja mit c99 oder c11 macht natürlich Sinn. Aber bei den Grundlagen sind
die Unterschiede noch nich so groß. Pointer bleibt pointer. Aber ich
werde das noch etwas raus arbeiten.
die IOCCC beispiele sind so schlecht das sich niemand die ernsthaft
merken wird
Danke für die ganzen Anregungen und Beispiele. Ich bin den thread gerade
durchgegangen und hab so einiges übernommen.
Zum Thema Rekursion bieten sich dann natürlich die Tower of Hanoi an ;-)