ich fange bald an Mathematik zu studieren und überlege, mir ein Macbook
zu kaufen. Das Mathematikstudium an meiner Uni umfasst auch einen
Programmierkurs in C, und jetzt würde ich gern wissen, ob man auch unter
Mac OS X gut in C programmieren kann. Oder ob sich das überhaupt gut zum
Programmieren eignet...
Gruß
Dominik
p.s.: Ich habe noch éin altes iBook G4
Ciao
Alfred
"Dominik Leukers" <dominik...@online.de> schrieb im Newsbeitrag
news:g8ucl6$erp$1...@online.de...
> ich fange bald an Mathematik zu studieren und überlege, mir ein Macbook
> zu kaufen. Das Mathematikstudium an meiner Uni umfasst auch einen
> Programmierkurs in C, und jetzt würde ich gern wissen, ob man auch unter
> Mac OS X gut in C programmieren kann.
Um in C Programmieren zu können ist "nur" ein guter Editor und ein
Compiler notwendig. Sobald das Programm mehr als ein paar Quelldateien
umfasst ist auch make (oder ein anderes Buildsystem), sowie eine
Versionsverwaltung sinnvoll. Diese Programme stehen auf jedem modernen
Desktop zur Verfügung[1]. Wenn Du mit dem Programmieren anfängst, wirst
Du hauptsächlich mit der Konsole arbeiten, und da hat das Betriebssystem
kaum Einfluss.
> Oder ob sich das überhaupt gut zum
> Programmieren eignet...
Klingt wie der Anfang eines längeren OT Threads...
bye
Rudi
[1] Nein, dies ist keine Wertung, ob jetzt OS X, Windows, KDE, Gnome
oder $IRGENDWAS jetzt ein moderner Desktop ist.
Ich studiere an der Uni Bonn, und da gibt es im Grundstudium neben
Lineare Algebra und Analysis auch das Modul "Algorithmische Mathematik".
In der Information steht, dass man dafür unbedingt Programmierkenntnisse
haben sollte, deshalb ist der Programmierkurs auch als Vorkurs
angesetzt. Warum die sich dort jetzt gerade für C entschieden haben,
weiß ich nicht. Jedenfalls kann ich mir vorstellen, dass dann auch
weiterhin vorrangig mit C gearbeitet wird.
Die wahrscheinliche Vermutung waere, dass eine Sprache gelernt werden
sollte, mit der man auch einigermassen Aussichten hat, umfangreichere
numerische Problem geloest zu bekommen, bevor die Sonne verlischt.
Danke für die schnelle Antwort.
> Klingt wie der Anfang eines längeren OT Threads...
Dazu wollen wir es doch nicht kommen lassen.
> [...] und jetzt würde ich gern wissen, ob man auch unter
> Mac OS X gut in C programmieren kann. [...]
Und ich würde jetzt gerne wissen, wieso man daran überhaupt zweifeln kann.
Mac OS ist ein Unix-basiertes System. C ist seinerzeit für Unix
entwickelt worden. Ein besseres Gespann als C und Unix wirst Du kaum finden.
Gruß. Claus
Dominik schrieb:
"..., und jetzt würde ich gern wissen, ob man auch unter
Mac OS X gut in C programmieren kann. Oder ob sich das
überhaupt gut zum Programmieren eignet..."
Das hört sich schon nach zweifeln an.
- Heinz
Mac OS ist kein UNIX, denn es enthält keinen Code vom "Ur-UNIX",
welches einmal in den Bell Labors von AT&T entwickelt wurde.
Ähnlich wie Linux ist Max OSX eine unixartiges System, weil es
sich teilweise so anfühlt (Posix-Standard).
Bitte keine falsche Gerüchte streuen.
Siehe: http://de.wikipedia.org/wiki/Unix
Und C ist eine tolle Programmiersprache, wenn man gerne mit Bufferoverflows
herumexperimentieren möchte.
C++ ist da schon das kleinere Übel solange man nicht Ansi-C in C++
programmiert.
Bedauerlicherweise wird Pascal immer unterschätzt. Dabei kann man mit
FreePascal + Lazarus ( Delphi-Clone ) sogar plattformübergreifen
Programmieren.
z.B. http://www.kanzelsberger.com/pixel/?page_id=12 ( Photoshop-Clone )
Gruß
Raymond
Das ist Unsinn (und hier off topic). UNIX(*) ist ein eingetragenes
Warenzeichen der Open Group und Mac OS X ist als UNIX(*) 03
zertifiziert, vgl
Als Autor von http://www.prog-c-math.de/ kann ich C als
Einführungssprache
natürlich nur unterstützen, irgendwer muss das Buch ja kaufen ;-)
Aber im Ernst: wir haben uns bewusst für C entschieden, da C noch
recht "nahe an der Maschine" ist aber mehr kann als Fortran77. C++
als Anfängersprache passt nicht in einen "normalen" einsemestrigen
Kurs, es sei denn man setzt sechs Wochenstunden Vorlesung an.
Haskell, Scheme, etc sind sicherlich interessante Programmiersprachen,
aber die Implementierung einer Matrix-Vektor Multiplikation z.B.
geht einem in C doch schneller von der Hand.
Gruß, Uwe
Raymond <ch...@raymisoft.de> wrote:
>> Mac OS ist ein Unix-basiertes System.
Da es (auch wenn mich das immer wieder wundert) die Zertifizierungen
ueberstanden hat, ist es ein UNIX (denn der Begriff ist heutzutage nicht
an die "Abstammung von bestimmten Quellen" gebunden, sondern daran, dass
es sich wie ein UNIX verhaelt, und dies anhand entsprechender Tests belegt
und mittels Zertifizierung offiziell bestaetigt wurde).
> Mac OS ist kein UNIX, denn es enthält keinen Code vom "Ur-UNIX",
> welches einmal in den Bell Labors von AT&T entwickelt wurde.
Das ist auch zimelich unerheblich. Was UNIX ist und was nicht bestimmt
derjenige, der die Rechte an dem Namen hat, und das ist wohl momentan
die "OpenGroup", und die hat festgelegt, dass *genau* *das* ein UNIX
ist, was als UNIX zertifiziert wurde (voellig unabhaengig von der Ab-
stammung des Codes).
> Bitte keine falsche Gerüchte streuen.
dto.
> Siehe: http://de.wikipedia.org/wiki/Unix
Du sienst dir fuer die Begriffsdefinition in diesem Fall die falschen
Quellen an: http://www.opengroup.org/certification/unix-home.html
> Und C ist eine tolle Programmiersprache, wenn man gerne mit Bufferoverflows
> herumexperimentieren möchte.
Man kann sich mit nahezu jeder Sprache nahezu beliebig in den Fuss
schiessen. In C ist es nur besonders einfach, die Sprache nicht oder
falsch zu verstehen und eigentlich notwendige Fehlerpruefungen wegzu-
lassen (was dann in entsprechendem Code resultiert) ...
Aber immer dran denken: *echte* Programmierer koennen in jeder beliebigen
Programmiersprache Fortran-Programme schreiben (ich habe sogar schon mal
entsprechenden Source in Lisp gesehen ...).
> C++ ist da schon das kleinere Übel solange man nicht Ansi-C in C++
> programmiert.
C++ hat mindestens genausoviel Potential, sich gepflegt in den Fuss zu
schiessen. Es vereint quasi die Fehlermoeglichkeiten obejktorientierter
Programmierung mit den Fehlermoeglichkeiten von C oder Assembler, sprich
es ist (was Fehlermoeglichkeiten betrifft) eine der ausgereiftesten
Sprachen ueberhaupt ... Darueber hinaus ist C++ hier OffTopic.
> Bedauerlicherweise wird Pascal immer unterschätzt. Dabei kann man mit
> FreePascal + Lazarus ( Delphi-Clone ) sogar plattformübergreifen
> Programmieren.
Plattformuebergreifend ueber *sehr* *wenige* Plattformen ...
Es gibt Dutzende von Sprachen, die auf mehr Plattformen verfuegbar sind
und bessere Moeglichkeiten zur plattformuebergreifenden Programmierung
bieten. Aber auch das ist hier voellig OffTopic.
Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...
Uwe Schmitt <rockspo...@googlemail.com> wrote:
> Aber im Ernst: wir haben uns bewusst für C entschieden, da C noch
> recht "nahe an der Maschine" ist aber mehr kann als Fortran77.
Wenn es zur Implementierung von Uebungen zur Mathematik sein soll:
Wozu braucht ihr da "Naehe zur Maschine"?
> Haskell, Scheme, etc sind sicherlich interessante Programmiersprachen,
> aber die Implementierung einer Matrix-Vektor Multiplikation z.B.
> geht einem in C doch schneller von der Hand.
Das wuerde ich nicht so pauschal behaupten (es ist *auch* eine Sache
der Gewohnheit). Gerade Scheme ist eine Sprache, die IMHO fuer "Pro-
grammieruebungen zur Begleitung einer Mathematik-Vorlesung" gar nicht
so deplatziert waere. Und bei C als "Anfaenger-Sprache" habe ich zu-
mindest doch *erhebliche* Bedenken. C erfordert IMHO ein Mass an
"Programmierdisziplin", das man sich IMHO erst anhand "restriktiverer
Sprachen" erarbeiten sollte, wenn der code nicht zu fehlertraechtig
werden soll ...
Es gibt uebrigens eine Reihe von Leuten, die dir fuer solche Zwecke
Ada empfehlen wuerden (und so verkehrt liegen sie damit gar nicht ...).
Meiner Meinung nach kann man so besser lernen wie ein Computer
eigentlich arbeitet. Prolog, Haskel, Lisp, ... hinterlassen beim
Programmier-
anfänger eher den Eindruck einer Black Box.
Da man in der Ausbuildung der Mathematiker ja nicht den Schwerpunkt
aufs
Programmieren legt, ist C eigentlich eine gute Basis um sich später in
Richtung
C++ oder Java oder C# weiter zu entwickeln.
Ich hab ja auch prinzipiell nichts gegen Ada etc., aber wenn man den
Studenten eine einzige Programmiersprache für die Praxis mit geben
will,
dann sind solche "Exoten" einfach zu speziell und zu wenig verbreitet.
Ich würde einem Stundenten mit eigenem Engangement und Interesse an
anderen Sprachen keine einzige schlecht machen oder ausreden wollen.
Nur wenns halt um die Ausbildung in einer einzigen Programmiersprache
geht,
dann doch C.
Gruß, Uwe
Ist der gcc denn schon auf dem Macbook vorinstalliert? Und ist da auch
ein guter Texteditor vorinstalliert? Oder muss extra noch danach suchen?
Uwe Schmitt <rockspo...@googlemail.com> wrote:
> On 26 Aug., 16:45, Juergen Ilse <i...@usenet-verwaltung.de> wrote:
>> Uwe Schmitt <rocksportroc...@googlemail.com> wrote:
>> > Aber im Ernst: wir haben uns bewusst für C entschieden, da C noch
>> > recht "nahe an der Maschine" ist aber mehr kann als Fortran77.
>> Wenn es zur Implementierung von Uebungen zur Mathematik sein soll:
>> Wozu braucht ihr da "Naehe zur Maschine"?
> Meiner Meinung nach kann man so besser lernen wie ein Computer
> eigentlich arbeitet. Prolog, Haskel, Lisp, ... hinterlassen beim
> Programmieranfänger eher den Eindruck einer Black Box.
Na und? Das Fach heisst doch "Mathematik" und nicht "Architekturen
von heutigen Computern", oder irre ich mich da? Die Programmier-
uebungen dienen da meinem Verstaendnis nach dazu, die jeweils ge-
lehrten Algorithmen formal aufschreiben und austesten zu koennen.
Das leistet auch jede "nicht maschinennahe Sprache". Wozu benoetigt
ihr da "Maschinennaehe"?
> Da man in der Ausbuildung der Mathematiker ja nicht den Schwerpunkt
> aufs Programmieren legt,
Genau das ist IMHO der Punkt: Der Schwerpunkt liegt nicht auf dem
programmieren und *erst* *recht* *nicht* auf "Implementierung von
Digitlrechnern". Ich sehe einfach keine Bedarf fuer "Maschinennaehe"
bei vorlesungsbegleitenden Programmieruebungen einer Mathematik-
vorlesung.
> ist C eigentlich eine gute Basis um sich später in Richtung C++ oder
> Java oder C# weiter zu entwickeln.
URGS!
> Ich hab ja auch prinzipiell nichts gegen Ada etc., aber wenn man den
> Studenten eine einzige Programmiersprache für die Praxis mit geben
> will, dann sind solche "Exoten" einfach zu speziell und zu wenig
> verbreitet.
Es ist *sinnvoller*, den Studenten die Faehigkeiten zu vermitteln, die
sie benoetigen, um eine Programmiersprache zu erlernen, sowie die Fae-
higkeit, einen Algorithmus so zu formulieren, wie es fuer die Implemen-
tierung in einer (nahezu beliebigen) Sprache erforderlich ist. Es ist
IMHO nicht notwendig, sie schon fruehzeitig auf eine bestimmte Sprache
(oder eine bestimmte Gruppe von Sprachen) einschiessen zu wollen.
Wenn sie spaeter eine andere Sprache benoetigen, lernen sie sie eben.
Das ist fuer Leute, die mit programmieren zu tun haben, Alltag; fuer
alle anderen i.d.R. nicht erforderlich.
> Ich würde einem Stundenten mit eigenem Engangement und Interesse an
> anderen Sprachen keine einzige schlecht machen oder ausreden wollen.
> Nur wenns halt um die Ausbildung in einer einzigen Programmiersprache
> geht, dann doch C.
Ich denke, es geht, um Vorlesungsbegleitende Programmieruebungen zu
einer Mathematikvorlesung, und nicht um das lehren einer einzigen
Programmiersprache, die dann moeglichst nicht nur fuer das gesamte
Studium sondern auch noch erheblich darueber hinaus die einzig not-
wendige sein soll (letzteres wuerde IMHO auch i.d.R. nicht funktio-
nieren ...).
Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
PS: ich habe irgendwo gelesen, dass an einigen Unis in Frankreich fuer
"vorlesungsbegleitende Programmieruebungen" grundsaetzlich nur OCAML
verwendet wird ...
>> ist C eigentlich eine gute Basis um sich später in Richtung C++ oder
>> Java oder C# weiter zu entwickeln.
>
> URGS!
Wie urgs? Ist C keine gute Basis? Oder ist es nicht gut, C++ und Java
zu lernen? Wenn man diese Sprachen beherrscht, deckt man einen großen
Teil der Anforderungen des Marktes ab.
Ich finde den Weg C -> C++, Java jedenfalls prima.
Jirka
Hmmm, üblicherweise kommt dabei vergurktes C++ heraus, weil man doch
relativ schnell dazu neigt, C++ wie C zu programmieren - was ja durchaus
geht. Allerdings entspricht dies nicht einem klugen C++-Design, welches
durchaus anders als ein C-Design aussehen sollte. Kluge
Designstrategieen wie etwa RAII kann man in C nicht "natürlich"
einsetzen, stattdessen wird man für Fehlerbehandlung eher auf
Return-codes o.ä. zurückgreifen; und es liegt nahe, beim Umstieg auf C++
die entsprechenden Idiome einfach zu "portieren".
Grüße,
Thomas
Jirka Klaue schrub:
Ich habe dem Umstieg von C nach C++ noch nicht geschafft, obwohl
ich schon ein oder zwei Anläufe genommen habe. Das Problem ist
dabei weniger das Eintippen von Programmcode, sondern eher das,
was vorher im Kopf passiert: Man entwickelt einen Plan, wie man
das gegebene Problem löst.
Dieser Plan sieht bei mir immer so aus, dass ich mir überlege,
welche Daten ich zu verwalten habe, wie ich die in Strukturen
packen kann und welche Funktionen ich zum Manipulieren dieser
Daten brauche. Daraus wird dann ein C-Programm. Wollte ich jetzt
noch Objekte einführen also Datenstrukturen und die
dazugehörigen Funktionen zusammenfassen, dann käme mir dass wie
eine nachgeschaltete überflüssige Zusatzarbeit vor, die die
Sache nur verkompliziert.
Ich gehe warscheinlich einfach mit einer für OO-Programmierung
falschen Denkweise an die Probleme heran.
Und diese Denkweise neu/anders zu erlernen halte ich für gar
nicht so einfach.
CU Rollo
Das ist doch schon der richtige Ansatz: Datenstrukturen und die darauf
operierenden Funktionen gehören zusammen. Jetzt musst Du
diese Funktionen nur innerhalb einer Klasse deklarieren/definieren
und nicht im prozeduralen Stil getrennt voneinander.
Ok, das ist jetzt nicht die volle Objektorientierung, aber schon
mal ein Anfang um überhaupt mit Klassen/Objekten zu arbeiten.
> Wollte ich jetzt
> noch Objekte einführen also Datenstrukturen und die
> dazugehörigen Funktionen zusammenfassen, dann käme mir dass wie
> eine nachgeschaltete überflüssige Zusatzarbeit vor, die die
> Sache nur verkompliziert.
>
Den waren "Segen" der Objektorientierung erkennst Du erst,
wenn Du prozedurale Programme geschrieben hast deren Komplexität
so groß war/wurde, dass die Wartung und Änderung des Programms zu
schwerfällig wurde. Kluges objektorientiertes Design macht
den Code einfach wartbarer und agiler.
Gruß, Uwe
>> Ich finde den Weg C -> C++, Java jedenfalls prima.
>
> Hmmm, üblicherweise kommt dabei vergurktes C++ heraus, weil man doch
> relativ schnell dazu neigt, C++ wie C zu programmieren - was ja durchaus
> geht. Allerdings entspricht dies nicht einem klugen C++-Design, welches
> durchaus anders als ein C-Design aussehen sollte. Kluge
> Designstrategieen wie etwa RAII kann man in C nicht "natürlich"
> einsetzen, stattdessen wird man für Fehlerbehandlung eher auf
> Return-codes o.ä. zurückgreifen; und es liegt nahe, beim Umstieg auf C++
> die entsprechenden Idiome einfach zu "portieren".
Man darf sich schon ein bißchen Mühe geben. Jedenfalls halte ich den
umgekehrten Weg für schwieriger. Ein guter Java-Programmierer wird
sich auf einem Mikrokontroller mit C erstmal sehr schwer tun, wenn
er das vorher nicht gelernt hat.
Jirka
Und zu 'dem Fach' gehoert auch, dass man geeignete technische
Hilfsmittel, also zB Computer, zur Loesung von Problemen einsetzen
kann. Jetzt kann man ein Werkzeug aber nicht und nur schlecht
benutzen, wenn man ueberhaupt keine Idee davon hat, wie es denn nun
funktioniert. Man kann dann allerdings 'theoretische Softwaretechnik'
betreiben, dh sich irgendetwas albernes (zB Haskell) ausdenken und
"beweisen" das man es tatsaechlich implementieren kann. Was niemand,
der mit der Materie auch nur oberflaechlich vertraut ist, jemals
bezweifelt haette. Aber beeindrucken wollte man ja auch die anderen.
> Die Programmieruebungen dienen da meinem Verstaendnis nach dazu, die
> jeweils gelehrten Algorithmen formal aufschreiben und austesten zu
> koennen. Das leistet auch jede "nicht maschinennahe Sprache". Wozu
> benoetigt ihr da "Maschinennaehe"?
Jede Programmiersprache ist "maschinennah", es gibt nicht unbedingt
eine Implementierung der jeweiligen Maschine 'in Hardware' anstelle
ihrer Simulation durch Software auf einer ganz anderen
Maschine. Inwiefern Idiosynkrasien der JVM inherent wissenwerter
waeren, als Idiosynkrasien von CPU x oder y stuende zu
demonstrieren. Zumal man die fuer C gar nicht zu wissen braucht, denn
'die C-Maschine' gibt es auch nicht wirklich. Sie orientiert sich
lediglich mehr an der Funktion realer Mehrzweck-CPUs als viele andere
Sprachen. Was einem schlimmstenfalls egal sein kann und bestimmt nicht
schadet.
>> Da man in der Ausbuildung der Mathematiker ja nicht den Schwerpunkt
>> aufs Programmieren legt, ist C eigentlich eine gute Basis um sich
>> später in Richtung C++ oder Java oder C# weiter zu entwickeln.
>
> URGS!
Es ist eine simple Sprache, die sich auf Konstrukte beschraenkt, die
man ohne groesseres Hintergrundwissen ueber unterschiedliche
Softwarentwicklungskonzepte aus den letzten dreissig Jahren verstehen
kann, deren Syntax das Fundament der Syntax einer ganzen Reihe
anderer Sprache bildet. Gerade das ist wohl fuer viele Menschen schon
eine wesentliche Schwierigkeit, so unverstaendlich es auch scheinen
mag (ob ich { begin oder done } oder fi nenne, bleibt sich meines
Erachtens nach ziemlich gleich).
>> Ich hab ja auch prinzipiell nichts gegen Ada etc., aber wenn man den
>> Studenten eine einzige Programmiersprache für die Praxis mit geben
>> will, dann sind solche "Exoten" einfach zu speziell und zu wenig
>> verbreitet.
>
> Es ist *sinnvoller*, den Studenten die Faehigkeiten zu vermitteln, die
> sie benoetigen, um eine Programmiersprache zu erlernen, sowie die Fae-
> higkeit, einen Algorithmus so zu formulieren, wie es fuer die Implemen-
> tierung in einer (nahezu beliebigen) Sprache erforderlich ist.
Fuer den eigentlich fachfremden Anfaenger duerfte 'wie kann ich den
Computer benutzten um eine Naeherungsloesung berechnen lassen' sehr
viel nuetzlicher (und verstaendlicher) sein, als eine Vorstellung von
Sprach-Taxonomie vermittelt, die bestimmt auch fuer irgendetwas gut
ist.
Und C ist als Sprache dafuer eigentlich sogar gut geeignet.
Das mag so sein, aber dann hast du _sehr_ gutes Schuhwerk, der Weg ist
nämlich lang und beschwerlich. Das fängt schon beim Einstieg an. IMHO
eignet sich C an der Stelle noch überhaupt nicht. Nimm am Anfang eine
Sprache, die zum Lernen und Lehren gedacht ist, wie Ada oder Object
Pascal. Da gibt es ein paar kleine Hilfestellungen. Um nur ein kleines
Beispiel zu nennen: Wenn man ein Feld deklariert, dann geht das in C
so:
char a[20];
und das ist ein Feld mit den Elementen 0 - 19. Als angehender
Programmierer zählt man aber nicht unbedingt bei 0 los (das auch
etwas, das man nur lernen muss, wenn man C macht). In Pascal schreibt
man
var a: array [1 .. 20] of char;
und die Welt ist wieder in Ordnung.
Dann die ganzen Probleme, die man eventuell mit dem Namespace bekommen
kann... und dann erst der Präprozessor: Was man damit so alles falsch
machen kann...
Kurzum: Es ist sicher nichts neues, dass C keine Lehrsprache ist.
Warum sollte man nicht zum Lehren eine solche verwenden?
> Jirka
Tschö,
Markus
--
Nur weil ein Genie nix reißt, muß ja nun nicht gleich jeder Idiot
pausieren... Bully hats ja auch geschafft.
-- gUnter nanonüm in de.alt.anime
> Wenn man ein Feld deklariert, dann geht das in C so:
>
> char a[20];
>
> und das ist ein Feld mit den Elementen 0 - 19. Als angehender
> Programmierer zählt man aber nicht unbedingt bei 0 los (das auch
> etwas, das man nur lernen muss, wenn man C macht). In Pascal schreibt
> man
>
> var a: array [1 .. 20] of char;
>
> und die Welt ist wieder in Ordnung.
Willst Du ernsthaft behaupten, daß es ein großes geistiges Potential
verlangt, von 1-20 auf 0-19 zu kommen?
> Kurzum: Es ist sicher nichts neues, dass C keine Lehrsprache ist.
> Warum sollte man nicht zum Lehren eine solche verwenden?
Weil dann der Umstieg auf eine praxisrelevante Sprache schwerer fällt.
Jirka
> Markus Wichmann wrote:
>
>> Wenn man ein Feld deklariert, dann geht das in C so:
>>
>> char a[20];
>>
>> und das ist ein Feld mit den Elementen 0 - 19. Als angehender
>> Programmierer zählt man aber nicht unbedingt bei 0 los (das auch
>> etwas, das man nur lernen muss, wenn man C macht). In Pascal schreibt
>> man
>>
>> var a: array [1 .. 20] of char;
>>
>> und die Welt ist wieder in Ordnung.
>
> Willst Du ernsthaft behaupten, daß es ein großes geistiges Potential
> verlangt, von 1-20 auf 0-19 zu kommen?
Nein, aber von ['a' .. 'z'] auf 0-25. :P
>> Kurzum: Es ist sicher nichts neues, dass C keine Lehrsprache ist.
>> Warum sollte man nicht zum Lehren eine solche verwenden?
>
> Weil dann der Umstieg auf eine praxisrelevante Sprache schwerer fällt.
Genau. Wenn man C gelernt hat, fällt einem der Umstieg auf
- beispielsweise - Java ja auch viel leichter, weil man zwar immer noch
keine Ahnung von Objektorientierung hat, aber wenigstens schon mal
geschweifte Klammern kennt.
Vinzent.
>>> Wenn man ein Feld deklariert, dann geht das in C so:
>>>
>>> char a[20];
>>>
>>> und das ist ein Feld mit den Elementen 0 - 19. Als angehender
>>> Programmierer zählt man aber nicht unbedingt bei 0 los (das auch
>>> etwas, das man nur lernen muss, wenn man C macht). In Pascal schreibt
>>> man
>>>
>>> var a: array [1 .. 20] of char;
>>>
>>> und die Welt ist wieder in Ordnung.
>> Willst Du ernsthaft behaupten, daß es ein großes geistiges Potential
>> verlangt, von 1-20 auf 0-19 zu kommen?
> Nein, aber von ['a' .. 'z'] auf 0-25. :P
Oh, toll!
Es gibt also Pascal-Syntax, die nicht 1:1 auf C übertragbar ist.
Worauf willst Du hinaus?
>>> Kurzum: Es ist sicher nichts neues, dass C keine Lehrsprache ist.
>>> Warum sollte man nicht zum Lehren eine solche verwenden?
>> Weil dann der Umstieg auf eine praxisrelevante Sprache schwerer fällt.
> Genau. Wenn man C gelernt hat, fällt einem der Umstieg auf
> - beispielsweise - Java ja auch viel leichter,
Gut erkannt. Habe ich doch auch geschrieben, oder?
> weil man zwar immer noch
> keine Ahnung von Objektorientierung hat, aber wenigstens schon mal
> geschweifte Klammern kennt.
Kommt drauf an, was man (Du?) gelernt hat. OO hatte in meiner
Grundausbildung erstmal nichts mit C oder Java oder sonst einer
Sprache zu tun.
Jirka
> Vinzent Hoefler:
>> Jirka Klaue:
>>> Markus Wichmann:
>
>>>> Wenn man ein Feld deklariert, dann geht das in C so:
>>>>
>>>> char a[20];
>>>>
>>>> und das ist ein Feld mit den Elementen 0 - 19. Als angehender
>>>> Programmierer zählt man aber nicht unbedingt bei 0 los (das auch
>>>> etwas, das man nur lernen muss, wenn man C macht). In Pascal schreibt
>>>> man
>>>>
>>>> var a: array [1 .. 20] of char;
>>>>
>>>> und die Welt ist wieder in Ordnung.
>
>>> Willst Du ernsthaft behaupten, daß es ein großes geistiges Potential
>>> verlangt, von 1-20 auf 0-19 zu kommen?
>
>> Nein, aber von ['a' .. 'z'] auf 0-25. :P
>
> Oh, toll!
> Es gibt also Pascal-Syntax, die nicht 1:1 auf C übertragbar ist.
Nicht?
-- 8< --
int main(void)
{
int a['z'];
a['x'] = 3;
return 'c';
}
-- 8< --
Geht doch.
Nebenbei, ist mein gcc buggy oder warum warnt er bei "-std=c99"
nicht mit "control reaches end of non-void function", wenn ich das return
statement weglasse?
> Worauf willst Du hinaus?
Wenn Du mich so fragst: Darauf, dass C zum Erlernen des
Handwerks "Programmieren" eine der ungeeigneteren Möglichkeiten ist,
da es dafür einerseits in den Ausdrucksmöglichkeiten zu beschränkt und
andererseits einfach nicht tolerant gegenüber - gerade - Anfängerfehlern
ist. Es ist nun mal als portabler Makro-Assembler entstanden, aber ich
würde heute keinem mehr ernsthaft empfehlen, als /erste/
Programmiersprache Assembler zu erlernen.
>>>> Kurzum: Es ist sicher nichts neues, dass C keine Lehrsprache ist.
>>>> Warum sollte man nicht zum Lehren eine solche verwenden?
>
>>> Weil dann der Umstieg auf eine praxisrelevante Sprache schwerer fällt.
>
>> Genau. Wenn man C gelernt hat, fällt einem der Umstieg auf -
>> beispielsweise - Java ja auch viel leichter,
>
> Gut erkannt.
Du meinen Sarkasmus dafür angeblich nicht.
>> weil man zwar immer noch
>> keine Ahnung von Objektorientierung hat, aber wenigstens schon mal
>> geschweifte Klammern kennt.
>
> Kommt drauf an, was man (Du?) gelernt hat.
?
> OO hatte in meiner
> Grundausbildung erstmal nichts mit C oder Java oder sonst einer
> Sprache zu tun.
Genausowenig wie Programmieren mit C (oder sonst einer Sprache) zu tun hat,
richtig. Man kann es sich allerdings mit der Wahl des anfänglichen
Werkzeugs leicht oder schwer machen. Nun allerdings ausgerechnet mit einem
Werkzeug anzufangen, dessen virtuose Beherrschung einige Jahre an Erfahrung
voraussetzt, hielte ich für suboptimal.
Und was den Umstieg auf eine andere Sprache betrifft: Wenn man die
Grundlagen einigermassen beherrscht, ist der Rest ein bisschen Syntax und
ein paar Spracheigenheiten, die man in zwei Wochen intus hat.
Mein erstes Werkzeug zur Programmentwicklung waren Papier und Bleistift.
Und das ist bei mir auch heute noch unverzichtbares Mittel.
Vinzent.
> Nebenbei, ist mein gcc buggy oder warum warnt er bei "-std=c99"
> nicht mit "control reaches end of non-void function", wenn ich das return
> statement weglasse?
Weil ein »return 0;« am Ende von main() in C99 implizit ist:
,----[ http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf ]
| 5.1.2.2.3 Program termination
|
| 1 If the return type of the main function is a type compatible with int,
| a return from the initial call to the main function is equivalent to
| calling the exit function with the value returned by the main function
| as its argument; reaching the } that terminates the main function
| returns a value of 0. If the return type is not compatible with int,
| the termination status returned to the host environment is
| unspecified.
`----
Sven
> Am 27.08.2008 um 18:14 schrieb Vinzent Hoefler:
>
>> Nebenbei, ist mein gcc buggy oder warum warnt er bei "-std=c99"
>> nicht mit "control reaches end of non-void function", wenn ich das return
>> statement weglasse?
>
> Weil ein »return 0;« am Ende von main() in C99 implizit ist:
Ah, sowas hatte ich befürch^mir schon gedacht. Danke für die Aufklärung.
Vinzent.
Das da oben ist kein C. 'x' < 'z' wird nicht von der C-Norm gefordert,
damit ist das Verhalten der ersten Anweisung undefiniert. Das einzige,
was man sicher ueber sizeof(a) sagen kann, ist sizeof(a) >=
sizeof(int).
Anders ausgedrueckt: Nikolaus Wirths zahhllose, verkleidete
Zahlenmengen gibt es in C nicht.
[...]
>> Worauf willst Du hinaus?
>
> Wenn Du mich so fragst: Darauf, dass C zum Erlernen des
> Handwerks "Programmieren" eine der ungeeigneteren Möglichkeiten ist,
> da es dafür einerseits in den Ausdrucksmöglichkeiten zu beschränkt und
> andererseits einfach nicht tolerant gegenüber - gerade - Anfängerfehlern
> ist. Es ist nun mal als portabler Makro-Assembler entstanden,
Ein 'portabler Makro-Assembler' waere ein Uebersetzungsprogram fuer
eine Assemblersprache, das Makros unterstuetzt und portabel ist,
also zB Gnu as. C ist das, was Knuth eine 'algebraische Sprache'
nennt, also weder eine Assemblersprache noch ein Uebersetzungprogramm
fuer eine Assemblersprache.
[...]
>> OO hatte in meiner Grundausbildung erstmal nichts mit C oder Java
>> oder sonst einer Sprache zu tun.
>
> Genausowenig wie Programmieren mit C (oder sonst einer Sprache) zu tun hat,
> richtig. Man kann es sich allerdings mit der Wahl des anfänglichen
> Werkzeugs leicht oder schwer machen. Nun allerdings ausgerechnet mit einem
> Werkzeug anzufangen, dessen virtuose Beherrschung einige Jahre an Erfahrung
> voraussetzt, hielte ich für suboptimal.
Einen Haufen vollkommen kuenstlicher Konzepte zu lernen, die ausser
Softwaretheoretikern und Leute, die Teile dieser Theorien brauchen,
niemand kennt und die zusaetzlich noch eher Ideologietransporter als
irgendetwas anderes sind waere das auch.
int a[20];
definiert ein Feld von zwanzig Ganzzahlen, auf die ueber a[0] - a[19]
zugegriffen werden kann, ist dagegen eher simpel.
> On Wed, 27 Aug 2008 16:24:39 +0200, Jirka Klaue wrote:
>
>> Vinzent Hoefler:
>>
>>> Nein, aber von ['a' .. 'z'] auf 0-25. :P
>>
>> Oh, toll!
>> Es gibt also Pascal-Syntax, die nicht 1:1 auf C übertragbar ist.
>
> Nicht?
Nicht.
> int a['z'];
Ist ein anderes Array als das o.g. Pascal-Array. Außerdem fehlt das 'a'.
> a['x'] = 3;
Geht schief, wenn auf der Zielarchitektur 'x' > 'z' ist (so ein Teil
hatte ich mal, ist aber schon lange her).
> Geht doch.
Bewiesen hast Du's aber noch nicht :-)
Gruß. Claus
> > a['x'] = 3;
>
> Geht schief, wenn auf der Zielarchitektur 'x' > 'z' ist (so ein Teil
> hatte ich mal, ist aber schon lange her).
>
uiuiui, dann wirds mit lexikographischen sortieren aber lustig ;-)
oder waren da wenigstens a > b > c ... > y > z ????
gruss, uwe
>>> OO hatte in meiner Grundausbildung erstmal nichts mit C oder Java
>>> oder sonst einer Sprache zu tun.
>> Genausowenig wie Programmieren mit C (oder sonst einer Sprache) zu tun hat,
>> richtig. Man kann es sich allerdings mit der Wahl des anfänglichen
>> Werkzeugs leicht oder schwer machen. Nun allerdings ausgerechnet mit einem
>> Werkzeug anzufangen, dessen virtuose Beherrschung einige Jahre an Erfahrung
>> voraussetzt, hielte ich für suboptimal.
>
> Einen Haufen vollkommen kuenstlicher Konzepte zu lernen, die ausser
> Softwaretheoretikern und Leute, die Teile dieser Theorien brauchen,
> niemand kennt und die zusaetzlich noch eher Ideologietransporter als
> irgendetwas anderes sind waere das auch.
Für jemanden, der diese Konzepte nach eigener Aussage auch nicht kennt,
bzw. nicht gelernt hat, nimmst Du Dir hier aber erheblich viel heraus.
Ich bin für meinen Teil nicht Informatiker und beanspruche für mich
nicht, das zu sein, würde mich aber nicht erdreisten, über Kollegen
derart zu urteilen. Letztendlich muss man in einem Fachgebiet erstmal
etwas gearbeitet haben, um beurteilen zu können, "wozu das alles gut ist".
Da der OP Mathematik studieren will (und nicht vorrangig das
Programmieren erlernen mag, was mit Informatik fast, aber nicht ganz
überhaupt nichts zu tun hat), würde ich eher umgekehrt argumentieren und
zu einer funktionalen Programmiersprache raten, die die Denkweise von
Mathematikern sehr viel besser repräsentieren kann, als dies imperative
Sprachen könnten (zur Info: Ich bin Mathematiker). Die Frage "was man
letztendlich damit anfängt" ist für den Mathematiker (und die
Studierenden ebenso) erstmal zweitranging. Wichtig ist, das notwendige
Abstraktionsvermögen zu schulen, und da würde ich zu ganz anderen Dingen
raten. Mathematik ist die Lehre von Strukturen, und dem strukturierten
Denken darüber.
Nein, ich programmiere auch, und ja, dazu verwende ich Erlang oder
ähnliche Sprachen nicht, sondern C oder C++. Aber alles zu seinem Zweck
- praktische Sprachen für praktische Probleme.
Nein, ich hatte C++ als Programmiersprache in der Mathematik - hatte
selbst keine Probleme, zumal ich das schon vorher gelernt hatte, aber
finde ich als Wahl nicht optimal. Heute nimmt man gerne auch Java, was
ich ebensowenig ideal finde.
> int a[20];
>
> definiert ein Feld von zwanzig Ganzzahlen, auf die ueber a[0] - a[19]
> zugegriffen werden kann, ist dagegen eher simpel.
Sicher ist das simpel, aber nicht die Sorte von Problem, mit der man
sich als Mathematiker beschäftigen muss - höchstens später in der
Numerik, was auch wieder eine andere Kiste ist. Da wird teilweise noch
in FORTRAN gerechnnet (urgh). Aber wie ich schon schrieb: Alles zu
seinem Zweck.
Grüße,
Thomas
> Vinzent Hoefler <nntp-2...@t-domaingrabbing.de> writes:
>> On Wed, 27 Aug 2008 16:24:39 +0200, Jirka Klaue wrote:
>>> Vinzent Hoefler:
>>>
>>>> Nein, aber von ['a' .. 'z'] auf 0-25. :P
>>>
>>> Oh, toll!
>>> Es gibt also Pascal-Syntax, die nicht 1:1 auf C übertragbar ist.
>>
>> Nicht?
>>
>> -- 8< --
>> int main(void)
>> {
>> int a['z'];
>>
>> a['x'] = 3;
>>
>> return 'c';
>> }
>> -- 8< --
>>
>> Geht doch.
>
> Das da oben ist kein C. 'x' < 'z' wird nicht von der C-Norm gefordert,
> damit ist das Verhalten der ersten Anweisung undefiniert.
Das hatte ich gehofft.
> Das einzige,
> was man sicher ueber sizeof(a) sagen kann, ist sizeof(a) >=
> sizeof(int).
a[0]?
> Anders ausgedrueckt: Nikolaus Wirths zahhllose, verkleidete
> Zahlenmengen gibt es in C nicht.
Das erwähnten andere schon. Also durchaus unintuitiv für durchschnittliche
C-Programmierer ("Wieso? Compiliert doch? Und funktionieren tut's
bei mir auch."), erst recht also für Anfänger.
>>> Worauf willst Du hinaus?
>>
>> Wenn Du mich so fragst: Darauf, dass C zum Erlernen des Handwerks
>> "Programmieren" eine der ungeeigneteren Möglichkeiten ist, da es dafür
>> einerseits in den Ausdrucksmöglichkeiten zu beschränkt und andererseits
>> einfach nicht tolerant gegenüber - gerade - Anfängerfehlern ist. Es ist
>> nun mal als portabler Makro-Assembler entstanden,
>
> Ein 'portabler Makro-Assembler' waere ein Uebersetzungsprogram fuer eine
> Assemblersprache, das Makros unterstuetzt und portabel ist, also zB Gnu
> as.
Seit wann ist "as" portabel? Mit dem hochoptimierten i386er-Code kann der
"as" einer SPARC genau gar nichts anfangen.
> C ist das, was Knuth eine 'algebraische Sprache' nennt, also weder
> eine Assemblersprache noch ein Uebersetzungprogramm fuer eine
> Assemblersprache.
Mag sein, dass es das jetzt *ist* (MacOS X ist ja schliesslich auch ein
UNIX), aber das war nicht der Anspruch bei der Entwicklung der Sprache vor
über 40 Jahren (oder so ungefähr). Der Anspruch war, eine portablen,
maschinennahe Sprache zu schaffen, um Betriebssysteme nicht immer wieder
neu schreiben zu müssen, wenn es neue Hardware gab. So ähnlich zumindest.
Eine portablen Assembler eben.
> int a[20];
>
> definiert ein Feld von zwanzig Ganzzahlen, auf die ueber a[0] - a[19]
> zugegriffen werden kann, ist dagegen eher simpel.
Simpel aus Sicht der darunterliegenden Maschine, nicht aus Sicht des
Anfängers. Und solange in "professionellen" Umgebungen geschriebener Code
so aussieht ...
-- 8< --
int SOMEPREFIX_Set_IndexCounter1(const unsigned short usSend)
{
unsigned char *CharData;
BOOL Success = TRUE;
CharData = (unsigned char *) &CounterValue;
if (!TRIGGER_SetCounter1Index(CharData[0]))
{
Success = FALSE;
}
if (!TRIGGER_SetCounter1Index(CharData[1]))
{
Success = FALSE;
}
return (Success);
}
-- 8< --
(Das ganze dann noch mal für SetIndexCounter2 und SetIndexCounter3
inklusive der entsprechenden Unterfunktionen.)
... so lange halte ich C als Lernsprache für ungeeignet. Offensichtlich
schaffen es ja nicht einmal gestandene (sich selbst so bezeichnende)
C-Programmierer, halbwegs anständigen, simplen und korrekten Code zu
schreiben.[1]
Wie soll dann erst ein Anfänger damit klar kommen?
Vinzent.
[1]Ehrlich gesagt, würde ich diese Leute lieber erst mal zu ein paar
Schulungen schicken, wo solche fruchtlosen "softwaretheoretischen"
Erkenntnisse lieber noch einmal wiederholt werden, bevor sie sich wieder
ihrer 2478 Zeilen umfassenden main() Funktion widmen dürfen. Well, not my
call.
> Vinzent Hoefler schrieb:
>
>> On Wed, 27 Aug 2008 16:24:39 +0200, Jirka Klaue wrote:
>>
>>> Vinzent Hoefler:
>>>
>>>> Nein, aber von ['a' .. 'z'] auf 0-25. :P
>>>
>>> Oh, toll!
>>> Es gibt also Pascal-Syntax, die nicht 1:1 auf C übertragbar ist.
>>
>> Nicht?
>
> Nicht.
>
>> int a['z'];
>
> Ist ein anderes Array als das o.g. Pascal-Array.
Ja. Aber Anfänger, die mal eben 256 MByte lokale Variablen deklarieren,
interessieren die paar Bytes, die da (in den meisten Fällen) sinnlos
draufgehen, nicht.
Würde ich genau genommen nicht einmal ankreiden, bewiese der Delinquent
doch immerhin Abstraktionsvermögen. ;)
> Außerdem fehlt das 'a'.
Also, ein paar Abstriche an der Syntax muss man schon machen.
>> a['x'] = 3;
>
> Geht schief, wenn auf der Zielarchitektur 'x' > 'z' ist (so ein Teil
> hatte ich mal, ist aber schon lange her).
Ja, darauf wollte ich ja schlussendlich auch hinaus. Inwiefern das für
Anfänger intuitiv ist, lasse ich mal dahingestellt. Ebenso die Frage, wie
viele real existierende System es noch gibt, bei denen das tatsächlich so
ist.
>> Geht doch.
>
> Bewiesen hast Du's aber noch nicht :-)
Nach Art eines Ex-Kollegen: "Ich hab's kompiliert und getestet, es
funktioniert." schon.
Vinzent.
Von wegen! Auf diesem Rechner waren alle Zeichen ab 96 aufwärts
(Kleinbuchstaben, Sonderzeichen, grafische Symbole) bunt und lustig
durcheinandergemischt. Darunter war alles brav ASCII.
War übrigens ein Sharp MZ80-K, falls es Jemanden interessiert.
Gruß. Claus
Jirka Klaue <kl...@dresearch.de> wrote:
> Markus Wichmann wrote:
>> Kurzum: Es ist sicher nichts neues, dass C keine Lehrsprache ist.
>> Warum sollte man nicht zum Lehren eine solche verwenden?
> Weil dann der Umstieg auf eine praxisrelevante Sprache schwerer fällt.
Warum sollte der Umstieg von C leichter fallen als der von z.B. Ada
(oder Modula2 oder ...)?
Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
Uwe Schmitt schrub:
> Das ist doch schon der richtige Ansatz: Datenstrukturen und die
> darauf operierenden Funktionen gehören zusammen. Jetzt musst Du
> diese Funktionen nur innerhalb einer Klasse
> deklarieren/definieren und nicht im prozeduralen Stil getrennt
> voneinander.
>
> Ok, das ist jetzt nicht die volle Objektorientierung, aber
> schon mal ein Anfang um überhaupt mit Klassen/Objekten zu
> arbeiten.
So habe ich das hier auch schon gelesen. Man kann das alles schön
kapseln, z.B. Datentypen nur so/dort definieren, dass nur ein
paar Funktionen diese Definitionen überhaupt sehen, dass sind
dann die Funktionen, die diese Daten manipulieren. Nur das geht
in C auch schon:-).
> Den waren "Segen" der Objektorientierung erkennst Du erst,
> wenn Du prozedurale Programme geschrieben hast deren
> Komplexität so groß war/wurde, dass die Wartung und Änderung
> des Programms zu schwerfällig wurde. Kluges objektorientiertes
> Design macht den Code einfach wartbarer und agiler.
So große Programme habe ich bisher halt nicht geschrieben, ich
glaube nicht, dass ich schon mal bei einem Projekt über 10000
Zeilen gekommen bin. Bin halt nur Hobby-Klein-Programmierer.
Objektorientiert steht für mich immer in engem Zusammenhang mit
GUI-Programmierung. Wohl, weil die meisten GUI-Programmiertools
in C++ arbeiten. Mein Problem dabei ist wohl noch ein anderes:
So ein Programm mit Fenstern und Events und so läuft halt nicht
so ab, wie ein klassisches Programm mit Anfang und Ende und dem
dazwischen.
Vermutlich vermenge ich diese beiden Probleme miteinander: Das
eine ist die OO-Programmierung, das andere ist die
GUI-Programmierung bei der ein Programm eben keinen klaren
Ablaufplan mehr hat.
CU Rollo
Rainer Weikusat <rwei...@mssgmbh.com> wrote:
> Juergen Ilse <il...@usenet-verwaltung.de> writes:
>> Uwe Schmitt <rockspo...@googlemail.com> wrote:
>>> On 26 Aug., 16:45, Juergen Ilse <i...@usenet-verwaltung.de> wrote:
>>>> Uwe Schmitt <rocksportroc...@googlemail.com> wrote:
>>>> > Aber im Ernst: wir haben uns bewusst für C entschieden, da C noch
>>>> > recht "nahe an der Maschine" ist aber mehr kann als Fortran77.
>>>> Wenn es zur Implementierung von Uebungen zur Mathematik sein soll:
>>>> Wozu braucht ihr da "Naehe zur Maschine"?
>>> Meiner Meinung nach kann man so besser lernen wie ein Computer
>>> eigentlich arbeitet. Prolog, Haskel, Lisp, ... hinterlassen beim
>>> Programmieranfänger eher den Eindruck einer Black Box.
>> Na und? Das Fach heisst doch "Mathematik" und nicht "Architekturen
>> von heutigen Computern", oder irre ich mich da?
> Und zu 'dem Fach' gehoert auch, dass man geeignete technische
> Hilfsmittel, also zB Computer, zur Loesung von Problemen einsetzen
> kann.
War nicht von Fach "Mathematik" die Rede? Das hat noch nicht einmal
zwingend ueberhaupt etwas mit Rechnern zu tun ...
> Jetzt kann man ein Werkzeug aber nicht und nur schlecht
> benutzen, wenn man ueberhaupt keine Idee davon hat, wie es denn nun
> funktioniert. Man kann dann allerdings 'theoretische Softwaretechnik'
> betreiben, dh sich irgendetwas albernes (zB Haskell) ausdenken und
> "beweisen" das man es tatsaechlich implementieren kann. Was niemand,
> der mit der Materie auch nur oberflaechlich vertraut ist, jemals
> bezweifelt haette. Aber beeindrucken wollte man ja auch die anderen.
War hier von einer "Lehre als Programmierer" oder einem "Mathematik-
studium" die Rede?
>> Die Programmieruebungen dienen da meinem Verstaendnis nach dazu, die
>> jeweils gelehrten Algorithmen formal aufschreiben und austesten zu
>> koennen. Das leistet auch jede "nicht maschinennahe Sprache". Wozu
>> benoetigt ihr da "Maschinennaehe"?
> Jede Programmiersprache ist "maschinennah", es gibt nicht unbedingt
> eine Implementierung der jeweiligen Maschine 'in Hardware' anstelle
> ihrer Simulation durch Software auf einer ganz anderen Maschine.
Stimmt, und da Mathematik nicht zwingend mit Computer-Hardware zu tun
hat, sollte man fuer die vorlesungsbegleitenden Uebungen einer Mathematik-
vorlesung auch nicht auf bestimmte Hardware Ruecksicht nehmen muessen.
Ergo: "Hardwarenaehe" ueberfluessig.
>>> Da man in der Ausbuildung der Mathematiker ja nicht den Schwerpunkt
>>> aufs Programmieren legt, ist C eigentlich eine gute Basis um sich
>>> später in Richtung C++ oder Java oder C# weiter zu entwickeln.
>> URGS!
> Es ist eine simple Sprache, die sich auf Konstrukte beschraenkt, die
> man ohne groesseres Hintergrundwissen ueber unterschiedliche
> Softwarentwicklungskonzepte aus den letzten dreissig Jahren verstehen
> kann, deren Syntax das Fundament der Syntax einer ganzen Reihe
> anderer Sprache bildet.
Es ist aber nicht die Sprache, die ideal zur Umsetzung dessen ist, was
man typischerweise in "vorlesungsbegleitenden Uebungen zu einer Mathemtik-
vorlesung" erwarten wuerde. Fuer numerische Probleme ist auch heute noch
immer Fortran die beliebtere Wahl (auch nicht ganz unberechtigt, obwohl
ich die Sprache nicht im geringsten magt), fuer viele andere Bereiche
der Mathematik waeren funktionale Sprachen besser geeignet (Rekursion
ist in Lisp und verwandten Sprachen eine Trivialitaet).
>> Es ist *sinnvoller*, den Studenten die Faehigkeiten zu vermitteln, die
>> sie benoetigen, um eine Programmiersprache zu erlernen, sowie die Fae-
>> higkeit, einen Algorithmus so zu formulieren, wie es fuer die Implemen-
>> tierung in einer (nahezu beliebigen) Sprache erforderlich ist.
> Fuer den eigentlich fachfremden Anfaenger duerfte 'wie kann ich den
> Computer benutzten um eine Naeherungsloesung berechnen lassen' sehr
> viel nuetzlicher (und verstaendlicher) sein, als eine Vorstellung von
> Sprach-Taxonomie vermittelt, die bestimmt auch fuer irgendetwas gut
> ist.
Fuer "eine erste Naeherung" benutzt man schlicht einen Taschenrechner ...
Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
In C wirds dann aber z.B. schon schwierig den Überblick über die
Funktionsnamen zu behalten.
Auch wenn Du momentan keinen Mehrzweck darin siehst, so würde
ich an Deiner Stelle trotzdem so vorgehen. Dann kriegst Du
ein Gefühl für die Sache und kannst von dort aus dich Richtung
OO weiter bewegen.
>
> > Den waren "Segen" der Objektorientierung erkennst Du erst,
> > wenn Du prozedurale Programme geschrieben hast deren
> > Komplexität so groß war/wurde, dass die Wartung und Änderung
> > des Programms zu schwerfällig wurde. Kluges objektorientiertes
> > Design macht den Code einfach wartbarer und agiler.
>
> So große Programme habe ich bisher halt nicht geschrieben, ich
> glaube nicht, dass ich schon mal bei einem Projekt über 10000
> Zeilen gekommen bin. Bin halt nur Hobby-Klein-Programmierer.
Naja, 10000 Zeilen ist schon ein großes Programm. Versuchs mal
mit OO wie oben beschrieben. Denke Du wirst den Unterschied
merken.
http://oreilly.com/catalog/9780596008673/ soll recht gut sein,
ist wohl in Java.
Gruß, Uwe
Man muß xcode installieren...
...DVD sollte dabeisein.
Weil die grundlegende Syntax schon bekannt ist, dh der 'Um Gottes
Willen! Wo bin ich denn hier gelandet ?!?'-Effekt beim Anblick von
etwas vollkommen ungewohnt ausehenden wird vermieden.
Ein Beispiel aus einem anderen Gebiet waere: Warum sollte
irgendjemand, der XP kennt, (Anfangs-)Schwierigkeiten mit Vista haben?
Anwort: Keine Ahnung, isaberso.
Der Effekt währt höchstens 5 Sekunden.
> Ein Beispiel aus einem anderen Gebiet waere: Warum sollte
> irgendjemand, der XP kennt, (Anfangs-)Schwierigkeiten mit Vista haben?
>
> Anwort: Keine Ahnung, isaberso.
Warum sollte jemand der Linux kennt, Probleme mit Linux haben? (Gut,
er kennt nicht wirklich Linux, sondern nur KDE und ist total hilflos,
wenn man ihn vor ein nacktes Openbox setzt).
So wird da schon eher ein Schuh draus. Er (der viel zitierte "jemand")
sollte schnell herausfinden, dass er jetzt keinen Button da unten mehr
hat, das aber wurscht ist, weil er mittels Rechtsklick ein xterm
starten kann, und da muss er nur den Namen des zu startenden Programms
eintippen und fertig. Und wenn er den nicht weiß, gibt es wenigstens
bei Debian ein großes Menü, das auch bloß nicht viel anders aussieht,
als das, das man von KDE geboten bekommt.
So, jetzt wieder zurück analogisieren: Relativ schnell wird der Jemand
feststellen, dass 'begin' jetzt '{' heißt und Strings mit '"' begrenzt
werden, Zeichen hingegen mit ''''. Ach ja, '''' muss man jetzt nicht
mehr auf die gezeigte Weise escapen.
Das ist halt das Übliche: Wenn man Programmieren kann, ist die Sprache
nebensächlich. Wenn man dann noch etwas weiter ist, weiß man: Jede
Sprache eignet sich für bestimmte Dinge besser als andere
(Stringmanipulation in C: Gott, behüte! ALSA mit Pascal ist aber auch
nicht wirklich toll).
Rainer Weikusat wrote:
> Juergen Ilse <il...@usenet-verwaltung.de> writes:
...[...]...
>>Warum sollte der Umstieg von C leichter fallen als der von z.B. Ada
>>(oder Modula2 oder ...)?
>
> Weil die grundlegende Syntax schon bekannt ist, dh der 'Um Gottes
> Willen! Wo bin ich denn hier gelandet ?!?'-Effekt beim Anblick von
> etwas vollkommen ungewohnt ausehenden wird vermieden.
Moeglich. Da war aber noch was mit der Lernreihenfolge.
> Ein Beispiel aus einem anderen Gebiet waere: Warum sollte
> irgendjemand, der XP kennt, (Anfangs-)Schwierigkeiten mit Vista haben?
>
> Anwort: Keine Ahnung, isaberso.
Ich habe weder mit XP noch Vista mehr Probleme gehabt als
ein geuebter Windoofs-Looser. Ich komme aus der Ecke PM
(Presentation Manager, OS/2) und XFree86 (ICEWM, KDE, Unix).
Das scheint die richtige Lernreihenfolge zu sein. Probleme
gibt es bei allen Windoofs-Systemen wegen der Stabilitaet,
Unhandlichkeit, minderwertigen Qualitaet und Ausruestung.
Aber wer nix Besseres kennt bemerkt gar nicht auf was fuer
einen verwesenden Gaul er da daherzockelt. Auf der anderen
Seite scheint MAC fuer den Profi_anwender_ von morgen ein
guter Einstieg zu sein. Windoofs ist _definitiv_ kein
sinnvoller Einstieg in die Welt der Rechner!
Zurueck zum C: Es ist an der richtigen Einstiegsstelle in
der Lernreihenfolge fuer Informatik und IT. Fortran ist
fuer Naturwissenschaftler (immer noch) sinnvoller.
MfG
Uwe Borchert
> Weil die grundlegende Syntax schon bekannt ist, dh der 'Um Gottes
> Willen! Wo bin ich denn hier gelandet ?!?'-Effekt beim Anblick von
> etwas vollkommen ungewohnt ausehenden wird vermieden.
Tja, die Praxis hat mir was anderes gezeigt. Einerseits hauptsächlich
SPS-Programmierer, die ST kennen (nach meinem Dafürhalten ein
Bastard von Pascal, MODULA und Ada), also durchaus nichts, was syntaktisch
irgendwie C ähnelt. Andererseits und interessanterweise waren es aber die
langjährigen C-Programmierer ("Hab ich im Physikstudium gelernt."), die
sich an die Eigenheiten von Java (gerüchtehalber eine Programmiersprache,
deren Syntax als C-ähnlich gilt) so schnell nicht gewöhnen konnten.
Auch die Studenten, denen seinerzeit Grundlagen von OOP erst einmal in
Smalltalk beigebracht bekamen, hatten trotz teilweise doch recht stark
vorhandenen C/C++-u.ä. Kenntnissen absolut keine Probleme. Und die Syntax
von Smalltalk ist doch um einiges anders als die von
sogenannten "praxisrelevanten" Programmiersprachen.
Kurz und gut, ich wage es hiermit, das Syntax-Argument in die Tonne zu
treten.
Vinzent.
[0] "Strukturierter Text", welch Name für eine Programmiersprache.[1]
[1] Ich hätte vielleicht meine Code-Kommentare so bezeichnet.
Ich habe das gelernt, Trottel. Deswegen lebt Du (auch) von meinem Geld
und nicht umgekehrt.
Das ist eine Aussage ueber das, was C und Java (Deiner Ansicht nach)
unterscheidet, naemlich, dass irgendwelche Dir bekannten Leute, die
ausserdem mal an einer namenlosen deutschen Hochschule Physik studiert
haben, Schwierigkeiten gehabt haetten, diese zu erlernen. Das bedeutet
etwas ueber diese Leute ('hatten Schwierigkeiten mit nichtgenannten
Aspekten von Java') und weiter nichts. Insbesondere sagt es nichts
ueber die Gemeinsamkeiten beider Sprachen, also zB die von mir
angesprochene grundsaetzlich aehnliche Syntax.
Daraus, dass jemand imstande sein sollte (hier beduerfte es eigentlich
einer 'richtigen' soziologischen Studie, die aber wohl niemand machen
wird), zB die Blockstruktur eines gegebenen Quelltextes ohne Muehe zu
erkennen, folgt jetzt nicht, dass er jeden anderen Inhalt auch
verstehen muesste (es gibt aber wohl ausserdem noch aehnliche oder
gleiche Operatoren[*]).
[*] 'Andere Programmiersprachen' treten bei mir nur insofern
auf, als das jemand von mir erwartet, vorhandene Quelltexte
in einer bestimmten Sprache gut genug zu verstehen, um sie
(sinnvoll) aendern zu koennen. Das war fuer Java, das sich
uebrigens bei Leuten, die Software nicht schreiben, sondern
bloss benutzen, eines ausgesprochen schlechten Rufs erfreut,
bislang nicht der Fall.
> So, jetzt wieder zurück analogisieren: Relativ schnell wird der Jemand
> feststellen, dass 'begin' jetzt '{' heißt und Strings mit '"' begrenzt
> werden, Zeichen hingegen mit ''''.
Es sei denn, der Jemand trifft auf
char a[20];
oder was?
Du hast doch vorgestern noch ganz anders geredet.
> Das ist halt das Übliche: Wenn man Programmieren kann, ist die Sprache
> nebensächlich.
Es dauert jedenfalls eine Weile, die jeweiligen Libs kennenzulernen.
Die Java-API ist ziemlich umfangreich. Die STL ist auch nicht über-
sichtlich und selbst C hat eine Menge Zeugs eingebaut (ich vermute
mal, daß kaum jemand weiß, daß es z.B. feraiseexcept() oder scalblnl()
gibt).
Jirka
> Vinzent Hoefler <nntp-2...@t-domaingrabbing.de> writes:
>> On Thu, 28 Aug 2008 14:55:08 +0200, Rainer Weikusat wrote:
>>> Weil die grundlegende Syntax schon bekannt ist, dh der 'Um Gottes
>>> Willen! Wo bin ich denn hier gelandet ?!?'-Effekt beim Anblick von
>>> etwas vollkommen ungewohnt ausehenden wird vermieden.
>>
>> Tja, die Praxis hat mir was anderes gezeigt. Einerseits hauptsächlich
>> SPS-Programmierer, die ST kennen (nach meinem Dafürhalten ein
>> Bastard von Pascal, MODULA und Ada), also durchaus nichts, was syntaktisch
>> irgendwie C ähnelt. Andererseits und interessanterweise waren es aber die
>> langjährigen C-Programmierer ("Hab ich im Physikstudium gelernt."), die
>> sich an die Eigenheiten von Java (gerüchtehalber eine Programmiersprache,
>> deren Syntax als C-ähnlich gilt) so schnell nicht gewöhnen konnten.
>
> Das ist eine Aussage ueber das, was C und Java (Deiner Ansicht nach)
> unterscheidet,
Nein, eine Aussage darüber, dass bereits bekannte Syntax beim Erlernen
einer neuen Programmiersprache offenkundig irrelevant ist.
> Das bedeutet etwas ueber diese Leute ('hatten Schwierigkeiten
> mit nichtgenannten Aspekten von Java') und weiter nichts.
Natürlich bedeutet es etwas über diese Menschen. Ich habe ja auch
keine Aussagen über Programmiersprachen machen wollen. Es ging um die
Aussage, dass das Erlernen von C eine angeblich gute Voraussetzung zum
Erlernen (anderer) praxisrelevanter Sprachen sei. Das letzte Mal, als ich
nachgeschaut habe, waren es Menschen, die Programmiersprachen erlernen,
nicht andersherum.
Vinzent.
> Markus Wichmann:
>
>> So, jetzt wieder zurück analogisieren: Relativ schnell wird der Jemand
>> feststellen, dass 'begin' jetzt '{' heißt und Strings mit '"' begrenzt
>> werden, Zeichen hingegen mit ''''.
>
> Es sei denn, der Jemand trifft auf
> char a[20];
> oder was?
Es ist durchaus ein Unterschied, ob man das als erste Sprache lernt und
daraus schliesst, dass es "grundsätzlich nicht anders geht" oder als
Zweitsprache, wodurch man lernt, dass es "hier nicht anders geht".
> Es dauert jedenfalls eine Weile, die jeweiligen Libs kennenzulernen.
Lesen sollte man halt können. Völlig egal, mit welcher Sprache man beginnt.
Vinzent.
Als Programmierneuling in Richtung Mathematik sind die Libs
wahrscheinlich erstmal zweitrangig.
Es werden wohl keine GUIs und Buttons benötigt.
Aber, wie in dclc reichlich zu sehen ist, sind
char a[20];
char *a;
char *a[20];
char (*a)[20];
usw.
die Probleme, die einem Anfänger zu schaffen machen.
Er muß sich um Dinge kümmern, die mit seinem Problem
nichts zu tun haben, und ihm aufgrund des 'low-levels'
der Sprache einfach von niemandem abgenommen werden.
Eine Sprache, die einen Anfänger vom Memoryhandling
fernhält, die Pointerarithmetik verbirgt und das Überschreiben
von Boundaries weitgehend verhindert ist in meinen Augen
am ehesten als Lernsprache geeignet. (Basic?)
Gruß Holger
>> Es dauert jedenfalls eine Weile, die jeweiligen Libs kennenzulernen.
> Lesen sollte man halt können. Völlig egal, mit welcher Sprache man beginnt.
Ich wollte zum Ausdruck bringen, daß "eine Sprache lernen" mehr
bedeutet, als die Syntax zu kennen.
Im Hinblick auf die Lernreihenfolge ist eh schon alles gesagt: Man ist
nicht der gleichen Meinung.
Jirka
> Aber, wie in dclc reichlich zu sehen ist, sind
>
> char a[20];
> char *a;
> char *a[20];
> char (*a)[20];
> usw.
>
> die Probleme, die einem Anfänger zu schaffen machen.
>
> Er muß sich um Dinge kümmern, die mit seinem Problem
> nichts zu tun haben, und ihm aufgrund des 'low-levels'
> der Sprache einfach von niemandem abgenommen werden.
>
> Eine Sprache, die einen Anfänger vom Memoryhandling
> fernhält, die Pointerarithmetik verbirgt und das Überschreiben
> von Boundaries weitgehend verhindert ist in meinen Augen
> am ehesten als Lernsprache geeignet. (Basic?)
Ich habe auch mit BASIC angefangen, dann Turbo-Pascal und
Modula-2. Das ganze Array- und Zeigergeraffel ist mir deshalb in C
trotzdem nicht leicht gefallen. C++ und Java waren dann kein wirklich
schlimmes Problem mehr. Vielleicht liegt's aber auch einfach an
der Anzahl der Jahre, die man programmiert. Vielleicht aber auch
nicht. :-)
Jirka
> [...], eine Aussage darüber, dass bereits bekannte Syntax beim Erlernen
> einer neuen Programmiersprache offenkundig irrelevant ist.
Ich habe eine Weile gebraucht, um von a[3,4] auf a[2][3] zu kommen, vor
allem, weil der Compiler nichts gesagt hat. Heute gehe ich an sowas
anders ran, aber ähnliche (möglichst gleiche) Syntax und Semantik finde
ich immer noch hilfreich. Was spricht denn Deiner Meinung nach dagegen?
Jirka
> Vinzent Hoefler:
>> Jirka Klaue:
>
>>> Es dauert jedenfalls eine Weile, die jeweiligen Libs kennenzulernen.
>
>> Lesen sollte man halt können. Völlig egal, mit welcher Sprache man beginnt.
>
> Ich wollte zum Ausdruck bringen, daß "eine Sprache lernen" mehr
> bedeutet, als die Syntax zu kennen.
Ja, ich glaube, darüber sind wir uns einig.
Eben deshalb halte ich das Syntax-Argument ja für sehr fadenscheinig.
> Im Hinblick auf die Lernreihenfolge ist eh schon alles gesagt: Man ist
> nicht der gleichen Meinung.
Das auch. Allerdings ist bei C die Lernkurve doch recht steil, wenn man es
"richtig" machen will. Es ist keine Sprache, die ich einem Anfänger
empfehlen würde. Segfaults beim Aufruf von printf() stellen nun mal kein
Erfolgserlebnis dar. ;)
Vinzent.
,----
| Das ist eine Aussage ueber das, was C und Java (Deiner Ansicht nach)
| unterscheidet, naemlich, dass irgendwelche Dir bekannten Leute, die
| ausserdem mal an einer namenlosen deutschen Hochschule Physik studiert
| haben, Schwierigkeiten gehabt haetten, dieses zu erlernen.
`----
Wie ich ausserdem bereits geschrieben hatte:
,----
| Daraus, dass jemand imstande sein sollte [...], zB die Blockstruktur
| eines gegebenen Quelltextes ohne Muehe zu erkennen, folgt jetzt nicht,
| dass er jeden anderen Inhalt auch verstehen muesste
`----
Dh ich widerspreche Deiner Kernaussage gar nicht, sie geht bloss an
meiner vollkommen vorbei.
>> Das bedeutet etwas ueber diese Leute ('hatten Schwierigkeiten
>> mit nichtgenannten Aspekten von Java') und weiter nichts.
>
> Natürlich bedeutet es etwas über diese Menschen. Ich habe ja auch
> keine Aussagen über Programmiersprachen machen wollen. Es ging um die
> Aussage, dass das Erlernen von C eine angeblich gute Voraussetzung zum
> Erlernen (anderer) praxisrelevanter Sprachen sei.
Es 'ging' wohl eher darum, dass jemand so mutig war, oeffentlich
zuzugeben, C unterrichten zu wollen, was die ueblichen Verdaechtigen,
die solches nicht leiden moegen, auf den Plan gerufen hat.
Das kommt auf den Einsatzzweck an. Zum Formulieren von (wahrscheinlich
recht einfachen) mathematischen Algorithmen ist C jedenfalls auch
geeignet, denn man kommt dabei nicht mit dem, was als C-Schwierigkeit
gilt, in Beruehrung, zumal wenn das 'das habe ich aber anderswo anders
gelernt'-Problem wegfaellt. Ich denke auch nicht, dass irgendeines der
oa Dinge fuer sich in einfachen Programmen problematisch ist, waehrend
komplexe Programme immer die Loesung komplexerer Probleme
erfordern. Es gibt zum Beispiel ueberhaupt keinen Grund, jemanden von
'Pointerarithmetik' fernzuhalten, denn diese vereinfacht bestimmte
Dinge (zB lexikalische Analyse/ Parsing oder auch nur
Array-Traversals) erheblich. Ein Beispiel dafuer waere:
static int const some_values[] = {
3,
2,
1,
45,
-1
};
int const *pv;
pv = some_values;
while (*pv != -1) {
do_something(*pv);
++pv;
}
Es gibt schlicht keine real existierenden Dinge, die keinen sich
ueber einen bestimmten Zeitraum hinweg veraendernden Zustand haben.
'Zustandsfreiheit' gibt es nur im Rahmen bestimmter, menschlicher
Vorstellungswelten, denen die Mehrzahl der auf der Strasse
herumlaufenden Leute mit nahezu vollkommenem Unverstaendnis gegenueber
steht.
> Vinzent Hoefler:
>
>> [...], eine Aussage darüber, dass bereits bekannte Syntax beim Erlernen
>> einer neuen Programmiersprache offenkundig irrelevant ist.
>
> Ich habe eine Weile gebraucht, um von a[3,4] auf a[2][3] zu kommen,
Das wird dem Anfänger in C aber auch ohne weitere Vorkenntnisse so
gehen. Ich hatte jedenfalls damit eher wenig Probleme, da ich auch
0-basierte Array bereits kannte und in Pascal a[3][4] genauso gut
geht wie die Notation mit Kommas. ;) YMMV.
> vor allem, weil der Compiler nichts gesagt hat.
*Das* ist eben das Problem, gerade für Anfänger. C-Compiler neigen
nunmal (philosophiebedingt) dazu, allen möglichen Dreck zu akzeptieren.
So finde ich heute noch Code, der etwa so aussieht:
|void Foo (char[][260] bar) { ...
CMMIW, aber für sonderlich sinnvoll halte ich dieses Konstrukt nicht. Dass
dazu noch die Ignoranz der erwähnten langjährigen C-Programmierer ("Wieso?
Funktioniert doch.") kommt, mag ein persönliches Problem sein, aber es
überzeugt mich nicht gerade davon, dass es Anfänger mit dieser Sprache
leicht haben.
> Heute gehe ich an sowas
> anders ran, aber ähnliche (möglichst gleiche) Syntax und Semantik finde
> ich immer noch hilfreich. Was spricht denn Deiner Meinung nach dagegen?
Ich habe nicht gesagt, dass ich dagegen bin. Ich sagte nur, dass ich es
für eher wenig relevant halte.
Die Erfahrung. Ich habe irgendwann 1986 mit KC-BASIC und Z80-Assembler
angefangen (im zarten Alter von 12 Jahren macht man solche Fehler
halt), habe ein wenig Forth und Pascal kennengelernt, und bin dann 1992
mittels Turbo-Pascal (und TASM) in "richtige" Programmierung eingestiegen.
Auf der Uni hat man dann versucht, mir Modula beizubringen, was ich
relativ schnell begriffen habe. Was ich absolut *nicht* begriffen habe,
war der Einstieg in objektorientierte Programmierung mittels C++, aber
das lag in diesem Fall kaum an der Sprache. Objektorientierung hat mir erst
Turbo-Vision beigebracht. Irgendwann gab es dann Source-Code von
"Wolfenstein 3-D" und "Descent" und das war der Punkt, an dem ich anfing,
mich ernsthaft mit C zu beschäftigen und gemerkt habe, dass die Compiler
daraus zwar relativ guten Code erzeugen konnten, aber die
Ausdrucksmöglichkeiten der Sprache im Vergleich mit dem, was ich kannte,
doch einigermassen beschränkt ist.
Danach folgte dann Ada, eine Runde Smalltalk, etwas VHDL, ein
wenig Prolog, mittlerweile beherrsche ich auch Java leidlich gut (abgesehen
davon, dass ich die 5000+ Klassen nicht auswendig kann) und nebenbei
debugge ich noch ein wenig C++, Perl und Python. Lisp habe ich
zugegebenermassen *nie* wirklich verstanden, aber ich bin ohnehin ein vi-
und kein emacs-Mensch. ;)
Also von der Syntax her gesehen, ein relativ bunter Mischmasch. Zugegeben,
dass ich gelegentlich "=", "==" und ":=" verwechsle, passiert dabei schon
mal, aber die ersten beiden sind ja auch sehr beliebte Fehler bei Leuten,
die *ausschliesslich* in C-ähnlicher Syntax programmieren, insofern halte
ich das keinesfalls für ein Argument.
Und natürlich haben mir meine Kenntnisse in Pascal das Erlernen von Ada
nicht gerade schwer gemacht, während die Ada-Kenntnisse wiederum für VHDL
recht hilfreich waren. Aber das läuft am Ende auch nur darauf hinaus, dass
man ein paar mal weniger in die Dokumentation schauen muss.
Aus meiner Sicht sollte ein Anfänger mit einer Sprache beginnen, die
halbwegs fehlerverzeihend ist (sprich: der Compiler sollte meckern, statt
Segfaults zu kodieren), streng typisiert ist, einigermassen intuitive
Regeln hat (IMO krank: Java akzeptiert a = b + c nicht ohne Typecast, wenn
a, b und c byte-Typen sind, da eine automatische Konvertierung nach int
stattfindet, die nicht mehr zum Ergebnistyp passt) und auch einfachere
Prinzipien des Software-Engineering (Sachen wie Information-Hiding z.B.)
nicht nur auf expliziten auszuprogrammierenden Umwegen unterstützt.
Viel bleibt dann nicht mehr übrig und es sind tatsächlich eher die
Pascal-Dialekte, die das liefern.
Wenn man das dann begriffen hat, kommt man auch mit C klar. Man weiss
halt, dass gewisse Dinge nicht so direkt gehen, während andere
einfacher sein mögen, aber da man die Prinzipien kennt, kann man sie
trotzdem anwenden. Dummes Beispiel dazu: Aufzählungstypen. In Pascal
eigenständige Typen mit entsprechender Typ und Bereichsprüfung, in C
weitgehend nichts anderes als benamte Integerkonstanten. Es erscheint aus
meiner Erfahrung heraus schwierig zu sein, jemandem die Vorzüge von
Aufzählungstypen (und wenn es nur in Hinsicht auf Lesbarkeit
und klar im Code definierte Constraints ist) zu zeigen, wenn er sie nur in
ihrer C-Inkarnation kannte ("So ein Blödsinn, da kann ich auch '#define'
schreiben.").
Um mich zu wiederholen: Ich halte Syntax für bestenfalls zweitrangig, wenn
man "Programmieren" erlernen möchte. Das, was "Programmieren" ausmacht,
ist universell. Ich halte C nun mal nicht für eine Sprache, die einem
diesen Weg besonders einfach macht, wenn man ihn beschreiten will. (Java
halte ich übrigens auch nur für marginal besser, die sogenannte strenge
Typisierung gilt ohnehin weitgehend nur für Klassen und ist eine
Gemeinsamkeit mit so ziemlich allen Sprachen, die sich objektorientiert
schimpfen, während sie für einfache Typen wahlweise nicht wirklich streng
ist oder - wie oben gezeigt - eher hirnt^H^H^Hnderlich.)
Vinzent.
> erfordern. Es gibt zum Beispiel ueberhaupt keinen Grund, jemanden von
> 'Pointerarithmetik' fernzuhalten, denn diese vereinfacht bestimmte
> Dinge (zB lexikalische Analyse/ Parsing oder auch nur
> Array-Traversals) erheblich. Ein Beispiel dafuer waere:
>
> static int const some_values[] = {
> 3,
> 2,
> 1,
> 45,
> -1
> };
>
> int const *pv;
>
> pv = some_values;
> while (*pv != -1) {
> do_something(*pv);
> ++pv;
> }
Das ist für einen Anfänger einfacher als beispielsweise:
|for i := Low (some_values) to High (some_values) do
| do_something (some_values[i]);
?
Mit dem zusätzlichen Effekt, dass man das Äquivalent von
"do_something (some_values)" vom Compiler gründlichst um die Ohren gehauen
kriegt, statt dem Effekt, dass aus dem Zeiger automatisch auf
"int" gecastet wird?
Abgesehen davon ist In-Band-Signalling einfach nur böse, auch wenn es in C
oft eine technische Notwendigkeit ist.
Vinzent.
Falsche Interpretationen werden auch durch Wiederholung nicht richtiger.
Ich sprach von der erfahrenen Lernfähigkeit von Leuten, nicht von
Unterschieden in C und Java.
> Wie ich ausserdem bereits geschrieben hatte:
>
> ,----
> | Daraus, dass jemand imstande sein sollte [...], zB die Blockstruktur |
> eines gegebenen Quelltextes ohne Muehe zu erkennen, folgt jetzt nicht, |
> dass er jeden anderen Inhalt auch verstehen muesste `----
>
> Dh ich widerspreche Deiner Kernaussage gar nicht, sie geht bloss an
> meiner vollkommen vorbei.
Kann es dann sein, dass Deine Aussage dafür am Thema vorbeigeht?
>> Natürlich bedeutet es etwas über diese Menschen. Ich habe ja auch keine
>> Aussagen über Programmiersprachen machen wollen. Es ging um die
>> Aussage, dass das Erlernen von C eine angeblich gute Voraussetzung zum
>> Erlernen (anderer) praxisrelevanter Sprachen sei.
>
> Es 'ging' wohl eher darum, dass jemand so mutig war, oeffentlich
> zuzugeben, C unterrichten zu wollen, was die ueblichen Verdaechtigen,
> die solches nicht leiden moegen, auf den Plan gerufen hat.
Nein. Es ging darum, C als Erstsprache erlernen zu wollen, woraufhin
u.a. das Argument auftauchte, dass das toll sei, weil ja dann eine
gleichartige Syntax zu praxisrelevanten Sprachen gegeben sei. Meine
Argumentation lautete hiermit nun im Speziellen, dass die Validität eines
solches Syntax-Argument mit Erfahrungen aus der Praxis nicht verfiziert
werden kann und im allgemeinen, dass ich C als Anfängersprache für
schlecht geeignet halte.
Vinzent.
Nee, da ging es ja um Anfänger. Hier ging es um Fortgeschrittene (oder
besser).
>> Das ist halt das Übliche: Wenn man Programmieren kann, ist die Sprache
>> nebensächlich.
>
> Es dauert jedenfalls eine Weile, die jeweiligen Libs kennenzulernen.
> Die Java-API ist ziemlich umfangreich. Die STL ist auch nicht über-
> sichtlich und selbst C hat eine Menge Zeugs eingebaut (ich vermute
> mal, daß kaum jemand weiß, daß es z.B. feraiseexcept() oder scalblnl()
> gibt).
>
Ist schon richtig. Aber was davon verwendet man? In C gibt es fast
schn eine eigene Bibliothek zur Stringmanipulation. Damit kann man
Sachen machen, die Pascal Operatoren einfacher und mit weniger
Fehlerquellen erledigen. Nur um ein Beispiel zu nennen.
Und das C ein Exception Handling hat, wusste ich bis heute nicht.
> Jirka
Tschö,
Markus
P.S.: Was tut scalblnl()? Ich habe die manpage nicht verstanden.
Ohne 'den Anfaenger', wer auch immer dass sein mag, telepathisch zu
ueberwachen, wird man das nicht ermitteln koennen. Der Code ist
allerdings einfacher, denn er iteriert nicht ueber einen
Zahlenbereich, um in Abhaengigkeit von einer Berechung mit der momentanen
Zahl und einem Startwert 'etwas anderes' zu tun.
C is unusual in that it allows pointers to point to anything.
[...]
Pointers have a bad reputation in academia, because they are
considered too dangerous, dirty somehow. But I think they are
powerful notation, which means they can help us express
ourselves clearly.
Consider: When you have a pointer to an object, it is a
name for exactly that object and no other. That sounds
trivial, but look at the following two expressions:
np
node[i]
The first points to a node, the second evaluates to (say) the
same node. But the second form is an expression; it is not so
simple. To interpret it, we must know what node is, what i
is, and that i and node are related by the (probably
unspecified) rules of the surrounding program. Nothing about
the expression in isolation can show that i is a valid index
of node, let alone the index of the element we want.
[http://www.lysator.liu.se/c/pikestyle.html]
> Mit dem zusätzlichen Effekt, dass man das Äquivalent von
> "do_something (some_values)" vom Compiler gründlichst um die Ohren gehauen
> kriegt, statt dem Effekt, dass aus dem Zeiger automatisch auf
> "int" gecastet wird?
Wenigstens fuer C99 sollte er das nicht werden (6.5.4|3 + 6.5.16.1|1).
Aber "Sinn oder Unsinn strikter Typ-Pruefungen" ist ein Thema, zu dem
keine einheitliche Sichtweise existiert: Wer sie gewohnt ist, haelt
sie fuer unverzichtbar oder doch wenigstens nuetzlich, wer eher
Sprachen mit dynamischer Typisierung oder vollkommen ohne welche
benutzt, fuer Quatsch, mit dem man sich nicht befassen sollte, "weil
er mit dem Problem nichts zu tun hat". Pragmatisch gesehen muss man
mit und ohne arbeiten koennen, und falls bei diesem wechselseitigen
Koepfeeinschlagen mal etwas definitives herauskommen sollte, wird sich
das wohl herumsprechen.
> Abgesehen davon ist In-Band-Signalling einfach nur böse, auch wenn
> es in C oft eine technische Notwendigkeit ist.
'Boese' ist eine moralische Kategorie. Was genau 'in-band signalling'
in einem Computerprogramm eigentlich sein soll, waere zu
definieren. Haette man das getan, koennte man als nachteilig
angesehene Nebeneffekte 'festnageln' und fuer konkrete Beispiele
nachweisen, dass diese Effekte sowohl auftreten als auch nachteilig
sind. Aber diese muessten eigentlich auch nachteilig sein, ohne zu
ihrer Beschreibung Begriffe aus der Nachrichtentechnik zu entlehnen.
Ein Beispiel einer 'naiven' Definition waere zB die Benutzung
derselben TCP-Verbindung fuer Kommandos und Datenuebertragung und die
Schlussfolgerung waere dann, dass 'HTTP' 'boese' sei, 'ftp' hingegen
'gut'. Was meiner Meinung nach (von den unpassenden Adjektiven mal
abgesehen) keine irgendwie nuetzlich Sichtweise darstellen wuerde.
> P.S.: Was tut scalblnl()? Ich habe die manpage nicht verstanden.
scalb*(x, y) == x * 2 ^ y // wenn FLT_RADIX = 2
Und angeblich tut es das sehr effizient.
Jirka
Nein, er iteriert nicht über einen Zahlenbereich, der noch relativ
leicht als der Bereich zu entziffern wäre, der die gültigen Indizes
eines Feldes enthält, sondern über einen Speicherbereich, der bei der
Startadresse eines Feldes anfängt und irgendwo da aufhört, wo mal eine
-1 auftaucht. Sicher ist das einfacher für einen Anfänger... (vor
Ironie wird gewarnt)
> C is unusual in that it allows pointers to point to anything.
>
> [...]
>
> Pointers have a bad reputation in academia, because they are
> considered too dangerous, dirty somehow. But I think they are
> powerful notation, which means they can help us express
> ourselves clearly.
>
Klar, zwei Worte für den gleichen Begriff zu haben, ist für klare
Ausdrucksweise unabdingbar. (s.o.)
[...]
> Nothing about
> the expression in isolation can show that i is a valid index
> of node, let alone the index of the element we want.
>
> [http://www.lysator.liu.se/c/pikestyle.html]
>
Aha. 'node[i]' ist also schlechter als 'np', weil wir bei 'node[i]'
nicht auf den ersten Blick sehen, ob das überhaupt die Zahl ist, die
wir haben wollen. Eine Frage an die Runde: Seht ihr bei 'np' alleine,
dass es genau die Zahl ist, die wir haben wollen? Damit 'np' überhaupt
auf irgendwas sinnvolles zeigt, ist auch wieder Programmkontext
vonnöten. Und auch dann sehen wir eventuell nur, dass 'np' mal auf
etwas sinnvolles gezeigt hat, aber was jetzt das Pointerziel ist, ist
dem Ausdruck alleine nicht anzusehen. Was wollte uns der Autor also
sagen?
[...]
Da es erst mal nix anderes tut, als den Exponentenanteil einer
Gleitkommazahl nach links zu schieben, würde ich da eine gewisse Effizienz
erwarten. (Sollte wohl ursprünglich mal "scale_bias" heissen?)
Vinzent.
> Vinzent Hoefler <nntp-2...@t-domaingrabbing.de> writes:
>> On Fri, 29 Aug 2008 11:27:51 +0200, Rainer Weikusat wrote:
>>> erfordern. Es gibt zum Beispiel ueberhaupt keinen Grund, jemanden von
>>> 'Pointerarithmetik' fernzuhalten, denn diese vereinfacht bestimmte
>>> Dinge (zB lexikalische Analyse/ Parsing oder auch nur
>>> Array-Traversals) erheblich. Ein Beispiel dafuer waere:
>>>
>>> static int const some_values[] = {
>>> 3,
>>> 2,
>>> 1,
>>> 45,
>>> -1
>>> };
>>>
>>> int const *pv;
>>>
>>> pv = some_values;
>>> while (*pv != -1) {
>>> do_something(*pv);
>>> ++pv;
>>> }
>>
>> Das ist für einen Anfänger einfacher als beispielsweise:
>>
>> |for i := Low (some_values) to High (some_values) do
>> | do_something (some_values[i]);
>>
>> ?
>
> Ohne 'den Anfaenger', wer auch immer dass sein mag, telepathisch zu
> ueberwachen, wird man das nicht ermitteln koennen.
Nunja. Ich spreche zumindest von den Erfahrungen, die ich gemacht habe.
> Der Code ist
> allerdings einfacher, denn er iteriert nicht ueber einen
> Zahlenbereich, um in Abhaengigkeit von einer Berechung mit der momentanen
> Zahl und einem Startwert 'etwas anderes' zu tun.
Du sprichst für mich in Rätseln. Ich glaube, ich muss mich erst einmal
wieder an Deinen Stil gewöhnen. Wenn Du also bitte die Liebenswürdigkeit
besässest, mir die Zielführung Deines Satzes noch einmal genauer
darzulegen?
> C is unusual in that it allows pointers to point to anything.
Was'n das für'n Blödsinn?
Auch in anderen Sprachen, die das Konzept "Pointer" haben, dürfen die
im allgemeinen auf alles zeigen. Wenn auch nicht immer auf jedes von
diesem "anything" (Stichwort: Ada'Unchecked_Access). Notfalls muss man
halt - genauso wie in C - mit Type-Casts nachhelfen.
> Pointers have a bad reputation in academia, because they are
> considered too dangerous, dirty somehow. But I think they are
> powerful notation, which means they can help us express
> ourselves clearly.
Natürlich sind Zeiger machtvoll. Aber sie können eben - wie jede Macht -
auch leicht missbraucht werden (besonders auch in C). Inwiefern man sich
dann damit "klar" ausdrücken kann, ist im Zweifelsfall kontextabhängig.
Besonders im Raum steht dann die Frage, ob man einem Programmier-Anfänger
genau diese Macht schon in die Hand geben möchte. Es ist aber nun mal in
C so, dass man ohne Zeiger praktisch keine sinnvollen Programme schreiben
kann.
Nehmen wir mal, so als Beispiel
|char *strcat(char *dest, const char *src);
Was sagt uns das? Eine Funktion, die zwei Zeiger erwartet. Die Daten
des zweiten Teils werden offenbar nicht geändert (also ist die
Wahrscheinlichkeit, dass er auch NULL sein darf, eher gering, ganz
auszuschliessen ist es allerdings nicht).
Aber was wissen wir über den ersten Parameter, ausser dass es ein Zeiger
auf einen "char" ist?
Ignorieren wir mal den Rückgabewert und kreieren einen annähernd
äquivalenten Prototypen in einem halbwegs modernen Pascal-Dialekt:
|procedure strcat (var Dest : String; const Source : String)
Diese Version kommt nun erst einmal völlig ohne (offensichtliche) Zeiger
aus und enthält zusätzlich noch weitere Informationen:
(1) "Dest sollte ein String sein." (Laut C-Prototyp könnte auch ein
einzelnes Zeichen gemeint sein, dass es in Wirklichkeit ein
nullterminierter C-String sein sollte, ist nicht erkennbar.)
(2) "Keines der beiden Argumente kann NIL/NULL sein."
(3) Das erste Argument sollte einen bereits initialisierten Wert
beinhalten (sonst hätte man als Parametermodus besser "out" angegeben.)
Mit diesen Informationen kann man schon einiges mehr anfangen und eine
Fehlbenutzung ist aus sprachlicher Sicht faktisch ausgeschlossen.
[Abgesehen davon erscheint mir "Dest := Dest + 'foo';" in diesem
Zusammenhang durchaus einfacher verständlich als 'strcat(s, "foo")', aber
dass das Stringhandling in C nicht gerade zu den einfachsten Dingen
gehört, dürfte allgemein akzeptiert sein, also ignorieren wir das einfach.]
Insofern: Ja, Zeiger sind (besonders in C) wichtig, aber sie werden
allgemein überschätzt.
Und gerade Anfänger sind von der Zeigerlastigkeit von C oft überfordert.
Apropos, da fällt mir gerade ein tolles Beispiel aus "Produktivcode" ein
(auf das relevante gekürzt):
|int *pnYear = 0;
|int *pnMonth = 0;
|int *pnDay = 0;
|
|[...]
|GetFileDate (szFileName, pnYear, pnMonth, pnDay);
|
|timestamp = *pnYear * 10000 + *pnMonth * 100 + *pnDay;
Dass das ganze auf:
"(int *) NULL * 10000 + (int *) NULL * 100 + (int *) NULL;"
verkürzbar ist, ist einige Jahre lang niemandem aufgefallen: "Compiliert
doch?" Wenn man bedenkt, dass die Software, aus dem dieses Stück Code
stammt, gute 200'000 qualitativ vergleichbare SLOC umfasst, tendenziell
sicherheitsrelevant ist (mit 200 Watt Laserleistung kann man wirklich gut
Löcher brennen) und den Fakt dazu rechnet, dass das u.a. von sich selbst so
bezeichnenden langjährigen "C-Programmierern" stammt, die eigentlich
einigermassen wissen sollten, was sie tun, muss man sich doch fragen, ob
das eine für Anfänger gut geeignete Sprache ist. Anfänger wissen nämlich
eher selten, was sie da tun. Ja, ich spreche da auch aus Erfahrung.
> Consider: When you have a pointer to an object, it is a name for
> exactly that object and no other. That sounds trivial, but look at the
> following two expressions:
>
> np
> node[i]
>
> The first points to a node, the second evaluates to (say) the same
> node.
Komisch ist nur, dass man in C den Unterschied zwischen dem Objekt "test"
und 't' mittels char* überhaupt nicht ausdrücken kann. Ein und derselbe
Zeiger kann also durchaus auf unterschiedliche Inkarnationen ähnlicher
Objekte zeigen. Ich bin also geneigt, die Aussage "ein Zeiger ist ein Name
für /genau ein/ Objekt" für schlicht unzutreffend zu halten.
> But the second form is an expression; it is not so simple. To
> interpret it, we must know what node is, what i is, and that i and node
> are related by the (probably unspecified) rules of the surrounding
> program.
Um "np" korrekt anzuwenden, braucht man auch ohne "i" etwa genau so viel
Informationen. Es stellt sich zusätzlich die Frage, ob ein etwaiger
Ausdruck "np++" überhaupt gültig sein kann, was sich bei node[i]
in den meisten anderen Sprachen wesentlich leichter beantworten lässt, es
führt im Falle der Ungültigkeit nämlich zu einem nicht übersetzbaren
Programm. Jetzt kann man einwenden (tut der Autor ja unten auch), dass ja
nicht bekannt ist, ob der Wert des Index "i" nun zur Laufzeit tatsächlich
einen gültigen Index beschreibt. Allerdings ist das für "np" in den
meisten Fällen auch nur ähnlich nicht-trivial beantwortbar.
Anderes Beispiel, die Deutung des Prototypen
"char *strcat (char *dest, const char* source)"
Wir erkennen zwei Zeiger auf char, der zweite Parameter wird (dank const
Modifizierer) offenbar nicht geändert. Daraus ergibt sich mit relativ
hoher Wahrscheinlichkeit, dass er nicht NULL sein sollte. Was kann man
über den ersten Parameter sagen? Er sollte wahrscheinlich auf mindestens
ein "char" zeigen und es ist wahrscheinlich, dass der Inhalt dieses "char"
von der Funktion geändert wird (sonst sollte da auch ein const stehen).
Daraus ergibt sich, dass es möglicherweise ebenfalls eine schlechte Idee
wäre, hier NULL zu übergeben. Den Rückgabewert ignorieren wir mal zum
Zwecke der Vereinfachung.
Jetzt übersetzen wir diesen Prototypen mal in einen halbwegs modernen
Pascal-Dialekt:
procedure strcat (var Dest : String; const Source : String);
Als erstes ist zu bemerken, dass wir plötzlich gar keine Notwendigkeit für
Zeiger mehr haben. Daraus ergibt sich, dass man hier schlicht nicht NULL
übergeben kann. Fehlerquelle eins eliminiert.
Zweitens erkennt man, dass sowohl Dest als auch Source eben nicht einfach
nur "char"s sind, sondern tatsächlich String. Dass der C-Prototyp
nullterminierte "Strings" erwartet, ist dort nicht erkennbar. Eine zweite
mögliche Fehlerquelle erledigt.
Ich halte das tatsächlich für einfacher verständlich. Die Absicht des
Programmiers geht zumindest deutlicher hervor. Natürlich wird das im
Zweifelsfall den Blick in die Dokumentation nicht ersparen, aber man
kann gesicherte Aussagen treffen statt nur mit "hoher Wahrscheinlichkeit"
zu raten.
[Abgesehen davon könnte man natürlich auch einfach "Dest := Dest +
Source;" schreiben, was die Sache noch einfacher macht. Aber gut,
die Stringverarbeitung in C ist nicht gerade toll gelöst, ich lasse das
als Argument mal weg.]
Um diesen ewig langen Absatz mal zu Ende zu bringen: Zeiger sind in C eine
sprachbedingte Notwendigkeit, aber ihr tatsächlicher Nutzen wird
im allgemeinen deutlich überschätzt. Um das Argument von weiter unten
vorwegzunehmen: Die Tatsache, dass es (in einer bestimmten Sprache) nicht
anders geht, heisst nicht, dass es die einzige - oder gar beste -
Lösung ist.
> Nothing about the expression in isolation can show that i is
> a valid index of node, let alone the index of the element we want.
Nichts an dem Zeiger "np" allein deutet darauf hin, dass er auf ein
gültiges Objekt zeigt und selbst wenn, wissen wir nicht, ob es das Objekt
ist, was wir wollen.
Was muss man rauchen, um so eine Argumentation aufbauen zu können? Ich
will auch was von dem Zeug, scheint witzig zu sein.
>> Mit dem zusätzlichen Effekt, dass man das Äquivalent von "do_something
>> (some_values)" vom Compiler gründlichst um die Ohren gehauen kriegt,
>> statt dem Effekt, dass aus dem Zeiger automatisch auf "int" gecastet
>> wird?
>
> Wenigstens fuer C99 sollte er das nicht werden (6.5.4|3 + 6.5.16.1|1).
Mag sein. Und es geht zumindest bei meinem gcc auch so nicht warnungsfrei
ab.
> Aber "Sinn oder Unsinn strikter Typ-Pruefungen" ist ein Thema, zu dem
> keine einheitliche Sichtweise existiert: Wer sie gewohnt ist, haelt sie
> fuer unverzichtbar oder doch wenigstens nuetzlich,
Der Vorteil ist, dass ich sie in den Fällen, wo sie mir hinderlich ist,
explizit "wegcasten" kann. Der Nachteil bei weniger strikter Prüfung liegt
darin, dass eine Menge möglicher Fehler eben nicht schon vom
Compiler erkannt wird.
Davon abgesehen, sind vom Programmierer eingefügte Type-Casts in C
tendenziell häufiger zu finden als in typstrengeren Sprachen. Klingt zwar
widersprüchlich, ist aber so. Wirklich erklären kann ich's auch nicht.
> wer eher Sprachen mit
> dynamischer Typisierung oder vollkommen ohne welche benutzt, fuer
> Quatsch, mit dem man sich nicht befassen sollte, "weil er mit dem
> Problem nichts zu tun hat".
Dynamische Typisierung hat mit strikter oder weniger strikter
Typprüfung erst mal nix zu tun. Der Unterschied liegt nur darin, wann die
Typfehler auftreten (sehr beliebter Laufzeitfehler: "foo() expects two
parameters, only one given").
> Pragmatisch gesehen muss man mit und ohne
> arbeiten koennen, und falls bei diesem wechselseitigen Koepfeeinschlagen
> mal etwas definitives herauskommen sollte, wird sich das wohl
> herumsprechen.
Offenbar nicht. Zumal der Streit, was nun schwache oder strenge
Typisierung ist, noch nicht wirklich entschieden ist. ;)
>> Abgesehen davon ist In-Band-Signalling einfach nur böse, auch wenn es
>> in C oft eine technische Notwendigkeit ist.
>
> 'Boese' ist eine moralische Kategorie.
Korrekt. Ich kann technische Notwendigkeit nun mal nicht mit technischen
Argumenten kritisieren. Dass etwas nicht anders geht, bedeutet allerdings
auch nicht, dass es eine gute (Vorsicht: moralische Kategorie!) Lösung ist.
> Was genau 'in-band signalling' in
> einem Computerprogramm eigentlich sein soll, waere zu definieren.
Triviales Beispiel für C: Das abschliessende '\0' eines C-"Strings".
> Haette man das getan, koennte man als nachteilig angesehene Nebeneffekte
> 'festnageln' und fuer konkrete Beispiele nachweisen, dass diese Effekte
> sowohl auftreten als auch nachteilig sind.
Buffer-Overflows und die klassischen "Off-By-One"-Fehler, sind sowohl ein
bekanntes als auch ein üblicherweise als nachteilig angesehenes Problem.
> Aber diese muessten
> eigentlich auch nachteilig sein, ohne zu ihrer Beschreibung Begriffe aus
> der Nachrichtentechnik zu entlehnen.
Wenn Dir ein besserer Begriff dafür einfällt...
> Ein Beispiel einer 'naiven' Definition waere zB die Benutzung derselben
> TCP-Verbindung fuer Kommandos und Datenuebertragung und die
> Schlussfolgerung waere dann, dass 'HTTP' 'boese' sei,
Inwiefern würde In-Band-Signalling auf HTTP zutreffen? Die Richtung der
Datenübertragung ist festgelegt und damit auch "Kommando-" und "Datenkanal".
Vinzent.
Dass das ganze auf:
> Nothing about the expression in isolation can show that i is
Vinzent.
Supersede: Man sollte nachts um 4 keine Postings mehr schreiben, vor
allem, wenn man vergisst, dass man das, was man gerade schreibt, schon mal
geschrieben hat. :D
Das weißt du, weil du den x86-Befehlssatz und das IEEE-Floating-Point-
Format kennst. Wer das nicht kennt, dürfte gewisse Mühen haben, diese
Funktion in C aufzuschreiben.
Stefan
Vinzent Hoefler <nntp-2...@t-domaingrabbing.de> wrote:
> On Fri, 29 Aug 2008 11:27:51 +0200, Rainer Weikusat wrote:
>> erfordern. Es gibt zum Beispiel ueberhaupt keinen Grund, jemanden von
>> 'Pointerarithmetik' fernzuhalten, denn diese vereinfacht bestimmte
>> Dinge (zB lexikalische Analyse/ Parsing oder auch nur
>> Array-Traversals) erheblich. Ein Beispiel dafuer waere:
>>
>> static int const some_values[] = {
>> 3,
>> 2,
>> 1,
>> 45,
>> -1
>> };
>>
>> int const *pv;
>>
>> pv = some_values;
>> while (*pv != -1) {
>> do_something(*pv);
>> ++pv;
>> }
>
> Das ist für einen Anfänger einfacher als beispielsweise:
>
> |for i := Low (some_values) to High (some_values) do
> | do_something (some_values[i]);
>
> ?
Du beachtest dabei den "array-Ende-Marker" in Form der "-1" nicht ...
Aber waere nicht dies gerade ein Beispiel dafuer, dass es manchmal ein
wenig "weniger maschinennah" einfacher waere, sich auf die eigentliche
Aufgabe statt auf die Implementierung zu konzentrieren? Wenn man eine
Sprache verwendet, bei der man z.B. den "arrays-Ende-Marker" nicht be-
noetigt, weil man fuer so etwas eben kein array sondern einen (nativen)
Datentyp "liste" der Sprache verwendet, wobei das "Ende der Liste"
einfach automatisch in der Sprache erkannt wird? Und wenn es dann
einfache Sprachkonstrukte gibt, die dirkt ueber die Listenelemente
iterieren, statt "mit pointern ueber speicherbereiche" oder mit
Indices ueber ein array?
> (defun square (x) (* x x))
SQUARE
> (setq list '(1 2 3 4 5))
(1 2 3 4 5)
> (mapcar 'square list)
(1 4 9 16 25)
>
(wobei hier der Einfachheit helber eben die hier definiterte Funktion
"square" statt dem oben stehenden "do_something" verwendet wird, um die
Eleganz der Loesung anhand von konkretem Code zu demonstrieren). Dieser
Codeschnipsel ist uebrigens Common Lisp.
Wobei ich zugeben muss, dass man da vielleicht mit einer etwas anderen
Denkweise an manche Probleme herangehen muss, als bei den "typischen
prozeduralen Sprachen" ...
Oder wenn man nicht mit Listen sondern mit arrays hantieren will (hier
mal ein Beispiel in OCAML statt in Lisp):
# let feld=[| 1; 2; 3; 4; 5; |];;
val feld : int array = [|1; 2; 3; 4; 5|]
# let square x = function x -> x * x;;
val square : 'a -> int -> int = <fun>
# Array.mapi square feld;;
- : int array = [|1; 4; 9; 16; 25|]
#
Und das ganze auch noch mit genauer Typenpruefung und interaktiv zu testen
um solche Kleinigkeiten evt. separat testen zu koennen. Wenn man sich diesen
separat ausfuehrbaren Code-Schnipsel (nein, da kommt nichts dazu, auch keine
Deklarationen, icludes, ...) und das mal mit einem kompletten C-Programm.
dass diese Funktionalitaet implementiert (einschliesslich aller includes,
Deklarationen, ... was so alles notwendig ist, um ein ausfuehrbares Pro-
gramm zu erhalten), dann komme ich zu dem Schluss, dass gerade fuer so
etwas wie "vorlesungsbegleitende Uebungen zu Mathematik-Vorlesungen"
evt. solche "nicht so maschinennahen Sprachen" evt. doch eher geignet
sind, weil sie den Programmierer weniger mit Dingen belasten, die mit
dem zu loesenden Problem oder dem zu implementierenden Algorithmus eher
weniger zu tun haben ...
Wenn wir diese Diskussion weiterzufuehren gednken, sollten wir aber besser
in eine andere Gruppe umziehen (welche? Vprschlaege? Gibt eine "advocacy"
Gruppe fuer Programmiersprachen?).
Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...
Assemblerkenntnisse sind hier unnötig, aber IEEE754 sollte man schon mal
angeschaut haben, ja. Dann würde man auch darauf kommen, dass man den
Exponenten nicht schieben muss, sondern addieren, schliesslich
exponenziert der ja schon. ;)
Mal ein kleiner Versuch:
-- 8< --
#include <stdio.h>
#include <stdint.h>
float scalbfn (float f, int y)
{
int32_t x = *((int32_t*) &f);
x = x + (y << 23);
return *((float*) &x);
}
int main (void)
{
printf ("%f\n", scalbfn (1.2, 2));
return 0;
}
-- 8< --
Das eklige sind vor allem die Casts, dazu kommt die Sache mit dem
Sign-Bit, die man korrekterweise auch beachten sollte (wobei Überlauf
erstmal Überlauf bleibt, ob sich das Vorzeichen dabei nun ändert, ist dann
eigentlich auch wurscht).
Zugegeben, ich musste so was ähnliches vor Jahren schon mal machen
(Konvertierung zwischen IEEE754 und Motorola 56K Gleitkommazahlen),
insofern bin ich bei dieser Art von Bitschiebereien wahrscheinlich etwas
vorbelastet.
Auf jeden Fall sieht man anhand des Beispiels, dass die Operation
doch einigermassen effizient implementierbar sein sollte.
Vinzent.
Klaro. Nur - nicht alles ist IEEE, und nicht alles, was einen C-Compiler
hat, verwendet IEEE. Heutzutage zugegebenermaßen "fast immer", aber ich
habe da noch ein paar alte Systeme, die verwenden sowas wie
BCD-Darstellung für Fließkommazahlen; da ist dann nichts mit "effiziente
Implementierung". (-:
> Auf jeden Fall sieht man anhand des Beispiels, dass die Operation
> doch einigermassen effizient implementierbar sein sollte.
Für IEEE - ja sicher.
Grüße,
Thomas
> Vinzent Hoefler wrote:
>> On Sat, 30 Aug 2008 12:34:35 +0200, Stefan Reuther wrote:
>>
>>> Vinzent Hoefler wrote:
>>>> On Fri, 29 Aug 2008 14:46:40 +0200, Jirka Klaue wrote:
>>>>> Markus Wichmann:
>>>>>> P.S.: Was tut scalblnl()? Ich habe die manpage nicht verstanden.
>>>>> scalb*(x, y) == x * 2 ^ y // wenn FLT_RADIX = 2
>>>>>
>>>>> Und angeblich tut es das sehr effizient.
>>>> Da es erst mal nix anderes tut, als den Exponentenanteil einer
>>>> Gleitkommazahl nach links zu schieben, würde ich da eine gewisse Effizienz
>>>> erwarten.
>>> Das weißt du, weil du den x86-Befehlssatz und das IEEE-Floating-Point-
>>> Format kennst. Wer das nicht kennt, dürfte gewisse Mühen haben, diese
>>> Funktion in C aufzuschreiben.
>>
>> Assemblerkenntnisse sind hier unnötig, aber IEEE754 sollte man schon mal
>> angeschaut haben, ja. Dann würde man auch darauf kommen, dass man den
>> Exponenten nicht schieben muss, sondern addieren, schliesslich
>> exponenziert der ja schon. ;)
>
> Klaro. Nur - nicht alles ist IEEE, und nicht alles, was einen C-Compiler
> hat, verwendet IEEE.
Durchaus richtig. Allerdings ist das Grundprinzip des Aufbaus von
Gleitkommazahlen trotzdem recht ähnlich. Als Beispiel das Format der Cray:
http://www.cisl.ucar.edu/zine/96/fall/articles/4.ieee.formats.html
(Wobei ich mir einbilde, mal gelesen zu haben, dass sie auch dort später
auf IEEE754 gewechselt haben.)
> Heutzutage zugegebenermaßen "fast immer", aber ich habe da
> noch ein paar alte Systeme, die verwenden sowas wie BCD-Darstellung für
> Fließkommazahlen; da ist dann nichts mit "effiziente Implementierung". (-:
Doch, da FLT_RADIX dann nicht mehr 2, sondern 10 sein dürfte.
Grundsätzlich wird entweder der Exponent dann per Addition angepasst oder
(wie im Falle des erwähnten DSP-56K, der keinen Exponenten hat), halt die
Mantisse geschoben.
>> Auf jeden Fall sieht man anhand des Beispiels, dass die Operation
>> doch einigermassen effizient implementierbar sein sollte.
>
> Für IEEE - ja sicher.
Auch für andere Formate (natürlich nicht in exakt der gezeigten
Implementation). Es dürfte einen Grund geben, warum man sich da auf
FLT_RADIX bezieht.
Vinzent.
> Hallo,
>
> Vinzent Hoefler <nntp-2...@t-domaingrabbing.de> wrote:
>> On Fri, 29 Aug 2008 11:27:51 +0200, Rainer Weikusat wrote:
>>> erfordern. Es gibt zum Beispiel ueberhaupt keinen Grund, jemanden von
>>> 'Pointerarithmetik' fernzuhalten, denn diese vereinfacht bestimmte
>>> Dinge (zB lexikalische Analyse/ Parsing oder auch nur
>>> Array-Traversals) erheblich. Ein Beispiel dafuer waere:
>>>
>>> static int const some_values[] = {
>>> 3,
>>> 2,
>>> 1,
>>> 45,
>>> -1
>>> };
>>>
>>> int const *pv;
>>>
>>> pv = some_values;
>>> while (*pv != -1) {
>>> do_something(*pv);
>>> ++pv;
>>> }
>>
>> Das ist für einen Anfänger einfacher als beispielsweise:
>>
>> |for i := Low (some_values) to High (some_values) do
>> | do_something (some_values[i]);
>>
>> ?
>
> Du beachtest dabei den "array-Ende-Marker" in Form der "-1" nicht ...
Das war allerdings Absicht. Daher ja auch mein Hinweis auf das
Inband-Signalling.
> Aber waere nicht dies gerade ein Beispiel dafuer, dass es manchmal ein
> wenig "weniger maschinennah" einfacher waere, sich auf die eigentliche
> Aufgabe statt auf die Implementierung zu konzentrieren?
Möglich. Ich weiss nicht, ob beispielsweise Rainer als Beispiel für ein
rein virtuelles Konzeot "Anfänger" (sorry, no offense) akzeptieren würde.
Ich bin jedenfalls in der Praxis nach wie vor froh darüber, wenn ich mich
nicht auf solchen Kleinkram konzentrieren muss.
> Wenn man eine
> Sprache verwendet, bei der man z.B. den "arrays-Ende-Marker" nicht be-
> noetigt, weil man fuer so etwas eben kein array sondern einen (nativen)
> Datentyp "liste" der Sprache verwendet, wobei das "Ende der Liste"
> einfach automatisch in der Sprache erkannt wird? Und wenn es dann
> einfache Sprachkonstrukte gibt, die dirkt ueber die Listenelemente
> iterieren, statt "mit pointern ueber speicherbereiche" oder mit Indices
> ueber ein array?
Ja. Dafür hat man in anderen Sprachen ja Iteratoren und ähnliche
Konstrukte erfunden.
>> (defun square (x) (* x x))
> SQUARE
>> (setq list '(1 2 3 4 5))
> (1 2 3 4 5)
>> (mapcar 'square list)
> (1 4 9 16 25)
>>
>>
> (wobei hier der Einfachheit helber eben die hier definiterte Funktion
> "square" statt dem oben stehenden "do_something" verwendet wird, um die
> Eleganz der Loesung anhand von konkretem Code zu demonstrieren).
Ja. Ich finde die Syntax zwar gewöhnungsbedürftig, aber wenn ich lange
genug draufschaue, versteh ich's sogar. ;)
Das Prinzip ist aber meines Erachtens für einen Anfänger durchaus
einfacher durchschaubar; wenn ich als weiteres Beispiel mal ein
kurzes Python-Schnipsel bringe
|for Keys in Dict.keys()
halte ich das auch für handhabbarer. (Wenn ich mich recht entsinne, geht
das in Smalltalk ähnlich.)
> Dieser
> Codeschnipsel ist uebrigens Common Lisp. Wobei ich zugeben muss, dass
> man da vielleicht mit einer etwas anderen Denkweise an manche Probleme
> herangehen muss, als bei den "typischen prozeduralen Sprachen" ...
Einen unbedarften Anfänger sollte das nicht stören, solange er nicht mit
dem einen oder anderen Konzept schon versaut^Win Berührung gekommen ist.
Ich persönlich habe allerdings, wie woanders schon mal erwähnt, nie
wirklich einen Draht zu Lisp gefunden. Aber als ich mich an funktionalen
Sprachen versucht habe, war ich durch das prozedurale Paradigma ja auch
schon versaut.
> Oder wenn man nicht mit Listen sondern mit arrays hantieren will (hier
> mal ein Beispiel in OCAML statt in Lisp):
>
> # let feld=[| 1; 2; 3; 4; 5; |];;
> val feld : int array = [|1; 2; 3; 4; 5|]
> # let square x = function x -> x * x;;
> val square : 'a -> int -> int = <fun>
> # Array.mapi square feld;;
> - : int array = [|1; 4; 9; 16; 25|]
> #
>
> Und das ganze auch noch mit genauer Typenpruefung und interaktiv zu
> testen um solche Kleinigkeiten evt. separat testen zu koennen. Wenn man
> sich diesen separat ausfuehrbaren Code-Schnipsel (nein, da kommt nichts
> dazu, auch keine Deklarationen, icludes, ...) und das mal mit einem
> kompletten C-Programm. dass diese Funktionalitaet implementiert
> (einschliesslich aller includes, Deklarationen, ... was so alles
> notwendig ist, um ein ausfuehrbares Pro- gramm zu erhalten), dann komme
> ich zu dem Schluss, dass gerade fuer so etwas wie "vorlesungsbegleitende
> Uebungen zu Mathematik-Vorlesungen" evt. solche "nicht so maschinennahen
> Sprachen" evt. doch eher geignet sind, weil sie den Programmierer
> weniger mit Dingen belasten, die mit dem zu loesenden Problem oder dem
> zu implementierenden Algorithmus eher weniger zu tun haben ...
Ja, durchaus Deiner Meinung. Ich bin zwar ehrlich gesagt, von der hier
gesehenen Syntax nicht so begeistert, aber für angehende Mathematiker
sollte das kein Problem darstellen, die hantieren schliesslich den ganzen
Tag mit den komischsten Symbolen. ;)
> Wenn wir diese Diskussion weiterzufuehren gednken, sollten wir aber
> besser in eine andere Gruppe umziehen (welche? Vprschlaege? Gibt eine
> "advocacy" Gruppe fuer Programmiersprachen?).
Die übliche Verdächte dclm, würde ich sagen. Ich mach mal X'post setze
das F'Up nach de.comp.lang.misc. Hoffe ich zumindest... ;)
Vinzent.
[...]
"Waere es nicht einfacher, wenn man dass alles viel komplizierter
machen wuerde?". So klingt das wenigstens fuer mich. Ich kann auch
nichts besonders 'maschinennahes' an dem C-Beispiel finden. Schon
soetwas wie 'vorzeichenbehaftet Ganzzahl' gibt es auf der Ebene
dessen, was man 'Maschinenprogrammierung' nennt, einfach nicht: Die
CPU hat 'irgendwelche Instruktionen', die bestimmte Algorithmen mit
Binaerzahlen, die eine gewisse Anzahl von Wert-Bytes haben
durchfuehren oder sogar nur einen solchen Datentyp und gegebenfalls
Lade- und Speicheroperationen, die unterschiedlich viele Wert-Bytes
aus dem Speicher lesen oder in diesen schreiben (ARM9: byte, halfword,
und word mit 1, 2 und 4 bytes). Je nachdem, welche dieser
Instruktionen benutzt werden, kann man das Ergebnis als negativen Wert
in einer bestimmten Darstellung intepretieren. Als Seiteneffekt
setzten manche dieser Instruktionen flag-bits, zB 'Ergebnis ist Null',
'Ergebnis hat ein gesetztes Vorteichenbit', 'Ueberlauf', 'Unterlauf',
in Ahaengigkeit vom Zustand eines oder mehrerer dieser bits koennen
Verzweigungen ausgefuehrt werden, die es moeglicherweise in Form
mehrere Instruktionen oder Instruktionskombinationen mit
unterschiedlichen Groessen und Reichweiten gibt. Speicherzugriffe
unterliegen gewissen Einschraekungen hinsichtlich der Adressen, mit
denen sie durchgefuehrt werden koennen (word-load nur von ohne Rest
durch vier teilbaren Adressen) und werden die nicht beachtet, loest
das Speichersystem uU eine Prozessor-Ausnahme aus (oder die
Ausfuerungszeit des Codes wird 'bloss' sehr viel laenger). Anstatt
unteroutinenlokaler Variablen gibt es eine typischerweise kleine Zahl
von CPU-Registern mit lustigen Namen wie R0 - R15, zu deren
konfliktfreier Benutzung eine bestimmte Konvention explizit kodiert
werden muss. Und diesen ganzen Kram, den ich ja noch sehr
unvollstaendig beschrieben habe, kann man in C vollkommen ignorieren:
Man definiert ein Feld von Ganzzahlen, dh einen Vektor, etwas
vollkommen 'unmaschinelles', der mit Zahlenwerten initialisiert wird
und nicht mit Bitmustern und benutzt dessen Elmente der Reihe nach
fuer irgendeine Opertation, deren Implementierung leicht dutzende oder
hunderte von Maschineninstruktionen erfordern kann.
>> (defun square (x) (* x x))
> SQUARE
>> (setq list '(1 2 3 4 5))
> (1 2 3 4 5)
>> (mapcar 'square list)
> (1 4 9 16 25)
>>
>
> (wobei hier der Einfachheit helber eben die hier definiterte Funktion
> "square" statt dem oben stehenden "do_something" verwendet wird, um die
> Eleganz der Loesung anhand von konkretem Code zu demonstrieren). Dieser
> Codeschnipsel ist uebrigens Common Lisp.
... und falls man in Lisp etwas anderes tut, als 'elegante
Demonstrationen elementarer Operationen' durchzufuehren, deklariert
man auch Typen, die zu etwas effizient von der CPU verarbeitbaren ohne
bestimmte, bekannte Eigenschaften uebersetzt werden koennen und kuemmert
sich darum, wann und wo man wieviel neues conses erzeugt bzw wie man
das gegebenfalls vermeiden kann.
> Wobei ich zugeben muss, dass man da vielleicht mit einer etwas anderen
> Denkweise an manche Probleme herangehen muss, als bei den "typischen
> prozeduralen Sprachen" ...
Das ist ein aus unerklaerlichen Gruenden weit verbreiteter
Irrglaube. Die Annahme, ein Computer habe kein Gedaechtnis, fuehrt
lediglich dazu, dass man eine Menge einfache Dinger sehr viel
komplizierter ausdruecken muss, ohne an dem Wesen der Vorgaenge auch
nur das geringste zu aendern. Eine Unterroutine, die eine andere
Unterroutine fuer alle Elemente einer verketteten Liste aufruft und
eine andere, verkettete Liste der Resulate zurueckgibt, kann man in C
genausogut formulieren und deren Benutzung sieht dann nicht wesentlich
anders aus. Allerdings kosten die indirekten Aufrufe der
Berechnungsfunktion mehr Zeit, als die direkte, wiederholte
Ausfuehrung der Berechnung (oder sogar der Berechungsfunktion) und
weil die Implementierung der Iterationsroutine ausserdem geschrieben
werden muesste, rentiert sich das eben haeufig nicht: Es bedeutet mehr
Arbeit mit dem Seiteneffekt langsamer ablaufenden Codes. Schon eine
Liste als abstrakten Datentype zu implementieren, ist essentiell
Quark: Es spart fuer elementare Operationen eine vernachlaessigbare
Anzahl von Anweisungen 'hier und dort' ein und erfordert im Gegenzug
die Implementierung zahlreicher Einmal-Algorithmen, die jeweils eine
nicht-elementare Operation, die von einem Programmteil benutzt wird,
zur Verfuegung stellen. Das kann man im Kontext dessen, was eine
solche Datenstruktur fuer irgentwas benutzt, einfacher machen. Der
Code wird auch verstaendlicher, wenn sich seine Struktur am zu
loesenden Problem orientiert, anstatt an 'Problemen bei seiner
Loesung'.
> Oder wenn man nicht mit Listen sondern mit arrays hantieren will (hier
> mal ein Beispiel in OCAML statt in Lisp):
>
> # let feld=[| 1; 2; 3; 4; 5; |];;
> val feld : int array = [|1; 2; 3; 4; 5|]
> # let square x = function x -> x * x;;
> val square : 'a -> int -> int = <fun>
> # Array.mapi square feld;;
> - : int array = [|1; 4; 9; 16; 25|]
> #
... dann sieht das wieder anders aus. Es wird sich immer eine Sprache
finden, bei der es noch kompliziertere Regeln fuer die Verwendung
nicht-alphanumerischer Zeichen gibt. Und man kann auch Quadratzahlen
damit berechnen. Das ist Schoen[tm].
@result = map { $_ ** 2; } (1, 2, 3, 4, 5);
> Und das ganze auch noch mit genauer Typenpruefung und interaktiv zu testen
> um solche Kleinigkeiten evt. separat testen zu koennen. Wenn man sich diesen
> separat ausfuehrbaren Code-Schnipsel (nein, da kommt nichts dazu, auch keine
> Deklarationen, icludes, ...) und das mal mit einem kompletten C-Programm.
> dass diese Funktionalitaet implementiert (einschliesslich aller includes,
> Deklarationen, ... was so alles notwendig ist, um ein ausfuehrbares Pro-
> gramm zu erhalten), dann komme ich zu dem Schluss, dass gerade fuer so
> etwas wie "vorlesungsbegleitende Uebungen zu Mathematik-Vorlesungen"
> evt. solche "nicht so maschinennahen Sprachen" evt. doch eher geignet
> sind, weil sie den Programmierer weniger mit Dingen belasten, die mit
> dem zu loesenden Problem oder dem zu implementierenden Algorithmus eher
> weniger zu tun haben ...
Wie bereits geschrieben: Du verwechselst meiner Ansicht nach
'Maschinenprogrammierung' und 'Umfang der Standardbibliothek'. Ggf
noch 'Maschinenprogrammierung' und 'geringe Menge syntaktischer
Ausnahmen'. Die C-Standardbibliothek halte ich allerdings selbst eher
fuer eine Sammlung historischer Kuriositaeten als fuer wirklich
nuetzlich. Andererseit halte ich es aber auch nicht fuer einen
Nachteil, das sie wenigstens darauf verzichtet, die Welt um eine
weitere praktisch vor allem unhandliche Implementierung von
Container-Datenstrukturen zu bereichern. Wer solches fuer notwendig
haelt, wird Bibliotheken fuer alles finden, was es auf diesem Gebiet
ueblicherweise gibt, aber mit 'Keep it simple, Sam' kommt man auch
ganz gut durch.
> Wenn wir diese Diskussion weiterzufuehren gednken, sollten wir aber besser
> in eine andere Gruppe umziehen (welche? Vprschlaege? Gibt eine "advocacy"
> Gruppe fuer Programmiersprachen?).
Ja. Deswegen ist sie auch diskussions-untauglich: 'Advocacy' bedeutet
praktisch fast immer 'Wettbruellen'. Das ist sicher auch ein schoenes
Hobby, aber ausser das immer jemand am lautesten bruellte, kommt dabei
nicht viel heraus.
> "Waere es nicht einfacher, wenn man dass alles viel komplizierter
> machen wuerde?". So klingt das wenigstens fuer mich.
Ja, Rainer. Und in der realen Welt löst man Probleme mittels
Computerprogrammen, die sich zufällig auf diese Art lösen lassen. Nur,
dass diese Probleme in den seltensten Fällen tatsächlich primär irgendetwas
mit einem Computer, dessen Befehlsliste, Speichermodell und weiterem blabla
zu tun haben.
> Wer solches fuer notwendig haelt, wird Bibliotheken fuer alles finden,
> was es auf diesem Gebiet ueblicherweise gibt, aber mit 'Keep it simple,
> Sam' kommt man auch ganz gut durch.
Ja, und deswegen programmiert man auch in Nullen und Einsen, denn
"simpler" geht's nicht. Da sich in der Praxis der "simple" Weg aber nicht
bewährt hat, hat man solche komischen Sachen wie "Abstraktion" erfunden.
Das ist übrigens eines von diesen akademischen Dingern, die kein Schwein
braucht.
Manchmal kommst Du mir vor wie ein Archäologe, der - weil er es
nicht anders kennt - die Fakäliengrube hinter seinem Haus mit dem Pinsel
ausbaggert.
Vinzent.
[...]
>>>> static int const some_values[] = {
>>>> 3,
>>>> 2,
>>>> 1,
>>>> 45,
>>>> -1
>>>> };
>>>>
>>>> int const *pv;
>>>>
>>>> pv = some_values;
>>>> while (*pv != -1) {
>>>> do_something(*pv);
>>>> ++pv;
>>>> }
[...]
>>> |for i := Low (some_values) to High (some_values) do
>>> | do_something (some_values[i]);
[...]
>> Der Code ist allerdings einfacher, denn er iteriert nicht ueber einen
>> Zahlenbereich, um in Abhaengigkeit von einer Berechung mit der momentanen
>> Zahl und einem Startwert 'etwas anderes' zu tun.
>
> Du sprichst für mich in Rätseln.
Das ist eine ziemlich exakte Uebersetzung von Teilen der oa Schleife
ins Deutsche. Dadurch wird der Vorgang an sich aber nicht einfacher:
Der Computer zaehlt einen bestimmten Zahlenbereich durch und die
enthaltenen Zahlen werden im Schleifenkoerper fuer eine Berechnung
verwendet, aus der sich nach dem Muster basis + (index * elementgroesse)
letztlich die Adresse eines Feldelementes ergibt, auf das indirekt
zugeriffen werden soll. Man koennte das eine Doppelindirektion
nennen, waehrend sie im anderen Fall nur einfach ist: Die explizite
Angabe der Distanz zum Feldanfang wird nicht benoetigt, ebensowenig
wie 'der Feldanfang' (oder meinetwegen 'das Feld') selber.
Das ist die Erklaerung. Die Bemerkung waere, dass in der zweiten
Schleife zwei Variablen vorkommen, in der ersten nur eine.
>> C is unusual in that it allows pointers to point to anything.
>
> Was'n das für'n Blödsinn?
>
> Auch in anderen Sprachen, die das Konzept "Pointer" haben, dürfen die
> im allgemeinen auf alles zeigen.
Standard-Pascal kennt zB keinen 'Adresse-von'-Operator. In einer
ganzen Reihe anderer Sprachen gibt es ueberhaupt keine Zeiger, sondern
bloss Referenzen auf Objekte. Ein C-Zeiger steht fuer einen Ort an
dem sich ein Objekt befindet, falls der Zeiger gueltig ist. Dahinter
befindet sich vielleicht auch noch ein Objekt und wenn dem so ist,
kann man den Zeiger inkrementieren, um auf dieses
zuzugreifen. Vielleicht gibt es auch davor noch eins usf. Was bei
Benutzung eines ungueltigen Zeigers passiert, ist bloss nicht
definiert. Dh es ist auch nicht als Fehler definiert.
[...]
>> Pointers have a bad reputation in academia, because they are
>> considered too dangerous, dirty somehow. But I think they are
>> powerful notation,
[...]
> Natürlich sind Zeiger machtvoll. Aber sie können eben - wie jede Macht -
> auch leicht missbraucht werden (besonders auch in C)
[...]
> Es ist aber nun mal in C so, dass man ohne Zeiger praktisch keine
> sinnvollen Programme schreiben kann.
>
> Nehmen wir mal, so als Beispiel
>
> |char *strcat(char *dest, const char *src);
>
> Was sagt uns das? Eine Funktion, die zwei Zeiger erwartet. Die Daten
> des zweiten Teils werden offenbar nicht geändert (also ist die
> Wahrscheinlichkeit, dass er auch NULL sein darf, eher gering, ganz
> auszuschliessen ist es allerdings nicht).
> Aber was wissen wir über den ersten Parameter, ausser dass es ein Zeiger
> auf einen "char" ist?
>
> Ignorieren wir mal den Rückgabewert und kreieren einen annähernd
> äquivalenten Prototypen in einem halbwegs modernen Pascal-Dialekt:
>
> |procedure strcat (var Dest : String; const Source : String)
>
> Diese Version kommt nun erst einmal völlig ohne (offensichtliche) Zeiger
> aus und enthält zusätzlich noch weitere Informationen:
>
> (1) "Dest sollte ein String sein." (Laut C-Prototyp könnte auch ein
> einzelnes Zeichen gemeint sein, dass es in Wirklichkeit ein
> nullterminierter C-String sein sollte, ist nicht erkennbar.)
> (2) "Keines der beiden Argumente kann NIL/NULL sein."
> (3) Das erste Argument sollte einen bereits initialisierten Wert
> beinhalten (sonst hätte man als Parametermodus besser "out"
> angegeben.)
Aus sich heraus sagt das beides gar nichts[*]. Dafuer braucht es
Referenzdokumentation zum Nachschlagen.
[*] "Der Verfasser der ersten Zeile mochte Sternchen und
bevorzugte einen simplen, 'unbuerokratischen' Stil. Der der
zweiten hatte die Gewohnheit, explizit und formell zu
kategorisieren"? Mit viel Phantasie koennte man noch an Luther
und Calvin denken, obwohl Herr Wirt wohl noch niemanden wegen
hartnaeckigem festhalten einer anderen Meinung oeffentlich
hat verbrennen lassen :->. Hoffe ich wenigstens.
[...]
> Apropos, da fällt mir gerade ein tolles Beispiel aus "Produktivcode" ein
> (auf das relevante gekürzt):
>
> |int *pnYear = 0;
> |int *pnMonth = 0;
> |int *pnDay = 0;
> |
> |[...]
> |GetFileDate (szFileName, pnYear, pnMonth, pnDay);
> |
> |timestamp = *pnYear * 10000 + *pnMonth * 100 + *pnDay;
>
> Dass das ganze auf:
>
> "(int *) NULL * 10000 + (int *) NULL * 100 + (int *) NULL;"
>
> verkürzbar ist, ist einige Jahre lang niemandem aufgefallen: "Compiliert
> doch?" Wenn man bedenkt, dass die Software, aus dem dieses Stück Code
> stammt, gute 200'000 qualitativ vergleichbare SLOC umfasst, tendenziell
> sicherheitsrelevant ist (mit 200 Watt Laserleistung kann man wirklich gut
> Löcher brennen) und den Fakt dazu rechnet, dass das u.a. von sich selbst so
> bezeichnenden langjährigen "C-Programmierern" stammt, die eigentlich
> einigermassen wissen sollten, was sie tun, muss man sich doch fragen, ob
> das eine für Anfänger gut geeignete Sprache ist. Anfänger wissen nämlich
> eher selten, was sie da tun. Ja, ich spreche da auch aus Erfahrung.
Die 'Erfahrung', das es wenigstens eine Person gibt, die eine Menge
schlechten C-Code geschrieben hat, ist aber nicht verallgemeinerbar: C
ist eben eine relativ einfache Sprache und deswegen kann sie von sehr
vielen Leuten in einem wenigstens nutzbaren Umfang erlernt werden.
>> Consider: When you have a pointer to an object, it is a name for
>> exactly that object and no other. That sounds trivial, but look at the
>> following two expressions:
>>
>> np
>> node[i]
>>
>> The first points to a node, the second evaluates to (say) the same
>> node.
>
> Komisch ist nur, dass man in C den Unterschied zwischen dem Objekt "test"
> und 't' mittels char* überhaupt nicht ausdrücken kann.
Ein char * zeigt auf ein Objekt vom Typ 'char'. "test" waere ein
String-Literal, dass man zB zur Initialisierung eines char-Feldes
benutzen koennte, auf dessen Elemente ein char * zeigen kann. Ein
Zeiger auf ein char-Feld haette einen anderen Typ:
#include <stdio.h>
char a[][4] = {
"123",
"456",
"789"
};
char (*p)[4] = a;
int main(void)
{
do
puts(*p);
while (++p < a + sizeof(a)/sizeof(*a));
return 0;
}
> Ein und derselbe Zeiger kann also durchaus auf unterschiedliche
> Inkarnationen ähnlicher Objekte zeigen. Ich bin also geneigt, die
> Aussage "ein Zeiger ist ein Name für /genau ein/ Objekt" für
> schlicht unzutreffend zu halten.
Sehr witzig. "Eine Integer-Variable kann durchaus unterschiedliche
Werte haben, ich bin also geneigt, die Aussage, sie haben /genau
einen/ Wert schlicht fuer unzutreffend zu halten." Ich bin uebrigens
auch geneigt, die Aussage, das die Wohnung neben meiner
Einpersonenappartment sei, fuer falsch zu halten, denn es gab schon
wenigstens drei unterschiedliche Mieter ...
>> But the second form is an expression; it is not so simple. To
>> interpret it, we must know what node is, what i is, and that i and node
>> are related by the (probably unspecified) rules of the surrounding
>> program.
>
> Um "np" korrekt anzuwenden, braucht man auch ohne "i" etwa genau so viel
> Informationen. Es stellt sich zusätzlich die Frage, ob ein etwaiger
> Ausdruck "np++" überhaupt gültig sein kann, was sich bei node[i]
> in den meisten anderen Sprachen wesentlich leichter beantworten lässt, es
> führt im Falle der Ungültigkeit nämlich zu einem nicht übersetzbaren
> Programm.
Korrekterweise muesste man ++np (np++ passt hier nicht zu ganz) mit
node[++i] vergleichen. Das sind wieder zwei (potentiell) gleichwertige
Ausdruecken, von denen einer zwei zueinander in Beziehung stehende
Variablen enthaelt und der andere nur eine.
> Jetzt kann man einwenden (tut der Autor ja unten auch), dass ja
> nicht bekannt ist, ob der Wert des Index "i" nun zur Laufzeit tatsächlich
> einen gültigen Index beschreibt.
Ich denke, er weist eher darauf hin, dass es zwischen i und node nur
die Beziehung gibt, in die der Code sie stellt.
[...]
>> Aber "Sinn oder Unsinn strikter Typ-Pruefungen" ist ein Thema, zu dem
>> keine einheitliche Sichtweise existiert: Wer sie gewohnt ist, haelt sie
>> fuer unverzichtbar oder doch wenigstens nuetzlich,
>
> Der Vorteil ist, dass ich sie in den Fällen, wo sie mir hinderlich ist,
> explizit "wegcasten" kann. Der Nachteil bei weniger strikter Prüfung liegt
> darin, dass eine Menge möglicher Fehler eben nicht schon vom
> Compiler erkannt wird.
>
> Davon abgesehen, sind vom Programmierer eingefügte Type-Casts in C
> tendenziell häufiger zu finden als in typstrengeren Sprachen. Klingt zwar
> widersprüchlich, ist aber so. Wirklich erklären kann ich's auch
> nicht.
Das koennte daran liegen, dass die meisten casts in existierenden
C-Programmen sowohl technisch als auch sprachlich ueberfluessig sind
:->.
>> wer eher Sprachen mit dynamischer Typisierung oder vollkommen ohne
>> welche benutzt, fuer Quatsch, mit dem man sich nicht befassen
>> sollte, "weil er mit dem Problem nichts zu tun hat".
>
> Dynamische Typisierung hat mit strikter oder weniger strikter
> Typprüfung erst mal nix zu tun.
'Dynamische Typisierung' bedeutet 'keine strikte Typ-Pruefung durch
einen Compiler'.
[...]
>>> Abgesehen davon ist In-Band-Signalling einfach nur böse, auch wenn es
>>> in C oft eine technische Notwendigkeit ist.
>>
>> 'Boese' ist eine moralische Kategorie.
>
> Korrekt. Ich kann technische Notwendigkeit nun mal nicht mit technischen
> Argumenten kritisieren. Dass etwas nicht anders geht, bedeutet allerdings
> auch nicht, dass es eine gute (Vorsicht: moralische Kategorie!)
> Lösung ist.
Der Punkt war (oder sollte sein), dass 'dieser Code ist boese' fuer
sich nichts bedeutet.
>> Was genau 'in-band signalling' in einem Computerprogramm eigentlich
>> sein soll, waere zu definieren.
>
> Triviales Beispiel für C: Das abschliessende '\0' eines C-"Strings".
Das ist keine Definition. 'in-band signalling' bedeutet 'Nutzung
desselben Uebertragungskanals sowohl fuer Nutzdaten als auch (von
diesen unabhaengige) Steuernachrichten'. Das laesst sich auf 'Folge
von Zahlen mit einem Wert != 0, gefolgt von einer 0' nicht sinnvoll
uebertragen.
[...]
>> Aber diese muessten eigentlich auch nachteilig sein, ohne zu ihrer
>> Beschreibung Begriffe aus der Nachrichtentechnik zu entlehnen.
>
> Wenn Dir ein besserer Begriff dafür einfällt...
Wofuer?
>> Ein Beispiel einer 'naiven' Definition waere zB die Benutzung derselben
>> TCP-Verbindung fuer Kommandos und Datenuebertragung und die
>> Schlussfolgerung waere dann, dass 'HTTP' 'boese' sei,
>
> Inwiefern würde In-Band-Signalling auf HTTP zutreffen? Die Richtung der
> Datenübertragung ist festgelegt und damit auch "Kommando-" und
> "Datenkanal".
Es gibt nur einen Kanal, der sowohl Nutzdaten als auch
Steuerinformationen uebertraegt.
... argumentiert man, wenn man Argumente hat. Andernfalls wird man
persoenlich. Darauf kann man dann nur persoenlich antworten: Du
verwechselt gewohnheitsmaessig Deine Umgebung mit 'der Welt' als
solcher. Aber Du entwickelst keine Software, die irgendjemand, mit ich
schon mal beruflich zu tun gehabt haette, jeweils benutzt hat oder
benutzen wird.
Soll ich Dir jetzt glauben, dass es die trotzdem gibt? Oder darf ich
mir Deine Position des 'was ich nicht persoenlich kennengelernt habe,
gibt es jedenfalls nicht' zueigenmachen?
Der Vorgang nicht. Aber das Ausdrücken eines solchen Vorgangs
möglicherweise:
"Wirf in jeden Briefkasten i der Strasse x ein Werbeblatt."
Abbruchbedingung: Ende der Strasse. In der einen Form in Form der
Hausnummer -1, falls die nicht existiert, falle ich in die Baugrube, in
der anderen Form ist der Arbeitsaufwand sogar im Voraus abschätzbar (und
definiert endlich).
> zugeriffen werden soll. Man koennte das eine Doppelindirektion nennen,
> waehrend sie im anderen Fall nur einfach ist: Die explizite Angabe der
> Distanz zum Feldanfang wird nicht benoetigt, ebensowenig wie 'der
> Feldanfang' (oder meinetwegen 'das Feld') selber.
Der "Feldanfang" wird auch hier irgendwann benötigt. Der Unterschied
besteht nur darin, dass man nicht einmal weiss, ob es tatsächlich ein
"Feld" sein könnte. Es geht also eine gewisse, unter Umständen
wichtige Information verloren.
> Das ist die Erklaerung. Die Bemerkung waere, dass in der zweiten
> Schleife zwei Variablen vorkommen, in der ersten nur eine.
Die "Variable" ist in der zweiten Schleife allerdings eine Konstante. Gut,
lassen wir das als Spitzfindigkeit stehen.
>>> C is unusual in that it allows pointers to point to anything.
>>
>> Was'n das für'n Blödsinn?
>>
>> Auch in anderen Sprachen, die das Konzept "Pointer" haben, dürfen die
>> im allgemeinen auf alles zeigen.
>
> Standard-Pascal kennt zB keinen 'Adresse-von'-Operator.
Was zwar Prozedurvariablen unmöglich macht, aber ansonsten aufgrund der
relativen Ausdrucksfähigkeit (Parametermode) dieses Manko wieder
einigermassen ausgleicht, schlicht aus der Tatsache heraus, dass es nicht
notwendig ist.
Man kann sich aber natürlich für jegliche Argumentation auf ein "zu
wenig mächtiges" Subset beschränken, welches zwar in den meisten real
existierenden Sprachumgebungen nicht existiert, aber zumindest bei der
Argumentation hilfreich ist. Siehe Linus Torvalds' Rant über Pascal,
welches "Scheisse ist, weil es kein goto kennt" (inhaltliche Kurzfassung
meinerseits). Natürlich ist dann ein real existierender Dialekt nicht mehr
standardkonform, aber das Kriterium Standardkonformität halte ich - ohne
Wertung der Sprache - für einen Anfänger erst einmal für etwas weniger
wichtig. Was jetzt weder heisst, dass ich unportablen Code ("Funktioniert
doch!?") gutheisse, noch auf irgendwelche Standards scheisse.
Aber bitte, ich kann das auch: "Ada is unusual in that it allows concurrent
execution of code." Ada hat Tasking als Sprachmittel eingebaut, C nicht.
Daraus folgt: Ich kann in einer (rein standardkonformen) C-Umgebung keine
Programme schreiben, die in irgendeiner Weise so was wie Multithreading
machen. Trotzdem gibt es real existierende, in C geschriebene Programme,
die das können. Wenn ich das jetzt auf die Spitze treibe, könnte ich also
behaupten, dass diese Programme weder standardkonform noch portabel sind
(technisch betrachtet sind sie das ja auch nicht), und demzufolge C eine
völlig sinnlose, vollkommen theoretische, rein akademische und
ausserhalb irgendwelcher Lehrinstitutionen komplett unbrauchbare Sprache
ist.
> In einer ganzen
> Reihe anderer Sprachen gibt es ueberhaupt keine Zeiger, sondern bloss
> Referenzen auf Objekte.
Was auch nix anderes ist, nur meist aus "akademischen" Gründen anders
genannt wird. In Ada heissen die Dinger auch nicht Zeiger, sondern
Zugriffstypen, nichtsdestotrotz werden sie schlussendlich vom Compiler in
nichts anderes als Speicheradressen aufgelöst.
> auch davor noch eins usf. Was bei Benutzung eines ungueltigen Zeigers
> passiert, ist bloss nicht definiert. Dh es ist auch nicht als Fehler
> definiert.
Nette Spitzfindigkeit. Ein Programm, dessen Funktion "undefiniert" ist,
ist in den seltensten Fällen als "funktionierend" oder gar "korrekt"
anzusehen.
>> Nehmen wir mal, so als Beispiel
>>
>> |char *strcat(char *dest, const char *src);
>>
>> Was sagt uns das? Eine Funktion, die zwei Zeiger erwartet. Die Daten
>> des zweiten Teils werden offenbar nicht geändert (also ist die
>> Wahrscheinlichkeit, dass er auch NULL sein darf, eher gering, ganz
>> auszuschliessen ist es allerdings nicht). Aber was wissen wir über den
>> ersten Parameter, ausser dass es ein Zeiger auf einen "char" ist?
>>
>> Ignorieren wir mal den Rückgabewert und kreieren einen annähernd
>> äquivalenten Prototypen in einem halbwegs modernen Pascal-Dialekt:
>>
>> |procedure strcat (var Dest : String; const Source : String)
>>
>> Diese Version kommt nun erst einmal völlig ohne (offensichtliche)
>> Zeiger aus und enthält zusätzlich noch weitere Informationen:
>>
>> (1) "Dest sollte ein String sein." (Laut C-Prototyp könnte auch ein
>> einzelnes Zeichen gemeint sein, dass es in Wirklichkeit ein
>> nullterminierter C-String sein sollte, ist nicht erkennbar.) (2)
>> "Keines der beiden Argumente kann NIL/NULL sein." (3) Das erste
>> Argument sollte einen bereits initialisierten Wert beinhalten (sonst
>> hätte man als Parametermodus besser "out" angegeben.)
>
> Aus sich heraus sagt das beides gar nichts[*].
Über die Semantik nicht, nein. Aber zumindest einiges über erwartete
Vorbedingungen, man kann also gewisse Dinge (aka. Fehlerquellen)
ausschliessen. Und - man kommt ohne (explizite) Zeiger problemlos aus.
> [*] "Der Verfasser der ersten Zeile mochte Sternchen und bevorzugte
> einen simplen, 'unbuerokratischen' Stil. Der der zweiten hatte die
> Gewohnheit, explizit und formell zu kategorisieren"?
Der Verfasser der ersten Zeile hatte vor allem gar keine andere
(sinnvollere) Möglichkeit, sich anders auszudrücken. Das liegt allerdings
im speziellen Fall nicht am Verfasser.
>> Apropos, da fällt mir gerade ein tolles Beispiel aus "Produktivcode"
>> ein (auf das relevante gekürzt):
>>
>> |int *pnYear = 0;
>> |int *pnMonth = 0;
>> |int *pnDay = 0;
>> |
>> |[...]
>> |GetFileDate (szFileName, pnYear, pnMonth, pnDay); | |timestamp =
>> *pnYear * 10000 + *pnMonth * 100 + *pnDay;
>>
>> Dass das ganze auf:
>>
>> "(int *) NULL * 10000 + (int *) NULL * 100 + (int *) NULL;"
>>
>> verkürzbar ist, ist einige Jahre lang niemandem aufgefallen:
>> "Compiliert doch?" Wenn man bedenkt, dass die Software, aus dem dieses
>> Stück Code stammt, gute 200'000 qualitativ vergleichbare SLOC umfasst,
>> tendenziell sicherheitsrelevant ist (mit 200 Watt Laserleistung kann
>> man wirklich gut Löcher brennen) und den Fakt dazu rechnet, dass das
>> u.a. von sich selbst so bezeichnenden langjährigen "C-Programmierern"
>> stammt, die eigentlich einigermassen wissen sollten, was sie tun, muss
>> man sich doch fragen, ob das eine für Anfänger gut geeignete Sprache
>> ist. Anfänger wissen nämlich eher selten, was sie da tun. Ja, ich
>> spreche da auch aus Erfahrung.
>
> Die 'Erfahrung', das es wenigstens eine Person gibt, die eine Menge
> schlechten C-Code geschrieben hat, ist aber nicht verallgemeinerbar: C
> ist eben eine relativ einfache Sprache und deswegen kann sie von sehr
> vielen Leuten in einem wenigstens nutzbaren Umfang erlernt werden.
Wenn dabei Dinge wie das oben erwähnte dabei herauskommen, scheint
die Nützlichkeit dieses "nutzbarem Umfangs" allerdings etwas auf der
Strecke zu bleiben. Immerhin sind für diesen "schlechten C-Code" in den
letzten 15 Jahren mehr als nur ein Programmierer verantwortlich gewesen.
Was natürlich nichts über die restlichen in der Welt existierenden
Programmierer aussagt. Statistisch wahrscheinlich, dass sich an nur einer
Stelle der ganze Müll gesammelt hat, ist es allerdings nicht. :->
>>> Consider: When you have a pointer to an object, it is a name for
>>> exactly that object and no other. That sounds trivial, but look at
>>> the following two expressions:
>>>
>>> np
>>> node[i]
>>>
>>> The first points to a node, the second evaluates to (say) the same
>>> node.
>>
>> Komisch ist nur, dass man in C den Unterschied zwischen dem Objekt
>> "test" und 't' mittels char* überhaupt nicht ausdrücken kann.
>
> Ein char * zeigt auf ein Objekt vom Typ 'char'. "test" waere ein
> String-Literal, dass man zB zur Initialisierung eines char-Feldes
> benutzen koennte, auf dessen Elemente ein char * zeigen kann.
Sagte ich doch.
#include <stdio.h>
int main(void)
{
char* a = "test";
char* b = &a[0];
printf ("%s %s", a, b);
return 0;
}
Was ist der qualifizierende Unterschied zwischen "char* a" und "char* b"?
Primär sehe ich da keinen, auch wenn möglicherweise die Intention darin
bestand, "a" auf ['t', 'e', 's', 't', '\0'] zeigen zu lassen und "b"
ausschliesslich auf 't'.
>> Ein und derselbe Zeiger kann also durchaus auf unterschiedliche
>> Inkarnationen ähnlicher Objekte zeigen. Ich bin also geneigt, die
>> Aussage "ein Zeiger ist ein Name für /genau ein/ Objekt" für schlicht
>> unzutreffend zu halten.
>
> Sehr witzig. "Eine Integer-Variable kann durchaus unterschiedliche Werte
> haben, ich bin also geneigt, die Aussage, sie haben /genau einen/ Wert
> schlicht fuer unzutreffend zu halten."
Das meinte ich nicht. Was ich meinte war, dass man anhand des Zeigers nicht
unbedingt erkennt, um was für eine Art von Objekt es sich dabei handelt.
Genau das schien der Autor allerdings ausdrücken zu wollen. Und
demgegenüber kann ich einwenden, dass zu einem bestimmten Zeitpunkt ein
Ausdruck "x[i]" genauso /genau ein/ Objekt bezeichnet wie "px". Wäre sonst
komisch.
>>> But the second form is an expression; it is not so simple. To
>>> interpret it, we must know what node is, what i is, and that i and
>>> node are related by the (probably unspecified) rules of the
>>> surrounding program.
>>
>> Um "np" korrekt anzuwenden, braucht man auch ohne "i" etwa genau so
>> viel Informationen. Es stellt sich zusätzlich die Frage, ob ein
>> etwaiger Ausdruck "np++" überhaupt gültig sein kann, was sich bei
>> node[i] in den meisten anderen Sprachen wesentlich leichter beantworten
>> lässt, es führt im Falle der Ungültigkeit nämlich zu einem nicht
>> übersetzbaren Programm.
>
> Korrekterweise muesste man ++np (np++ passt hier nicht zu ganz) mit
> node[++i] vergleichen. Das sind wieder zwei (potentiell) gleichwertige
> Ausdruecken, von denen einer zwei zueinander in Beziehung stehende
> Variablen enthaelt und der andere nur eine.
Wobei "++" dieselbe Beziehung darstellt.
>> Dynamische Typisierung hat mit strikter oder weniger strikter
>> Typprüfung erst mal nix zu tun.
>
> 'Dynamische Typisierung' bedeutet 'keine strikte Typ-Pruefung durch
> einen Compiler'.
Aber es bedeutet nicht zwingend "keine strikte Typ-Prüfung durch die
Laufzeitumgebung".
>>>> Abgesehen davon ist In-Band-Signalling einfach nur böse, auch wenn es
>>>> in C oft eine technische Notwendigkeit ist.
>>>
>>> 'Boese' ist eine moralische Kategorie.
>>
>> Korrekt. Ich kann technische Notwendigkeit nun mal nicht mit
>> technischen Argumenten kritisieren. Dass etwas nicht anders geht,
>> bedeutet allerdings auch nicht, dass es eine gute (Vorsicht: moralische
>> Kategorie!) Lösung ist.
>
> Der Punkt war (oder sollte sein), dass 'dieser Code ist boese' fuer sich
> nichts bedeutet.
Der Code an sich kann ja auch nix dafür. Es ist der Entwickler, der die
Lösung präferiert hat (vielleicht aus "technischer Notwendigkeit", dann
kann ihm kein Vorwurf gemacht werden). Daher auch die moralische
Kategorie. :P
>>> Was genau 'in-band signalling' in einem Computerprogramm eigentlich
>>> sein soll, waere zu definieren.
>>
>> Triviales Beispiel für C: Das abschliessende '\0' eines C-"Strings".
>
> Das ist keine Definition. 'in-band signalling' bedeutet 'Nutzung
> desselben Uebertragungskanals sowohl fuer Nutzdaten als auch (von diesen
> unabhaengige) Steuernachrichten'.
Übertragungskanal: Der Speicher des Computers.
Nutzdaten: Die im Speicher enthaltenen Bytes.
Steuernachricht: '\0' (welches in den Nutzdaten ja nicht vorkommen darf)
für "jetzt hör auf, hier ist Ende".
> Das laesst sich auf 'Folge von Zahlen mit einem Wert != 0, gefolgt
> von einer 0' nicht sinnvoll uebertragen.
Geeignetes Abstraktionsvermögen vorausgesetzt, schon.
>>> Aber diese muessten eigentlich auch nachteilig sein, ohne zu ihrer
>>> Beschreibung Begriffe aus der Nachrichtentechnik zu entlehnen.
>>
>> Wenn Dir ein besserer Begriff dafür einfällt...
>
> Wofuer?
IBS in der von mir gebrachten Abstraktion. ;)
>>> Ein Beispiel einer 'naiven' Definition waere zB die Benutzung
>>> derselben TCP-Verbindung fuer Kommandos und Datenuebertragung und die
>>> Schlussfolgerung waere dann, dass 'HTTP' 'boese' sei,
>>
>> Inwiefern würde In-Band-Signalling auf HTTP zutreffen? Die Richtung der
>> Datenübertragung ist festgelegt und damit auch "Kommando-" und
>> "Datenkanal".
>
> Es gibt nur einen Kanal, der sowohl Nutzdaten als auch
> Steuerinformationen uebertraegt.
Da bin ich konträrer Meinung. Aber das liegt wohl eher an unserer
unterschiedlichen kontextuellen Definition von Steuerinformation und
Nutzdaten.
Vinzent.
> Vinzent Hoefler <nntp-2...@t-domaingrabbing.de> writes:
>> On Sun, 31 Aug 2008 14:33:47 +0200, Rainer Weikusat wrote:
>>> "Waere es nicht einfacher, wenn man dass alles viel komplizierter
>>> machen wuerde?". So klingt das wenigstens fuer mich.
>>
>> Ja, Rainer. Und in der realen Welt
>
> ... argumentiert man, wenn man Argumente hat.
... oder erzählt ganz viel Sachen von Speicheradressen, Registernamen
und ähnlichem Zeugs, was für die spezifische Diskussion absolut irrelevant
ist, weil es mit dem eigentlichen Thema nichts, aber auch gar nichts zu tun
hat.
> Andernfalls wird man persoenlich.
Entschuldige, dass ich Dich ansprach.
> Darauf kann man dann nur persoenlich
> antworten: Du verwechselt gewohnheitsmaessig Deine Umgebung mit 'der
> Welt' als solcher.
Nun, ich spreche aus meiner persönlichen Erfahrung, welche sich
zufälligerweise mit der Erfahrung vieler anderer Leute, die ich
ernstnehme, deckt. Willst Du mir das zum Vorwurf machen?
> Aber Du entwickelst keine Software, die irgendjemand,
> mit ich schon mal beruflich zu tun gehabt haette, jeweils benutzt hat
> oder benutzen wird.
Du hast mit sehr hoher Wahrscheinlichkeit schon mal ein Produkt in der Hand
gehalten, welches durch mittelbare Hilfe der Software, an der ich
mitentwickelt habe, entstanden ist.
> Soll ich Dir jetzt glauben, dass es die trotzdem gibt? Oder darf ich mir
> Deine Position des 'was ich nicht persoenlich kennengelernt habe, gibt
> es jedenfalls nicht' zueigenmachen?
Komisch. Genau diese "Position" hätte ich Dir tatsächlich zugeordnet. Aber
egal. Ich bin mir zumindest nicht bewusst, Deine Aussagen öfter als
real nicht-existent dargestellt zu haben als Du meine.
Vinzent.
>>>> Das weißt du, weil du den x86-Befehlssatz und das IEEE-Floating-Point-
>>>> Format kennst. Wer das nicht kennt, dürfte gewisse Mühen haben, diese
>>>> Funktion in C aufzuschreiben.
>>> Assemblerkenntnisse sind hier unnötig, aber IEEE754 sollte man schon mal
>>> angeschaut haben, ja. Dann würde man auch darauf kommen, dass man den
>>> Exponenten nicht schieben muss, sondern addieren, schliesslich
>>> exponenziert der ja schon. ;)
>> Klaro. Nur - nicht alles ist IEEE, und nicht alles, was einen C-Compiler
>> hat, verwendet IEEE.
>
> Durchaus richtig. Allerdings ist das Grundprinzip des Aufbaus von
> Gleitkommazahlen trotzdem recht ähnlich. Als Beispiel das Format der Cray:
>
> http://www.cisl.ucar.edu/zine/96/fall/articles/4.ieee.formats.html
>
> (Wobei ich mir einbilde, mal gelesen zu haben, dass sie auch dort später
> auf IEEE754 gewechselt haben.)
>
>> Heutzutage zugegebenermaßen "fast immer", aber ich habe da
>> noch ein paar alte Systeme, die verwenden sowas wie BCD-Darstellung für
>> Fließkommazahlen; da ist dann nichts mit "effiziente Implementierung". (-:
>
> Doch, da FLT_RADIX dann nicht mehr 2, sondern 10 sein dürfte.
Nein, FLT_RADIX wäre auf diesem (zugegebenermaßen kranken) System 100. (-:
> Grundsätzlich wird entweder der Exponent dann per Addition angepasst oder
> (wie im Falle des erwähnten DSP-56K, der keinen Exponenten hat), halt die
> Mantisse geschoben.
>>> Auf jeden Fall sieht man anhand des Beispiels, dass die Operation
>>> doch einigermassen effizient implementierbar sein sollte.
>> Für IEEE - ja sicher.
>
> Auch für andere Formate (natürlich nicht in exakt der gezeigten
> Implementation). Es dürfte einen Grund geben, warum man sich da auf
> FLT_RADIX bezieht.
Sicher.
Grüße,
Thomas
Das ist schon mal ein Verstoß gegen die Zugriffsregeln 6.5p4. Als Nutzer
einer C-Implementation darfst du sowas nicht guten Gewissens schreiben.
Der Implementierer, der genau weiß, dass sein Compiler obiges zum
gewünschten Code übersetzt, der darf das. Und deswegen verlangt die
Norm, dass er das tut und 'scalbfn' nennt.
Stefan
> Vinzent Hoefler wrote:
>> On Sat, 30 Aug 2008 12:34:35 +0200, Stefan Reuther wrote:
> [Was tut scalblnl()?]
>>>>Da es erst mal nix anderes tut, als den Exponentenanteil einer
>>>>Gleitkommazahl nach links zu schieben, würde ich da eine gewisse Effizienz
>>>>erwarten.
>>>
>>>Das weißt du, weil du den x86-Befehlssatz und das IEEE-Floating-Point-
>>>Format kennst. Wer das nicht kennt, dürfte gewisse Mühen haben, diese
>>>Funktion in C aufzuschreiben.
>>
>> Assemblerkenntnisse sind hier unnötig, aber IEEE754 sollte man schon mal
>> angeschaut haben, ja. Dann würde man auch darauf kommen, dass man den
>> Exponenten nicht schieben muss, sondern addieren, schliesslich
>> exponenziert der ja schon. ;)
> [...]
>> float scalbfn (float f, int y)
>> {
>> int32_t x = *((int32_t*) &f);
>
> Das ist schon mal ein Verstoß gegen die Zugriffsregeln 6.5p4.
Ähm. Irgendwie hab' ich den falschen Absatz, glaube ich:
ISO/IEC 9899:1999 (E):
|Some operators (the unary operator ~, and the binary operators <<, >>, &,
|^, and |, collectively described as bitwise operators) are required to
|have operands that have integer type. These operators return values that
|depend on the internal representations of integers, and have
|implementation-defined and undefined aspects for signed types.
Auch in 6.5.4. (Cast-Operators) finde ich nichts, was grundsätzlich
(im juristischen Sinne) dagegen spricht.
> Als Nutzer einer C-Implementation darfst du sowas nicht guten Gewissens
> schreiben.
Ja, klar. Dass ich hier spezifische (und damit auch unportable) Annahmen
über Grösse, Alignment und u.U. sogar Endianess der beteiligten
Typen mache(n muss), war ja von vornherein klar. ;)
Wobei ich gerade feststelle, dass C99 offenbar tatsächlich
IEEE754/854-konforme Gleitkommatypen fordert (Annex F), was die in
der Praxis möglichen Varianten dann doch arg einschränkt.
> Der Implementierer, der genau weiß, dass sein Compiler obiges zum
> gewünschten Code übersetzt, der darf das. Und deswegen verlangt die
> Norm, dass er das tut und 'scalbfn' nennt.
Rischdisch. Ziel der Aktion war ja auch lediglich, darzulegen, warum die
vom Compilerhersteller gelieferte Implementation im allgemeinen doch recht
effizient sein sollte. Dass ich solche Sachen dann nicht gerne selbst pro
mögliches Zielsystem schreiben möchte, versteht sich ja von
selbst. Schliesslich bin ich faul.
Vinzent.
Ich hatte geschrieben, dass der Code einfacher sei und diese Aussage
sogar noch mehrfach erlaeutert, weil 'er benutzt eine Variable'
anstelle von 'er benutzt zwei Variablen' wohl in sich selbst nicht
auffaellig genug ist. Spekulationen darueber, was hypothetische andere
Personen vielleicht wie empfinden koennten, sind ziemlich
sinnfrei. Das es jemanden gibt, der Deine technische Erklaerung des
C-Beispiels vielleicht nicht versteht, weil die darin verwendeten
Begriffe ihm unbekannt sind, heisst nichts: Das sind
Implementierungsdetails, die man nur dann wissen muss, wenn man
Aussagen ueber den erzeugten Code anstelle von Aussagen ueber den
Quellcode machen moechte.
>> C is unusual in that it allows pointers to point to anything.
>>
>> [...]
>>
>> Pointers have a bad reputation in academia, because they are
>> considered too dangerous, dirty somehow. But I think they are
>> powerful notation, which means they can help us express
>> ourselves clearly.
>>
>
> Klar, zwei Worte für den gleichen Begriff zu haben, ist für klare
> Ausdrucksweise unabdingbar. (s.o.)
Dieser Rueckverweis ist 'dangling pointer': Bisher hattest Du nichts
geschrieben, wozu er passen wuerde. Um welchen Begriff geht es, welche
zwei Worte dafuer hast Du in oa Text gefunden und warum haelst Du sie
fuer vollkommen synonym?
> [...]
>> Nothing about
>> the expression in isolation can show that i is a valid index
>> of node, let alone the index of the element we want.
>>
>> [http://www.lysator.liu.se/c/pikestyle.html]
>>
>
> Aha. 'node[i]' ist also schlechter als 'np', weil wir bei 'node[i]'
> nicht auf den ersten Blick sehen, ob das überhaupt die Zahl ist,
'schlechter' ist Dein Adjektiv. In dem von mir zitierten Text kam es
nicht vor. Dessen Aussage bezieht sich immer noch darauf, das node und
i zwei voneinander unabhaengige Variablen sind, die durch den Code,
der sich benutzt, in eine bestimmte Beziehung zu einander gesetzt
werden.
> Eine Frage an die Runde: Seht ihr bei 'np' alleine, dass es genau
> die Zahl ist, die wir haben wollen?
Es ist ueberhaupt keine Zahl, sondern ein Zeiger auf ein Element eines
Feldes von Strukturen (wahrscheinlich). Dh es ist ein 'Ding', dessen
Bedeutung verstanden werden muss, anstelle von zweien, die in einer
sich aus dem nicht gezeigten anderen Code ergebenden Beziehung
zueinander stehen. Um mehr geht es gar nicht.
[...]
> Was wollte uns der Autor also sagen?
1 < 2 == 1
Einfacher ist das, was weniger Teile hat.
> 1 < 2 == 1
>
> Einfacher ist das, was weniger Teile hat.
Aber eben um diese Einfachheit geht es: Man versucht, Komplexität dadurch
zu verringern, dass man die /Anzahl/ der zur Problemlösung /benötigten/
Einzelteile reduziert, nicht zwingend die Anzahl der möglichen zur
Verfügung stehenden Einzelteile. Auch wenn dann diese Einzelteile selbst
wieder "abstrakt akademische Dinger" sind, die in ihrer Eigenkomplexität
deutlich über "inkrementiere einen Zeiger auf Irgendwas" hinausgehen. (Was
jetzt kein Credo für riesige ("aufgeblasene") Standardbibliotheken sein
soll, falls das mal wieder jemand so verstanden haben möchte.)
Um mal wieder eine naturgemäss vollkommen unpassende Analogie zu
bringen: Der architektonische Plan eines Hauses bezeichnet meines
Wissens auch nicht jeden einzeln zu verwendenden Ziegelstein, sondern
hauptsächlich die für die Betrachtung relevanten (wenn auch in sich
komplexeren) Teile.
Vinzent.
P.S. "(1 < 2) == 1" oder "1 < (2 == 1)"? Ich mag explizite
Klammerung, auch wenn der Sprachstandard Operatorenrangfolgen festlegt.
Tippfehler. 6.5p7: "An object shall have its stored value accessed only
by an lvalue expression that has one of the following types:"
Stefan
Nun heißt die Verwendung von weniger Variablen nicht unbedingt, dass
der Code einfacher wird.
Beispiel:
int a = 1;
int b = 2;
int c = a + b;
OK, das ist noch einfach zu durchschauen, und a und b sind eigentlich
reichlich überflüssig. Was machst du aber bei so etwas hier:
double a = exp(5 * log(6));
double b = scalbln(a, 5);
double c = a * 5 + b * 6;
Da wird es schon schwieriger. Und jetzt stelle dir mal vor, die
Initialisierung von a und b ginge bis zur 80. Spalte und die von c
wäre noch etwas komplexer. Würdest du dann immer noch die Variante
ohne a und b präferieren?
> Spekulationen darueber, was hypothetische andere
> Personen vielleicht wie empfinden koennten, sind ziemlich
> sinnfrei. Das es jemanden gibt, der Deine technische Erklaerung des
> C-Beispiels vielleicht nicht versteht, weil die darin verwendeten
> Begriffe ihm unbekannt sind, heisst nichts: Das sind
> Implementierungsdetails, die man nur dann wissen muss, wenn man
> Aussagen ueber den erzeugten Code anstelle von Aussagen ueber den
> Quellcode machen moechte.
>
>>> C is unusual in that it allows pointers to point to anything.
>>>
>>> [...]
>>>
>>> Pointers have a bad reputation in academia, because they are
>>> considered too dangerous, dirty somehow. But I think they are
>>> powerful notation, which means they can help us express
>>> ourselves clearly.
>>>
>>
>> Klar, zwei Worte für den gleichen Begriff zu haben, ist für klare
>> Ausdrucksweise unabdingbar. (s.o.)
>
> Dieser Rueckverweis ist 'dangling pointer': Bisher hattest Du nichts
> geschrieben, wozu er passen wuerde. Um welchen Begriff geht es, welche
> zwei Worte dafuer hast Du in oa Text gefunden und warum haelst Du sie
> fuer vollkommen synonym?
>
Nicht in dem Text! Es ging doch um Pointer. Damit Pointer etwas
definitiv nützliches tun, müssen sie auf irgendwas zeigen, das wir
schon definiert haben. Also ist ein Pointer nach der Initialisierung,
solange wir ihn nicht verändern, ein Synonym für etwas, das wir schon
definiert haben. Beispiel:
int node[5];
int* np;
np = node;
Jetzt sind node und np vollkommen synonym.
Sicher gibt es nützliche Verwendungsmöglichkeiten von Pointern, aber
gerade "klare Ausdrucksweise" gehört definitiv nicht dazu.
>> [...]
>>> Nothing about
>>> the expression in isolation can show that i is a valid index
>>> of node, let alone the index of the element we want.
>>>
>>> [http://www.lysator.liu.se/c/pikestyle.html]
>>>
>>
>> Aha. 'node[i]' ist also schlechter als 'np', weil wir bei 'node[i]'
>> nicht auf den ersten Blick sehen, ob das überhaupt die Zahl ist,
>
> 'schlechter' ist Dein Adjektiv. In dem von mir zitierten Text kam es
> nicht vor.
Das muss es auch nicht, denn es wurde durch seine Wortwahl impliziert.
> Dessen Aussage bezieht sich immer noch darauf, das node und
> i zwei voneinander unabhaengige Variablen sind, die durch den Code,
> der sich benutzt, in eine bestimmte Beziehung zu einander gesetzt
> werden.
>
Richtig, soweit stimmt es ja auch. Er sagt aber in dem von mir
zitierten Teil, dass wir bei 'node[i]' nicht ohne Programmkontext
sehen, dass wir die richtige Zahl erwischt haben. Seine Wortwahl
impliziert, dass er sagen will, dass das mit 'np' ginge. Geht aber
nicht.
>> Eine Frage an die Runde: Seht ihr bei 'np' alleine, dass es genau
>> die Zahl ist, die wir haben wollen?
>
> Es ist ueberhaupt keine Zahl, sondern ein Zeiger auf ein Element eines
> Feldes von Strukturen (wahrscheinlich).
Ja, da haben wir es schon: Man weiß es nicht. Ich weiß auch nicht, was
der Autor des von dir zitierten Textes also nun sagen wollte.
> Dh es ist ein 'Ding', dessen
> Bedeutung verstanden werden muss, anstelle von zweien, die in einer
> sich aus dem nicht gezeigten anderen Code ergebenden Beziehung
> zueinander stehen. Um mehr geht es gar nicht.
>
Tut mir ja leid, wenn ich dein Weltbild erschüttern muss, aber damit
ein Pointer irgend etwas sinnvolles tut, muss er auf etwas zeigen.
Damit er das tut, muss er mit etwas anderem in eine Beziehung gesetzt
werden (wie in
np = node;
). Wenn er dann noch in einer Schleife 'np++' ausführen lässt,
passiert was? Die Zuordnung geht verloren, und wenn es kein
definiertes Ende gibt (und mir fiele kein Grund ein, warum sich ein
Mathematiker mit sowas wie Ende-Markern rumärgern sollte), dann ist
'np' irgendwas, von dem wir nix wissen.
Dahingegen stüzt sich ein Code wie
for (int i = 0; i <= sizeof array / sizeof array[0]; i++)
array[i] = i;
auf Informationen, die sowieso mitgeschleppt werden, und der
Mathematiker braucht sich keine Sorgen zu machen, dass er kein -1 im
Feld verwenden darf oder braucht, und wenn er keine negativen Zahlen
braucht, kann er sogar gleich das sign-bit entfernen und so die
Maximalzahl verdoppeln.
>
> [...]
>
>> Was wollte uns der Autor also sagen?
>
> 1 < 2 == 1
>
> Einfacher ist das, was weniger Teile hat.
Das stößt sich aber an der Lösungsstrategie "Teile und Herrsche". Und
die ist IMHO ganz gut (die objektorientierte Strategie ist davon ja
letztlich abgeleitet). Gut, es gibt für alles Grenzen: Es ist nicht
das Ziel, am Ende eigene Funktionen nur für die Multiplikation zu
schreiben, wenn das eigentliche Problem in der RSA-Verschlüsselung
besteht. Aber übertreiben kann man ja alles.
[...]
>>> Nein, er iteriert nicht über einen Zahlenbereich, der noch relativ
>>> leicht als der Bereich zu entziffern wäre, der die gültigen Indizes
>>> eines Feldes enthält, sondern über einen Speicherbereich, der bei der
>>> Startadresse eines Feldes anfängt und irgendwo da aufhört, wo mal eine
>>> -1 auftaucht. Sicher ist das einfacher für einen Anfänger...
>>
>> Ich hatte geschrieben, dass der Code einfacher sei und diese Aussage
>> sogar noch mehrfach erlaeutert, weil 'er benutzt eine Variable'
>> anstelle von 'er benutzt zwei Variablen' wohl in sich selbst nicht
>> auffaellig genug ist.
>
> Nun heißt die Verwendung von weniger Variablen nicht unbedingt, dass
> der Code einfacher wird.
Es ging hier um zwei konkrete Beispiel und nicht um 'alles beliebig',
was Du Dir auszudenken imstande bist.
[...]
>>>> C is unusual in that it allows pointers to point to anything.
>>>>
>>>> [...]
>>>>
>>>> Pointers have a bad reputation in academia, because they are
>>>> considered too dangerous, dirty somehow. But I think they are
>>>> powerful notation, which means they can help us express
>>>> ourselves clearly.
>>>>
>>>
>>> Klar, zwei Worte für den gleichen Begriff zu haben, ist für klare
>>> Ausdrucksweise unabdingbar. (s.o.)
>>
>> Dieser Rueckverweis ist 'dangling pointer': Bisher hattest Du nichts
>> geschrieben, wozu er passen wuerde. Um welchen Begriff geht es, welche
>> zwei Worte dafuer hast Du in oa Text gefunden und warum haelst Du sie
>> fuer vollkommen synonym?
>
> Nicht in dem Text! Es ging doch um Pointer. Damit Pointer etwas
> definitiv nützliches tun, müssen sie auf irgendwas zeigen, das wir
> schon definiert haben. Also ist ein Pointer nach der Initialisierung,
> solange wir ihn nicht verändern, ein Synonym für etwas, das wir schon
> definiert haben.
Das ist nicht relevant: Entscheidend ist nicht, wieviele andere
Ausdruecke man auch noch formulieren koennte, die denselben Wert wie
ein gegebener Ausdruck haben (unendlich viele), sondern wieviel
gleichbedeutende Ausdruecke im selben Codeabschnitt gleich benutzt
werden.
[...]
> Sicher gibt es nützliche Verwendungsmöglichkeiten von Pointern, aber
> gerade "klare Ausdrucksweise" gehört definitiv nicht dazu.
Weil? Bitte mit Bezug auf das Beispiel vom einfachen und komplexen
Ausdruck, die man alternativ verwenden kann.
>>>> Nothing about
>>>> the expression in isolation can show that i is a valid index
>>>> of node, let alone the index of the element we want.
>>>>
>>>> [http://www.lysator.liu.se/c/pikestyle.html]
>>>>
>>>
>>> Aha. 'node[i]' ist also schlechter als 'np', weil wir bei 'node[i]'
>>> nicht auf den ersten Blick sehen, ob das überhaupt die Zahl ist,
>>
>> 'schlechter' ist Dein Adjektiv. In dem von mir zitierten Text kam es
>> nicht vor.
>
> Das muss es auch nicht, denn es wurde durch seine Wortwahl
> impliziert.
Der Satz da oben ist von Dir geschrieben wurden und stellt meiner
Ansicht nach keine korrekte Zusfammenfassung der Aussage des
urspruenglich zitierten Textes da. Insbeondere ist er sehr viel
allgemeiner und benutzt emotional aufgeladenere Adjektive.
>> Dessen Aussage bezieht sich immer noch darauf, das node und
>> i zwei voneinander unabhaengige Variablen sind, die durch den Code,
>> der sich benutzt, in eine bestimmte Beziehung zu einander gesetzt
>> werden.
>
> Richtig, soweit stimmt es ja auch. Er sagt aber in dem von mir
> zitierten Teil, dass wir bei 'node[i]' nicht ohne Programmkontext
> sehen, dass wir die richtige Zahl erwischt haben.
Nein, das sagt er nicht. Er sagt, wie ich bereits mehrfach geschrieben
hatte, das node[i] ein komplexer Ausdruck ist, der zwei unabhaengige
Variablen enthaelt deren genaue Beziehung zueinander nur durch
Kenntnis des restlichen Codes ermittelt werden kann, waehrend das auf
den Ausdruck 'np' nicht zutrifft (das er aus mehreren, unabhaengigen
Groessen zusammengesetzt sei, die 'aus sich heraus' keine Beziehung
zueinander haben).
Es geht ueberhaupt nicht darum, ob der (einfache oder komplexe)
Ausdruck den Wert hat, den er nach Meingung von irgendjemand haben
sollte, sondern um die beiden Ausdruecke selber.
> Seine Wortwahl impliziert, dass er sagen will, dass das mit 'np'
> ginge. Geht aber nicht.
Offensichtlich Unsinnigkeit einer Interpretation bedeutet meistens,
dass sie falsch ist.
>>> Eine Frage an die Runde: Seht ihr bei 'np' alleine, dass es genau
>>> die Zahl ist, die wir haben wollen?
>>
>> Es ist ueberhaupt keine Zahl, sondern ein Zeiger auf ein Element eines
>> Feldes von Strukturen (wahrscheinlich).
>
> Ja, da haben wir es schon: Man weiß es nicht. Ich weiß auch nicht, was
> der Autor des von dir zitierten Textes also nun sagen wollte.
Das ist fuer den gebenenen Fall auch nicht wirklich von Belang. Der
Text sagt nur 'points to a node', dh er laesst den exakten Typ offen.
>> Dh es ist ein 'Ding', dessen Bedeutung verstanden werden muss,
>> anstelle von zweien, die in einer sich aus dem nicht gezeigten
>> anderen Code ergebenden Beziehung zueinander stehen. Um mehr geht
>> es gar nicht.
>>
>
> Tut mir ja leid, wenn ich dein Weltbild erschüttern muss, aber damit
> ein Pointer irgend etwas sinnvolles tut, muss er auf etwas zeigen.
> Damit er das tut, muss er mit etwas anderem in eine Beziehung gesetzt
> werden (wie in
>
> np = node;
>
> ).
Auch diese Interpretation (diesmal) meiner Aussage ist offensichtlich
unsinnig. Also ist sie wohl auch falsch. Ich schreibe naemlich immer
noch (und die ganze Zeit schon) von zwei Ausdruecken mit
unterschiedlichen Eigenschaften.
[...]
>>> Was wollte uns der Autor also sagen?
>>
>> 1 < 2 == 1
>>
>> Einfacher ist das, was weniger Teile hat.
>
> Das stößt sich aber an der Lösungsstrategie "Teile und Herrsche". Und
> die ist IMHO ganz gut (die objektorientierte Strategie ist davon ja
> letztlich abgeleitet).
Es geht auch weiterhin um genau zwei Ausruecke: np und node[i], von
denen einer ein komplexer Ausdruck ist (node[i]) und der andere nicht.
Ich fürchte, du willst mit dem Kopf durch die Wand. Gut, meinetwegen,
aber beschwere dich danach nicht, dass die Wand hart war.
Zurück zum Text: "Einfach" ist ein Adjektiv des persönlichen
Geschmacks, insofern könnten wir noch in zwei Jahren hier sitzen, und
uns bekriegen mit Bekundungen, was wir nun leichter finden und was
nicht.
> [...]
>>
>> Tut mir ja leid, wenn ich dein Weltbild erschüttern muss, aber damit
>> ein Pointer irgend etwas sinnvolles tut, muss er auf etwas zeigen.
>> Damit er das tut, muss er mit etwas anderem in eine Beziehung gesetzt
>> werden (wie in
>>
>> np = node;
>>
>> ).
>
> Auch diese Interpretation (diesmal) meiner Aussage ist offensichtlich
> unsinnig. Also ist sie wohl auch falsch. Ich schreibe naemlich immer
> noch (und die ganze Zeit schon) von zwei Ausdruecken mit
> unterschiedlichen Eigenschaften.
>
Äh... hä? Auch nach mehrmaligem Lesen (auch des Vorgeplänkels)
erschließt sich mir der Sinn dieses Absatzes nicht ganz. 'node[i]' ist
ein komplexer Ausdruck, ja, aber das hatten wir schon. Er ist deshalb
so komplex, weil zwei voneinander unabhängige Variablen, nämlich node
und i, in Beziehung gesetzt werden. Das wiederum passiert bei 'np'
nicht, so sagst du. Das kann aber nicht sein. Der einzige Unterschied
ist der Ort, wo die Beziehung aufgebaut wird: 'node[i]' steht in der
Schleife, der Pointer wird davor initialisiert. Darum wissen wir, um
noch mal zu dem Text von oben zurückzukommen, immer noch nicht, was
'np' jetzt in der Schleife genau ist. Es ist ein Pointer, ja, aber wo
zeigt er hin?
> [...]
>
>>>> Was wollte uns der Autor also sagen?
>>>
>>> 1 < 2 == 1
>>>
>>> Einfacher ist das, was weniger Teile hat.
>>
>> Das stößt sich aber an der Lösungsstrategie "Teile und Herrsche". Und
>> die ist IMHO ganz gut (die objektorientierte Strategie ist davon ja
>> letztlich abgeleitet).
>
> Es geht auch weiterhin um genau zwei Ausruecke: np und node[i], von
> denen einer ein komplexer Ausdruck ist (node[i]) und der andere nicht.
Ach, _jetzt_ verstehe ich, worum es dir geht: In der Nomenklatur des
C-Standards heißt 'node[i]' "Ausdruck", und du deklarierst den einfach
mal als komplex. Na gut, aber ich halte Pointer trotzdem für komplexer
als Ausdrücke.
[...]
> Zurück zum Text: "Einfach" ist ein Adjektiv des persönlichen
> Geschmacks,
Nein. Es ist begruendet definierbar und somit ist eine solche
Definition auch diskutierbar.
>>> Tut mir ja leid, wenn ich dein Weltbild erschüttern muss, aber damit
>>> ein Pointer irgend etwas sinnvolles tut, muss er auf etwas zeigen.
>>> Damit er das tut, muss er mit etwas anderem in eine Beziehung gesetzt
>>> werden (wie in
>>>
>>> np = node;
>>>
>>> ).
>>
>> Auch diese Interpretation (diesmal) meiner Aussage ist offensichtlich
>> unsinnig. Also ist sie wohl auch falsch. Ich schreibe naemlich immer
>> noch (und die ganze Zeit schon) von zwei Ausdruecken mit
>> unterschiedlichen Eigenschaften.
>>
>
> Äh... hä? Auch nach mehrmaligem Lesen (auch des Vorgeplänkels)
> erschließt sich mir der Sinn dieses Absatzes nicht ganz.
Der Sinn des obigen Absatzes erschliesst sich vermutlich niemandem,
denn es fehlt der Kontext, in dem er einen solchen hatte.
> 'node[i]' ist ein komplexer Ausdruck, ja, aber das hatten wir
> schon. Er ist deshalb so komplex, weil zwei voneinander unabhängige
> Variablen, nämlich node und i, in Beziehung gesetzt werden.
Er ist deshalb komplex, dh (ungefaehr) 'zusammengesetzt'. Das ist
nicht die Bedeutung, mit der Du diese Adjektiv benutzt, denn die waere
nicht steigerbar, 'so komplex' also eine Wortkombination ohne Sinn.
> Das wiederum passiert bei 'np' nicht, so sagst du. Das kann aber
> nicht sein.
Das ist aber einfach so. 'np' ist kein zusammengesetzer Ausdruck.
Ein nicht mehr ganz triviales Code-Beispiel (Entfernung von
ungueltigen Rueckwaertsreferenzen aus einem URL-Pfad) hantiert zB mit
fuenf unterschiedlichen Positionen innerhalb desselben Feldes, die in
einem Schleifenkoerper insgesamt 31 mal benutzt werden. Der Code
enthielte also bei Verwendung von Index-Ausdruecken anstelle der
Zeiger 62 zusaetzliche 'eckige Klammern', die damit die bei weitem am
haeufigsten auftretenden Zeichen waeren, ohne auch nur das
mindeste spezifische zur Bedeutung beizutragen. Hinzu kaeme noch
31 Mal der Feldname, der das auch nicht taete.
> Der einzige Unterschied ist der Ort, wo die Beziehung aufgebaut
> wird: 'node[i]' steht in der Schleife, der Pointer wird davor
> initialisiert. Darum wissen wir, um noch mal zu dem Text von oben
> zurückzukommen, immer noch nicht, was 'np' jetzt in der Schleife
> genau ist. Es ist ein Pointer, ja, aber wo zeigt er hin?
Weder 'node[i]' noch 'np' standen in dem von mir urspruenglich
zitierten Text in einer Schleife. Eine Aussage ueber die Gueltigkeit
des einen oder des anderen Ausdrucks ist aufgrund blosser Betrachtung
beider nicht moeglich. Damit ist eine Interpretations des 'let alone
the index we want' (Paraphrase) als offensichtlich unsinnige Aussage
ueber ebendiese Gueltigkeit in Anwesenheit einer anderen
Interpretationsmoeglichkeiten, naemlich, dass sich die Aussage auf das
genanntem, zwei unterschiedliche Ausdruecke, bezog, nicht sinnvoll.
Geeignet als Unsinn interpretieren kann man alles.
>> [...]
>>
>>>>> Was wollte uns der Autor also sagen?
>>>>
>>>> 1 < 2 == 1
>>>>
>>>> Einfacher ist das, was weniger Teile hat.
>>>
>>> Das stößt sich aber an der Lösungsstrategie "Teile und Herrsche". Und
>>> die ist IMHO ganz gut (die objektorientierte Strategie ist davon ja
>>> letztlich abgeleitet).
>>
>> Es geht auch weiterhin um genau zwei Ausruecke: np und node[i], von
>> denen einer ein komplexer Ausdruck ist (node[i]) und der andere nicht.
>
> Ach, _jetzt_ verstehe ich, worum es dir geht: In der Nomenklatur des
> C-Standards heißt 'node[i]' "Ausdruck", und du deklarierst den einfach
> mal als komplex.
Wie bereits geschrieben: Er ist komplex. Das ist nicht dasselbe wie
'kompliziert', was zugebenermassen eine sehr subjektive Kategorie
waere. Genau obige Aussage ('it is an expression') findet sich
auch in dem zitierten Text.
Eine (wenig massgebliche) persoenliche Erfahrung dazu waere zB, das
Zeiger- anstelle von Ausdrucksnotation es fuer mich einfacher macht,
Algorithmen, die mit unterschiedlichen, variablen Positionen
innerhalb eines oder mehrerer Felder arbeiten muessen, zu formulieren
und auch zu verstehen. Da wuerde ich jedem raten, es erst mal selber
zu versuchen, bevor man es als unwesentlich abtut. Jedenfalls war das
auch das Vorbild fuer die generalisierten Iteratoren, die zB C++
anbietet.