Guten 'Abend allerseits,
Wie verhält sich das
oder noch besser, was mache ich hier verkehrt oder übersehe es:
Aus einer main heraus rufe ich eine funktion auf mit rückgabe:
1
voidmain(void){
2
3
printf("Main: %s\r\n",machwas("was geht ab"));
4
5
}
6
7
// in der Funktion bastle ich an der übergebenen Variablen
8
// und irgendwie scheint diese dann nicht immer den richtigen Wert
9
// zu haben
10
11
char*machwas(char*daten){
12
13
printf("Main->Func: %s\r\n",daten);
14
15
// ein paar sachen über andere funktionen...
16
// ..
17
18
19
returndaten;
20
21
}
Wie lange lebt eigentlich die übergebene Variable *daten as char ?
Um welche Variable handelt es sich dabei, wenn diese nicht als Locale
oder Globale Variable deklariert wurde und nur im Funktionsaufruf
vereinbart ist?
Da ich nicht sicher bin, würde ich das dann so machen, und die Variablen
abgrenzen, ist das besser:
1
char*machwas(char*daten){
2
3
char_localdaten[24]={0};// übergabe wird nie über 20 sein..
4
5
memcpy(_localdaten,daten,strlen(daten));
6
7
8
printf("Local -> Func: %s\r\n",_localdaten);
9
10
// return _localdaten; meckert der compiler weil man eine locale Adresse..
11
12
// daher:
13
14
memcpy(daten,_localdaten,strlen(_localdaten));
15
16
returndaten;
17
18
19
}
Ist das nicht alles irgendwie doppelt gehoppelt?
Und welche Priorität nimmt die in der Funktionübergabe deklarierte
Variable (daten) ein? Ist das eine Locale Variable der Main die
übergeben wird?
Danke schon jetzt für Tips!
daten lebt solange die Funktion ausgeführt wird.
A b e r: daten ist ein Zeiger auf eine Zeichenkette. Somit enthält
daten eine Adresse.
Diese Adresse übergibst du ja (als Kopie) von außerhalb der Funktion.
Demnach ist auch diese Adresse noch nach beenden der Funktion gültig.
In C gibt es nur Call by Value. Das was als Call by Reference bezeichnet
wird, ist nur eine Werteübergabe (Kopie) von Adressen.
Das was du da rumkopierst ist Schwachsinn und bringt gar nichts.
Da liegt ein Mißverständnis vor, dass ich mir aber auch nicht so recht
erklären kann.
Denn in der Funktionsdeklaration und Definition vereinbarst Du
"Parameter" und keine "Variablen". Näheres erklärt ein C Buch.
Der Unterschied ist nicht leicht allgemein zu erklären, denn er hängt
von den Implementierungs- und Maschinendetails ab.
Setze einmal voraus, dass globale Variablem im RAM und lokale Variablen
(bei statics ist das ein wenig anders) auf dem Stack abgelegt werden.
Ein solche Maschine wird oft auch Parameter auf dem Stack ablegen.
Nimm einmal an, dass es sich um eine Zahl, die als Literal übergeben
wird. Sie hat bei ihrem Übergabe an die Funktion keinen eigenen
Speicherplatz und erhält ihn (abgesehen von anderen Faktoren in dem
Zsh.) nur für die Zeit, in der die Funktion abgearbeitet wird.
Insbesondere sind Änderungen an dem Parameter nach verlassen der
Funktion nicht mehr sichtbar. Sonst müsste sich ja das Literal ändern.
Bei einer int-Variablen ist das sogar genauso. Sie wird zeitweise auf
dem Stack kopiert, kann auch verändert werden, behält aber ihren Wert
nicht (Falls kein Zeiger bzw. eine Referenz vorliegt).
Bei einem String ist das im Prinzip gleich. Nur wird hier (sehr häufig)
ein Zeiger auf die Zeichenkette übergeben. Dieser Zeiger zeigt, je nach
Maschine auf einen Bereich im Programmspeicher (bei Flash-Basierten
Harvard-Architekturen ist das oft so) oder im RAM (bei RAM-basierten
von-Neumann Maschinen ist das oft so). Je nach Fall steht dort also (das
ist im C-Standard so festgelegt) ein Zeiger auf einen Bereich, den Du
formal gesehen nicht verändern kannst - in der Realität, d.h. wenn Du
was falsch machst, aber manchmal doch. Das selbe gilt für den Bereich
auf den der Zeiger zeigt.
Es bleibt aber die Tatsache, das Du ursprünglich ein Literal übergeben
hast, eine Art Konstante (obwohl das begrifflich nicht ganz das selbe
ist, kann man es doch vergleichen). Die kannst Du per Definition nicht
ändern. Warum würdest Du ein Literal verwenden wollen, falls Du es
ändern wolltest?
D.h. Dein Code ist schon im Ansatz falsch, denn
1. Willst Du einen Parameter verändern (die Übergabe eines Zeigers bei
Strings ist ein impliziter Vorgang der sich aus der Sprachdefinition
ergibt, von dem Du keinerlei Nutzen hast)
2. Willst Du ein Literal ändern - was in sich schon widersinnig ist.
Dirk B. schrieb:> Das was du da rumkopierst ist Schwachsinn und bringt gar nichts.
Jep, zumal es eh schon fraglich ist was es überhaupt bringen soll eiene
Pointer den man einer Funktion übergeben hat als Rückgabewert wieder
zurückzugeben wenn dieser sich innerhalb der Funktion überhaupt nicht
verändern kann.
Die andere Frage wäre warum:
memcpy(_localdaten,daten,strlen(daten));
Wenn das ganze eine String sein soll wäre doch eigentlich folgendes
angebracht:
strcpy(_localdaten, daten);
Spart den zusätzlichen Funktionsaufruf für strlen
Ähem. Nicht das ich da wen irreführe. Bei Flash-basierten Harvards
werden Strings eher in das RAM kopiert. Das erspart dem Compiler Arbeit
in dem er Funktionen nicht so stricken muss das sie sowohl mit Zeigern
ins Flash als auch mit Zeigern ins RAM klarkommen muss.
Was ich oben darüber geschrieben ist also falsch. Aber an der
Grundaussage ändert sich dadurch nichts.
Irgendwer schrieb:> Jep, zumal es eh schon fraglich ist was es überhaupt bringen soll eiene> Pointer den man einer Funktion übergeben hat als Rückgabewert wieder> zurückzugeben wenn dieser sich innerhalb der Funktion überhaupt nicht> verändern kann.strcpy und strcat machen es auch so. Der Wert vom destination wird
auch nicht verändert, das worauf er zeigt schon.
http://www.cplusplus.com/reference/cstring/strcpy/
Das kann man gebrauchen, wenn man das Ergebnis gleich wieder an eine
Funktion übergibt.
Dirk B. schrieb:> Irgendwer schrieb:>> Jep, zumal es eh schon fraglich ist was es überhaupt bringen soll eiene>> Pointer den man einer Funktion übergeben hat als Rückgabewert wieder>> zurückzugeben wenn dieser sich innerhalb der Funktion überhaupt nicht>> verändern kann.>> strcpy und strcat machen es auch so. Der Wert vom destination wird> auch nicht verändert, das worauf er zeigt schon.> http://www.cplusplus.com/reference/cstring/strcpy/
Für denn Fall hast du natürlich recht
>> Das kann man gebrauchen, wenn man das Ergebnis gleich wieder an eine> Funktion übergibt.
Habe es mir gerade nochmal angeschaut und erst dabei gesehen das es die
"daten" hier zweimal ausgegeben werden sollen.
"Innerhalb" einer printf nochmal eine andere printf aufrufen ist schon
etwas sehr verwirrend (und um so fraglicher was der Salat soll und ob
überhaupt genau definiert ist welche zu welchem Zeitpunkt ausgeführt
wird).
Irgendwer schrieb:> (und um so fraglicher was der Salat soll und ob> überhaupt genau definiert ist welche zu welchem Zeitpunkt ausgeführt> wird).
Was soll darin unklar sein?
Erst werden die Parameter berechnet und dann kann die Funktion (das
printf) aufgerufen werden
Bei
1
printf("Main: %s %s\r\n",machwas("was geht ab"),machwas("Mann!"));
wäre unklar, in welcher Reihenfolge das
"Main->Func: was geht ab" und das "Main->Func: Mann!" ausgegeben wird.
Das "Main: was geht ab Mann!" ist jedenfalls zu Schluss dran.
Danke bisher.
Das Problem, warum ich die kopiererei versuchte in der Funktion war,
ich habe mit der Variablen 'daten' in der Funktion verschiedene Sachen
probiert, und es waren auf Anhieb unterschiedliche Werte in
verschiedenen
weiteren Verarbeitungen.
Mal genauer:
In der Main habe ich den Funktionsaufruf
1
printf("Main: %s\r\n",machwas("was geht ab"));
OK soweit.
Ich habe einen weiteren Funktionsaufruf in der machwas Funktion
eingebaut
die mir für jedes Char den HEX Wert liefert, dazu habe ich Achtung :)
sizeof(daten) verwendet für die Anzahl der Zeichen in Daten. 'auweia'
Das war glaube ich genau der Gedankenfehler. Der mich dann zu der
Kopiererei veranlasste.
Den der weitere Funktionsaufruf geht von einer normalen Variablen aus,
bei der Kopiererei hatte ich ja in der Funktion dann
1
char_localdaten[24]={0};// übergabe wird nie über 20 sein..
24 Zeichen als Puffer, und die 20 Zeichen die ich wollte, wurden mir
dann auch als HEX in der zweiten Funktion richtigerweise angezeigt, nur
die Weitergabe der Variable 'daten' an die Hex Funktion brachte mir nur
4 Zeichen bzw 8 Hexzahlen.
Dann wurde ich stutzig und unsicher, wie man es nun richtig macht, oder
ob die Variable 'daten' nur kurzlebt oder..
Wie ich drauf kam :
Wenn ich in der Funktion einen Testaufruf mache
- sizeof(daten)
liefert der mir 'nur' 4 Byte, denke dass es eben nur eine Pointer
Variable ist, die mit 4 Byte dasteht, richtig?
Der Funktion machwas wird ja als Parameter der Pointer ( Adresse ) des
String "was geht ab" übergeben, PointerVariable ist jetzt doch 'daten'
oder? Müsste doch so sein.
Was mich dann irretiert hatte, ist, dass wenn ich aus der Funktion
rausgehe, also return daten an die main zurück gebe, dann habe ich
meinen kompletten String wieder.
Und ich dachte 'daten' ist nicht gleich 'daten' und habe die kopiererei
in der Funktion angefangen,
und das klappte dann sizeof(_Localdaten) lieferte ja dann genügend
zeichen .
Ich habe anstatt sizeof(daten) jetzt strlen(daten) in der Funktion,
jetzt liefert es auch anstatt 4
Die kopiererei habe ich jetzt wieder entfernt.
Solved ;-)
Ok, meine Anschlussfragen:
Diese 'variable' daten ist dann also nach dem Funktionsaufruf wieder
weg?
Hab ich das richtig verstanden? Der Speicherplatz wird dann wieder frei
gegeben?
Ist das eine richtige Vorgehensweise so oder eine Speicher
Verschwendung? Kann / soll man ( habe etwas vorgelesen ) mit maloc()
dann bewusst einen Bereich einrichten oder ist das was die Funktion mit
der Variablen macht, in etwa das gleiche oder sogar besser?
Vielen Dank bisher! Es waren wieder einige Sachen dabei, die mir hier
und da wieder einen Denkanstoss lieferten, danke!!
Den Link kenne ich Fragezeichen - danke - direkte Worte und Tips sind
aber manchmal hilfreicher -
c schüler schrieb:> - sizeof(daten)> liefert der mir 'nur' 4 Byte, denke dass es eben nur eine Pointer> Variable ist, die mit 4 Byte dasteht, richtig?
Ja, steht so in jedem Lehrbuch über C.
> Ok, meine Anschlussfragen:>> Diese 'variable' daten ist dann also nach dem Funktionsaufruf wieder> weg?
Ja, die Variable daten (von der Funktion) ist dann weg.
> Hab ich das richtig verstanden? Der Speicherplatz wird dann wieder frei> gegeben?
Ja, der von dem Pointer ( die 4 Byte), aber nicht der Bereich, auf den
daten zeigt.
> Ist das eine richtige Vorgehensweise so oder eine Speicher> Verschwendung? Kann / soll man ( habe etwas vorgelesen ) mit maloc()> dann bewusst einen Bereich einrichten oder ist das was die Funktion mit> der Variablen macht, in etwa das gleiche oder sogar besser?
Ich weiß jetzt nicht, worauf du dich beziehst. Aber nochmal:
Das mit dem malloc und _localdaten ist in diesem Fall Schwachsinn.
Aber noch etwas anderes. Du übergibst an machwas ein Stringliteral
(Text in Anführungszeichen). Diesen darfst du nicht verändern, da er in
einem Speicherbereich liegt, der nur zum lesen da ist.
Bei einem Array sieht das anders aus.
Vielen Dank!
Dirk B. schrieb:>> Hab ich das richtig verstanden? Der Speicherplatz wird dann wieder frei>> gegeben?> Ja, der von dem Pointer ( die 4 Byte), aber nicht der Bereich, auf den> daten zeigt.
Hallo Dirk, der Bereich in dem die Daten stehen ( also in dem Fall das
Stringliteral) nimmt dann ja 20 zeichen Platz ein, wird dieser Platz
später wieder von anderen daten genutzt und verwendet oder ist das
'verlorener' Speicherbereich, könnte/muss man diesen "Speicherbreich"
wieder freigeben? Oder braucht man sich darum nicht zu kümmern?
>> Aber noch etwas anderes. Du übergibst an machwas ein Stringliteral> (Text in Anführungszeichen). Diesen darfst du nicht verändern, da er in> einem Speicherbereich liegt, der nur zum lesen da ist.> Bei einem Array sieht das anders aus.
Array ist das Stichwort, so soll es später werden.
Das mit dem direkten Übergeben war jetzt einmal ein Beispiel.
Später sollte das in etwa so aussehen ( theroretisch - sind bestimmt
noch Denkfehler drin ) :
Meine Fragen wären dann, ob ich das so machen kann, oder ob ich einen
Pointer vereinbaren muss. Ich hab das nachfolgende noch nicht probiert,
rein theoretisch gedacht:
1
voidmain(void){
2
3
char*ptr;
4
chardaten[20]={0};
5
ptr=&daten;
6
7
dump(*ptr);
8
9
}
10
11
12
13
voiddump(*ptr){
14
15
inti;
16
17
for(i=0;i<strlen(ptr);i++)printf("%02x ",ptr[i]);
18
19
}
Oder ist das eigentlich nicht notwendig, da im ersten Funktionsparameter
1
dump(*ptr);
das gleiche rauskommt wie
1
dump(char*daten);
Mein Anliegen:
Diese 'daten' werden in verschiedenen Funktionen immer wieder dazu
benutzt, weiter zu verarbeiten, zu ändern. Wäre es da gescheiter eine
Globale Variable und einen Globalen Pointer darauf einzurichten, auf die
dann jede Funktion zugreifen kann?
Dirk B. schrieb:> Aber noch etwas anderes. Du übergibst an machwas ein Stringliteral> (Text in Anführungszeichen). Diesen darfst du nicht verändern, da er in> einem Speicherbereich liegt, der nur zum lesen da ist.
Und deshalb gibt der Compiler da eine Warnung aus, wenn ihm das nicht
irgendwer verboten hat. Weil die Funktion machwas als Parameter einen
Zeiger auf char sehen will, also auf Zeichen, die man auch
überschreiben darf, und stattdessen einen Zeiger auf const char
bekommt.
Wenn die Warnung nicht kommt, ist irgendwas an den Compileroptionen
verdreht. Reparier' das, das macht dir sonst noch viel Ärger.
c schüler schrieb:> Hallo Dirk, der Bereich in dem die Daten stehen ( also in dem Fall das> Stringliteral) nimmt dann ja 20 zeichen Platz ein, wird dieser Platz> später wieder von anderen daten genutzt und verwendet oder ist das> 'verlorener' Speicherbereich, könnte/muss man diesen "Speicherbreich"> wieder freigeben? Oder braucht man sich darum nicht zu kümmern?
Er wird nicht genutzt. Du musst ihn nicht wieder freigeben.
Er ist auch nicht verloren, weil du die Daten ja gebraucht hast.
Irgendwo muss der Text ja stehen.
c schüler schrieb:> char *ptr;> char daten[20] = {0};> ptr = &daten;
Der Name vom Array (ohne weiter Zusätze) ergibt die Anfangsadress vom
Array und ist vom Typ Zeiger auf Arraytyp. (hier Zeiger auf char)
Mit dem Adressoperator bekommst du aber einen Zeiger auf das Array (hier
Zeiger auf char[20].
Das ist vom Zahlenwert dasselbe, aber trotzdem etwas anderes.
Darum:
ptr = daten;
oder
ptr = &daten[0];
Überleg mal, was bei deinem Beispielen rauskommt, wenn daten selber ein
Pointer ist.
Das ergibt die Speicheradresse vom Pointer selber. Die willst du hier
aber gar nicht haben.
> void dump(*ptr) {>> int i;>> for (i=0; i<strlen(ptr); i++) printf("%02x ",ptr[i]);>> }
Was soll er ausgeben?
In deinem Beispiel nichts, da strlen 0 ergibt.
Wenn du 20 mal die 00 sehen willst, musst du die Länge als extra
Paramter mit übergeben.
c schüler schrieb:> Danke bisher.
Gerne.
> Ok, meine Anschlussfragen:
Ich bitte Dich erst einmal Dein C-Buch in Hinblick auf die Festlegung,
was ein Parameter bzw. eine Variable ist und die damit in Zusammenhang
stehenden Fragen, zu lesen. Damit wird einiges klarer.
Der wichtigste Unterschied zwischen Variable und Parameter ist, dass mit
dem Parameter ein sprachliches Mittel geschaffen ist, die Beziehung
zwischen einer Variable ausserhalb der Funktion und ihrem Wert bzw.
ihrem Speicherort innerhalb der Funktion herzustellen.
Eine Variable hat diese Eigenschaft nicht. Sie sagt nichts über sich
selbst aus, als das ein benanntes Ding besteht, das seinen Inhalt und
jede Veränderung daran (im wesentlichen) permanent, während des gesamten
Programmlaufes, behält.
Ein Parameter behält seinen Wert nicht während des gesamten
Programmlaufes, sondern nur während die die Funktion läuft, für die er
deklariert ist.
Das ist vereinfacht. Denn es gibt eine Reihe von Sonderformen sowohl von
Variablen als auch Parametern. Im Programmtext werden sie mit "type
modifiern" bzw. "Typ-Modifizierern" beschrieben.
Auch hängt die Anwendbarkeit von gewissen Begriffen hier von der
Maschine ab. So kann der Wert eines Parameters durchaus in einem
"Register" gespeichert sein, was einerseits technologisch ein Speicher
ist, aber andererseits, formal (z.B. im C-Standard) nicht zu den
Speichern, also nicht zum Programm oder Datenspeichern gezählt wird.
Der Stack selbst liegt (natürlich) im RAM, wird aber im Kontext der
C-Programmierung nicht zu den Speichern gezählt.
Der Begriff "Speicher freigeben" hat eine viel speziellere Bedeutung im
C-Standard, als Du sie hier verwendest (zufällig gerade malloc/free).
Abstrakt hast Du recht, formal aber nicht.
Überhaupt zählt viel von den Speicher-Fragen zu den sogenannten
"Implementierungsdetails", die Dich im Moment vermutlich eher verwirren,
als weiterbringen.
Ich lese sogar in dem (deutschen) Wikipedia-Artikel, dass Parameter als
eine Unter-Klasse von Variablen bezeichnet werden. Es ist nicht völlig
falsch das zu schreiben und gibt eine gute Einführung in den Begriff,
aber es führt, wie bei einem Anfänger wie Dir zu der Annahme, dass sie
grundsätzlich beständig sind; und im Zusammenhang mit der Verwendung mit
Literalen, dazu, dass für jedes Daten-Element gelten, dass 'direkt'
(Literal) oder indirekt (Variable, Parameter) ein Datum beschreibt,
beliebig manipulierbar. So ist das aber nicht richtig. Und zwar nicht
nur ungefähr falsch sondern völlig. :-)
Der Wikipedia-Artikel stellt diese Verallgemeinerung dann wieder in die
richtigen Zusammenhänge und gibt eine recht gute Übersicht über die
wichtigen Aspekte, so dass ich Dir rate, ihn zu lesen. Was Du nicht
verstehst überlies einfach erstmal und lese ihn immer wieder mal. Du
wirst im Laufe der Zeit (insbesondere wenn Du mehrere Sprachen gelernt
hast) wie er immer verständlicher wird.
Es ist vielleicht ratsam, wenn Du das Thema vorerst nur nach seinen
Erscheinungen auffasst, das C-Buch weiter liest und so nach und nach
lernst, was der Unterschied in der Definition und der funktionale
Unterschied ist.
Tut mir leid, wenn ich das nicht in kurzen Worten erklären kann. Ich
wünsche dennoch viel Erfolg.
Deine Frage hier:
Beitrag "Re: c code: Priorität & Lebensdauer Variable im Funktionsaufruf"
fokussiert das Ganze ein bisschen mehr, finde ich, weswegen ich
versuchen will noch einmal zu antworten.
1. Es ist ein Unterschied, ob Du auf die Werte eines Parameters nur
lesend zugreifst oder sie verändern willst. Lesend geht immer ohne
Probleme. Schreibend in erster Näherung nur mit Wirkung innerhalb der
Funktion selbst. Es gibt allerdings in C Sprachmittel um Daten, die als
Parameter (eigentlich Argument) übergeben wurden auch ausserhalb der
Funktion zu erhalten (Call by Value, Call by reference)
2. Du würdest Dir das lernen vielleicht vorerst etwas einfacher machen,
wenn Du annimmst, dass Du genau das machen darfst was im Standard steht
und alles andere nicht. Ob und was da wie wann gespeichert wird und wann
unter welchen Umständen nicht mehr, ist "implementierungsabhängig". Nimm
die Eigenschaften wie Beständigkeit etc. einfach nur nach Ihren
Erscheinungen und den Regeln für ihre Verwendung und vorerst nicht nach
dem, was auf der Maschine passiert.
Dirk B. schrieb:> c schüler schrieb:>> char *ptr;>> char daten[20] = {0};>> ptr = &daten;> Der Name vom Array (ohne weiter Zusätze) ergibt die Anfangsadress vom> Array und ist vom Typ Zeiger auf Arraytyp. (hier Zeiger auf char)>> Mit dem Adressoperator bekommst du aber einen Zeiger auf das Array (hier> Zeiger auf char[20].> Das ist vom Zahlenwert dasselbe, aber trotzdem etwas anderes.>> Darum:> ptr = daten;> oder> ptr = &daten[0];>> Überleg mal, was bei deinem Beispielen rauskommt, wenn daten selber ein> Pointer ist.> Das ergibt die Speicheradresse vom Pointer selber. Die willst du hier> aber gar nicht haben.
Ok, ich blätter das Kapitel noch mal zurück, denke dass ich den Ansatz
von Dir verstanden habe..
>>> void dump(*ptr) {>>>> int i;>>>> for (i=0; i<strlen(ptr); i++) printf("%02x ",ptr[i]);>>>> }> Was soll er ausgeben?> In deinem Beispiel nichts, da strlen 0 ergibt.> Wenn du 20 mal die 00 sehen willst, musst du die Länge als extra> Paramter mit übergeben.
Hast Recht - ja - das war jetzt nicht sonderlich elegant von mir ;-)
1
voidmain(void){
2
3
chardaten[21]="Beispieltext 20 lang\0";// Karl Heinz sagte das mal
4
// ein zeichen mehr einplanen
5
// für \0 bei Strings
6
7
..
Das andere werde ich nochmal durch und abarbeiten, danke bisher!!
btw: Die Compiler Meldung hatte ich tatsächlich.
Danke Klaus, ich blättere schon - mir ist es wichtig die richtige
Bezeichnung sprachlich zu verwenden, damit man das auch beschreiben
kann,
was man wissen will. Ein paar Sachen sind mir jetzt schon viel
verständlicher, ein paar andere schmeisse ich noch kreuz und quer
zusammen, aber ich sehe Licht in dem Tunnel :) vielen Dank für Eure Tips
und Eure Zeitinnahme für 'unsere' 1000 fach gestellten Anfänger Fragen.
Danke! ;)
c schüler schrieb:> void main(void) {>> char daten [21] = "Beispieltext 20 lang\0"; // Karl Heinz sagte das mal> // ein zeichen mehr> einplanen> // für \0 bei Strings
Karl Heinz hat recht, aber der Compiler ist so schlau, dass er bei
Stringliteralen automatisch eine '\0' anhängt.
Die musst du nicht explizit angeben.
Du musst nur daran denken, dass sie da ist. Bei strlen wird sie nicht
mitgezählt.
Ausserdem kann der Compiler auch automatisch die Länge vom Array
bestimmen:
char daten [] = "Beispieltext 20 lang";
Und da kannst du dann auch den Unterschied zwischen sizeof() und
strlen() nehmen
sizeof(daten) liefert hier die Größe vom Array, egal wieviel drin steht.
Das geht, weil daten hier ein Array ist und kein Pointer.
Klaus schrieb:
Ich weiss nicht so recht was du da schreibst
> Ich lese sogar in dem (deutschen) Wikipedia-Artikel, dass Parameter als> eine Unter-Klasse von Variablen bezeichnet werden. Es ist nicht völlig> falsch das zu schreiben
Ich würde sogar sagen, das ist völlig richtig.
Ein Parameter einer Funktion ist eine Variable, genauso wie eine lokale
Variable eine Variable ist. Vom Scope und der Lebensdauer her gibt es da
keinen Unterschied.
Der einzige Unterschied besteht darin, dass einer Parameter-Variable der
Wert, der sich aus dem Argument des Aufrufers ergibt, während des
FUnktionsaufrufs zugewiesen wird.
Gerade in C gibt es überhaupt keinen Zusammenhang zwischen einem
Parameter und dem was der Aufrufer benutzt hat, um dem Parameter seinen
Wert beim Funktionseintritt zu verpassen. Das Argument der Aufrufers
wird ausgewertet, sein Wert festgestellt, eine neue Variable mit dem
Namen des Parameters in der Funktion erzeugt, der Wert zugewiesen. Das
wars. Ist die Funktion beendet, verschwindet die Parameter-Variable
wieder aus dem Speicher, so wie jede andere lokale Variable auch. Das
allerdings beeinflusst wiederrum nicht das Argument, welches zum Aufruf
benutzt wurde. Denn das gehört ja nicht zur Funktion sondern zum
Aufrufer. Zwischen den beiden, Argument und Parametervariable, gibt es
keinerlei Verknüpfung, ausser das während des Aufrufs der Wert des einen
benutzt wird, um ihn dem anderen zuzuweisen. Aber abgesehen davon sind
die beiden völlig unabhängig voneinander.
Ich gebe zu, dass man bei Pointer etwas verwirrt sein kann. Schliesslich
benutzt man Pointer um damit in C ein Konzept zu implementieren. Aber
eigentlich läuft das technisch auch nicht anders ab. Das Argument des
Aufrufers wird ausgewertet, nur ergibt sich in diesem Fall eben eine
Speicheradresse. Diese Speicheradresse wird der Parametervariablen der
FUnktion während des Aufrufs zugewiesen. Nach Beendigung der Funktion
vershwindet die Pointer-Variable wieder im Nirwana. Technisch gesehen
ist da also auch nichts anderes abgelaufen.
Nur dass mir diese übergebene Adresse jetzt auch Zugang zu
Speicherbereichen verschafft, die nicht im Dunstkreis der Funktion
liegen.
Es ist wie ein Zettel Papier, den ich dir gebe und auf dem die Adresse
des Kölner Doms steht. Wenn du mit dem Streichen des Doms fertig bist
(viel Spass), dann zerknüllst du den Zettel und verbrennst ihn. Der
Zettel und damit die Adresse ist vernichtet. Aber deswegen verschwindet
ja der Dom nicht magisch.
c schüler schrieb:>> Danke Klaus, ...
Bitte. Ich vermute allerdings, dass ich Dir nicht wirklich viel helfen
konnte.
> ... ich blättere schon
Ich selbst habe vor, nunmehr über 30 Jahren, 14 Tage frei genommen, bin
weggefahren und habe es mir mit dem "K&R" (dem, nach den Autoren und
Spracherfindern Kernighan und Ritchie so genannten Buch) und einem
Getränk bequem gemacht. Einen Computer habe ich erstmal garnicht
angefasst.
Ich hatte Vorkenntnisse in Assembler und hatte mir zuvor die
Funktionsweise von Interpretern (Commodore-Basic) anhand von Listings
und mit dem Debugger und, zumindest in der Theorie, die von Compilern
angeschaut. Die wesentlichsten Fälle der tatsächlichen Implementierung
von Variablen, Stack und Parameter waren mir zum Teil real, zum Teil
theoretisch bekannt. Gute Kenntnisse in Elektronik und Digitaltechnik
sowie boolescher Algebra waren vorhanden.
Ich fürchte allerdings, diese Schritte werden heutzutage gerne
übersprungen, was dann die Verständnisprobleme eher verwickelter macht.
Ich habe es mir in gewisser Weise wesentlich einfacher gemacht.
Viel Erfolg dennoch :-)
> - mir ist es wichtig die richtige> Bezeichnung sprachlich zu verwenden, damit man das auch beschreiben> kann,> was man wissen will.
Das finde ich gut. Man kann gar nicht genug betonen, dass der
wesentliche Punkt in der Technik (wie in der Kunst) die bildliche und
textuelle Darstellung ist. Programmiersprachen sind "Sprachen". Sie
haben ihre Bereich in denen sie "exakt" definiert sind, ihre
Zweifelsfälle und versteckten schmutzigen Ecken.
"Erbsenzählen" gehört dazu. Und es macht Spass.
> Ein paar Sachen sind mir jetzt schon viel> verständlicher, ein paar andere schmeisse ich noch kreuz und quer> zusammen, aber ich sehe Licht in dem Tunnel :)
Schön. Das ist wie mit allen Fähigkeiten. Sie wachsen mit dem Lernen und
- ganz wichtig - mit der Erfahrung. Das schaffst Du, wenn Du immer
fleissig bist.
> vielen Dank für Eure Tips> und Eure Zeitinnahme für 'unsere' 1000 fach gestellten Anfänger Fragen.>> Danke! ;)
Naja. Du hast Dich, nach meinem Eindruck, bemüht Dein Problem klar
darzustellen, es schien mir erkennbar, dass Du von dem Thema gewisse
Kenntnisse erworben hast und Du hast konkreten Code vorgelegt - bist
also wirklich selbst am arbeiten. Darüber hinaus hast Du Dich höflich
und bescheiden verhalten. Das manches unkorrekt oder ungeschickt
ausgedrückt ist, liegt in der Natur des Lernprozesses.
Also dann ...
sizeof - strlen
Eine andere Möglichkeit, da noch etwas Klarheit reinzubringen, ist es,
sich zu verinnerlichen, dass sizeof eine Compile-Time Sache ist. D.h.
hier wertet der Compiler bereits den Ausdruck aus und bestimmt den sich
daraus ergebenden Zahlenwert. Dieser Zahlenwert ist aber fix - ein
einziger Zahlenwert.
D.h. es wäre nicht möglich in
1
voidfoo(char*txt)
2
{
3
machirgendwasmitsizeof(txt)
4
}
5
6
intmain()
7
{
8
foo("Hallo Welt");
9
foo("juhu");
10
}
innerhalb von foo mit einem einzigen Zahlenwert hochzukommen. Denn bei
dem einen Aufruf müsste ja 10 (oder 11, je nach Betrachtung) rauskommen
und beim zweiten Aufruf 4 (oder 5). Aber welches ist denn das richtige
Ergebnis? Der Compiler kann das klarerweise gar nicht bestimmen.
Die richtige Sichtweise ist es natürlich, dass foo losgelöst vom Aufruf
zu betrachten. sizeof liefert die Speichergrösse dessen, was ich ihm
vorwerfe. Was werfe ich ihm den vor? Na die Variable txt. Und die hat
natürlich eine Speichergröße. Die ist eine Pointervariable und als
solche liefert sizeof natürlich die Größe eines Pointers auf diesem
System. Hier konkret 4 Bytes.
Mehr geht nicht und mehr kann man auch nicht erwarten, wenn der Compiler
einen sizeof während des Compilierens zu einem Zahlenwert auswerten
soll.
(Disclaimer: ja ich weiss, mit den Möglichkeiten von C99 ist sizeof
nicht mehr nur eine reine Compiler-Time Sache. Aber lasst uns jetzt die
Dinge nicht komplizierter machen als notwendig)
Um also die Textlänge des Textes zu bestimmen, auf den die
Pointer-Variable verweisst, muss man auf den Text selber durchgreifen.
Ist ja auch kein Problem. Die Variable txt verrät uns ja, wo der Text im
Speicher liegt. Und dann braucht es natürlich einen Mechanismus, der zur
Laufzeit des Programms die Textlänge feststellt. Damit landen wir genau
bei strlen, denn genau das ist seine Aufgabe. Gib ihm die Adresse, und
strlen klappert den Text ab und stellt fest, wie gross er ist.
Um das Beispiel von weiter oben aufzugreifen.
Wenn ich dir den Zettel mit einer Adresse gebe (es sind standardisierte,
immer gleich grosse Zettel), dann würde ein sizeof die Fläche des
Zettels liefern. Diese Zahl mag zwar auch für so einiges verwendbar
sein, aber um die Menge an benötigter Farbe festzustellen, ist es
untauglich. Da musst du schon das Objekt selber betrachten, dessen
Adresse ich dir aufgeschrieben habe. Das ist aber nicht das, was sizeof
macht. Wenn ich aber vor dem Dom stehe, dann kann ich mich fragen, was
denn eigentlich die sizeof vom Dom ist. Nur: Ich gebe dir ja nicht den
Dom selber, wenn ich dir den Auftrag erteile. Ich gebe dir ja einen
Zettel, auf dem die Adresse des Objekts steht (zum Beispiel die des
Doms. Ich könnte dir aber auch die Adresse der Frauenkirche in München
aufschreiben). Das ist ein kleiner aber feiner Unterschied. Ich hantiere
direkt mit dem Objekt. Du hingegen hantierst über den Umweg, dass du
erst mal nur die Adresse auf einem Zettel hast. Um dessen Größe
festzustellen bleibt dir nichts anderes übrig, als mit Zollstock und
Massband loszuziehen und es zu vermessen.
Karl Heinz schrieb:> Klaus schrieb:>> Ich weiss nicht so recht was du da schreibst
Ich will Dich nicht einfach abbügeln, insbesondere da ich der Ansicht
bin, dass Du viele Kenntnisse hast, die Du auch verständlich darstellen
kannst.
Deine Formulierung des ersten Satzes ist allerdings recht sallop und
suggeriert mir in gewisser Weise und vor dem Hintergrund meines ersten
Satzes, dass ich irgendwie völlig falsch liege. Du hast mich in diesem
Forum von einigen Irrtümern befreit und mir manches Neue nahe gebracht.
Das ist wahr. Andererseits habe ich in einigen anderen Threads
festgestellt. dass meine Sichtweise und/oder Darstellung von Deiner
abweicht, obwohl es um den selben objektiven Fakt ging.
Zum einen möchte ich daher Deinen Beitrag gründlich lesen. Zum anderen
möchte ich mir noch vorbehalten, ob ich meine Sichtweise erkläre oder
auch rechtfertige oder lediglich feststelle, dass sie von Deiner
abweicht.
Da es ja in diesem Thread erst einmal um die Frage des TOs geht und Du
vielleicht die Absicht hast, direkt darauf zu antworten, möchte ich
jedenfalls sagen, dass ich an Deiner Antwort interessiert bin.
Lehrreich wäre das sicherlich, wie ich meine.
Klaus schrieb:> Karl Heinz schrieb:>> Klaus schrieb:>>>> Ich weiss nicht so recht was du da schreibst>> Ich will Dich nicht einfach abbügeln, insbesondere da ich der Ansicht> bin, dass Du viele Kenntnisse hast, die Du auch verständlich darstellen> kannst.>> Deine Formulierung des ersten Satzes ist allerdings recht sallop und> suggeriert mir in gewisser Weise und vor dem Hintergrund meines ersten> Satzes, dass ich irgendwie völlig falsch liege.
Ich hab nur nicht verstanden, was dich an der Formulierung, nach der ein
Parameter auch nichts anderes als eine lokale Variable ist, eigentlich
stört. Denn genau das ist ein Parameter.
Zum anderen finde ich diesen Satzteil hier unglücklich
> dass mit dem Parameter ein sprachliches Mittel geschaffen ist, die> Beziehung zwischen einer Variable ausserhalb der Funktion
denn eigentlich gibt es in C zwischen diesen Dingen keinerlei
'Beziehung'. Die beiden sind in keinster Weise irgendwie miteinander
logisch verknüpft.
Man kann in C eine Pointer Variable benutzen um sich selbst über den
Umweg einer Adressübergabe eine derartige Beziehung herzustellen, aber
in C an sich gibt es keine derartige Beziehung. Argument des Aufrufers
und Parametervariable einer Funktion sind voneinander vollkommen
unabhängig.
> Da es ja in diesem Thread erst einmal um die Frage des TOs geht und> Du vielleicht die Absicht hast, direkt darauf zu antworten, möchte> ich jedenfalls sagen, dass ich an Deiner Antwort interessiert bin.
Ein Grossteil meiner Antwort ist eigentlich an den TO gerichtet.
Sieh das bitte so.
Dass ich dir vieles nicht erläutern muss (vor allen Dingen nicht in der
Art wie ich das getan habe), ist mir klar. Empfänger der Botschaft
sollte der TO sein und nicht du.
Das hab ich vielleicht nicht klar genug herausgearbeitet.
@ Karl Heinz
Hm. Du benutzt die selben Fakten um Deinen Widerspruch zu belegen die
ich benutze um das mit meiner ursprüngliche Aussage zu tun.
Dann bezieht sich Dein Einwand wohl nur auf den zitierten Satz allein.
Naja: "nicht falsch" in Anwendung auf eine Kategorisierung ist durchaus
eine problematische Aussage. Denn es ist ja durchaus nicht klar, ob ich
darauf hinaus will, dass entgegen meiner Ansicht, hier zwei Kategorien
unrichtig, oder unter Auslassung von übergeordneten Kategorien
angeordnet worden sind oder die Objekte überhaupt keine Eigenschaften
teilen.
Ich meine, dass Parameter und Variable funktional und semantisch einige
Eigenschaften teilen. Aber es gibt auch Unterschiede. Das ganze ist
soweit immer noch unscharf, als es die Unterscheidung zwischen der
Nennung im Programmtext, seine physische Repräsentation auf der Maschine
und die Operationen damit nicht nennt. So etwas wird halt schnell
sprachlich subtil.
--- Das obige schrieb ich, bevor ich Deine Beiträge von 18:37 und 18:45
las.
Karl Heinz schrieb:> Ich hab nur nicht verstanden, was dich an der Formulierung, nach der ein> Parameter auch nichts anderes als eine lokale Variable ist, eigentlich> stört. Denn genau das ist ein Parameter.
Das habe ich oben in diesem Beitrag berührt. Meine Ansicht ist, dass
Parameter und Variablen eher für sich eine Nebenordnung darstellen.
Im Programmtext ist ein Parameter unter Anderem eine deklaratorische
Aussage darüber welche Argumente übergeben werden. Diese Aussage
entalten Variablendeklarationen nicht - einfach weil sie es nicht
brauchen. Funktional wird der Parameter innerhalb wie eine Variable
behandelt. Das rechtfertigt Deine Darstellung.
Allerdings impliziert die im Text vorhergehende Verwendung als Parameter
eine Einschränkung des Geltungsbereiches. Letzteres definiert weder
einen funktionalen noch semantischen fundamentalen Unterschied zu
Variablen aber eine spezifischen funktionalen Sinn, den Variablen an
sich nicht haben (die haben andere spezifische funktionale Bedeutungen -
sind z.B. implizit global sichtbar wenn "static" fehlt, aber auch nur
potentiell, denn aktuell im Text nur referenzierbar, wenn im Modul ein
extern geschrieben ist [letzteres sage ich mit dem Vorbehalt, als ich da
im aktuellen Standard nochmal nachschauen müsste]).
> Zum anderen finde ich diesen Satzteil hier unglücklich>> dass mit dem Parameter ein sprachliches Mittel geschaffen ist, die>> Beziehung zwischen einer Variable ausserhalb der Funktion> denn eigentlich gibt es in C zwischen diesen Dingen keinerlei> 'Beziehung'. Die beiden sind in keinster Weise irgendwie miteinander> logisch verknüpft.
Hm. Merkwürdig. Da der funktionale Vorgang von Dir genauso beschrieben
wird, wie ich ihn mir vorstelle, verstehe ich das nicht.
Wenn der Wert eines Parameters an einen Speicherplatz kopiert wird, den
die Funktion dann lesen und schreiben kann, besteht doch eine "logische
Beziehung", meine ich. Was ist daran unzutreffend? Das Wort "logisch"? -
Damit meine ich "formal, funktional und syntaktisch definiert" und auch
so realisiert. Das ist ja interessant ...
> Man kann in C eine Pointer Variable benutzen ...
Ich finde wir sollten das Pointer Thema hier rauslassen, wenn Du
einverstanden bist, denn es scheint mir, was ich evtl. unzutreffend
sehen sollte, nicht eigentlich zu berühren.
Wobei mir unstreitig scheint, das Pointer hier (neben modul-lokalen
Variablen) die Lösung für das praktische Problem des TO sind. Inhaltlich
sehe ich den Absatz von Dir genauso.
Falls das allerdings ein Kernpunkt Deines Widerspruches ist, dann wäre
ich auf eine etwas ausführlichere Erklärung angewiesen.
Karl Heinz schrieb:>> Da es ja in diesem Thread erst einmal um die Frage des TOs geht und>> Du vielleicht die Absicht hast, direkt darauf zu antworten, möchte>> ich jedenfalls sagen, dass ich an Deiner Antwort interessiert bin.>> Ein Grossteil meiner Antwort ist eigentlich an den TO gerichtet.> Sieh das bitte so.
Ach so. Puzzled! :-)
Klaus schrieb:> Allerdings impliziert die im Text vorhergehende Verwendung als Parameter> eine Einschränkung des Geltungsbereiches. Letzteres definiert weder> einen funktionalen noch semantischen fundamentalen Unterschied zu> Variablen aber eine spezifischen funktionalen Sinn, den Variablen an> sich nicht haben (die haben andere spezifische funktionale Bedeutungen -> sind z.B. implizit global sichtbar wenn "static" fehlt, aber auch nur> potentiell, denn aktuell im Text nur referenzierbar, wenn im Modul ein> extern geschrieben ist [letzteres sage ich mit dem Vorbehalt, als ich da> im aktuellen Standard nochmal nachschauen müsste]).
Ich denke der Knackpunkt ist, dass hier der Begriff 'Variable' für alles
mögliche herhalten muss.
Die Rede ist allerdings in diesem Zusammenhang von funktionslokalen
Variablen und nicht von globalen oder sonstigen Variablen.
Ok, in diesem Sinne könnte man den Wikipedia Artikel (den ich ausser in
deinem Zitat nicht gelesen habe) schuldig sprechen.
Paramater sind funktionslokale Variablen.
> Wenn der Wert eines Parameters an einen Speicherplatz kopiert wird, den> die Funktion dann lesen und schreiben kann, besteht doch eine "logische> Beziehung", meine ich. Was ist daran unzutreffend?
Deine Aussage implizierte (zumindest für mich), dass es auch nachdem der
Funktionsaufruf erfolgt ist, eine irgendwie geartete Verbdinung zwischen
"der Variablen des Aufrufers" und dem Parameter (die Variable der
Funktion) gibt. Und die existiert nun mal nicht.
Die Parametervariable enthält eine Kopie des Wertes 'der Variablen des
AUfrufers'. Aber egal was ich auch immer mit dieser Kopie anstelle, es
beeinflusst in keiner Weise den Aufrufer, von dem diese Kopie gezogen
wurde.
Du sprichst in deinem Satz von 'der Beziehung einer Variablen
....
Autsch!
Jetzt hab ich erst verstanden, was du mit dem Satz
> dass mit dem Parameter ein sprachliches Mittel geschaffen ist, die> Beziehung zwischen einer Variable ausserhalb der Funktion und ihrem> Wert bzw. ihrem Speicherort innerhalb der Funktion herzustellen.
ausdrücken willst.
Ok. Mein Fehler. Ich denke ich hab das missverstanden.
Du willst damit sagen, dass ein Funktionsparameter etwas ist, mit dem
man benennen kann, wie die funktionslokale Variable heissen soll, die
den Wert aufnimmt, der vom Aufrufer übergeben wird.
> die Beziehung zwischen einer Variable ausserhalb der Funktion
Wichtig: Der Aufrufer übergibt einen Wert. Der kann aus einer Variablen
stammen, muss aber nicht. An dieser Stelle ist es meiner Meinung nach
besser, hier die "Variable ausserhalb der Funktion" nicht zu erwähnen.
Genau das und das Wort 'Beziehung' hat mich auf die falsche Fährte
geführt.
Ich finde es erklärungstechnisch besser, wenn man sagt: der Aufrufer
bestimmt einen Wert und die Parametervariable empfängt (fängt, kriegt
zugewiesen) diesen Wert. Wie auch immer dieser Wert beim Aufrufer
zustande kommt.
Denn dann ist völlig klar, dass es die eine Seite nichts von der anderen
Seite weiss und es nur darum geht, dass Werte über die 'Funktionsgrenze'
geschleust werden, die halt (notgedrungenermassen) in einer benannten
Variablen (dem Parameter) aufgefangen werden und so der Funktion dann
zur Verfügung stehen.
Karl Heinz schrieb:> Klaus schrieb:> ...> Deine Aussage implizierte (zumindest für mich), dass es auch nachdem der> Funktionsaufruf erfolgt ist, eine irgendwie geartete Verbdinung zwischen> "der Variablen des Aufrufers" und dem Parameter (die Variable der> Funktion) gibt. Und die existiert nun mal nicht.> ...> Du sprichst in deinem Satz von 'der Beziehung einer Variablen>
Ups. Wohl ein "beziehungstechnisches" Problem.
...
> Autsch!> ...> Ok. Mein Fehler. Ich denke ich hab das missverstanden.>> Du willst damit sagen, dass ein Funktionsparameter etwas ist, mit dem> man benennen kann, wie die funktionslokale Variable heissen soll, die> den Wert aufnimmt, der vom Aufrufer übergeben wird.
Im wesentlichen: Ja.
> Ich finde es erklärungstechnisch besser, wenn man sagt: der Aufrufer> bestimmt einen Wert und die Parametervariable empfängt (fängt, kriegt> zugewiesen) diesen Wert. Wie auch immer dieser Wert beim Aufrufer> zustande kommt.> Denn dann ist völlig klar, dass es die eine Seite nichts von der anderen> Seite weiss und es nur darum geht, dass Werte über die 'Funktionsgrenze'> geschleust werden, die halt (notgedrungenermassen) in einer benannten> Variablen (dem Parameter) aufgefangen werden und so der Funktion dann> zur Verfügung stehen.
Ich verwende Beziehung wie "Relation" (in der allg. Bedeutung, die man
aus der Mathematik kennt, wohl um Fremdwörter zu vermeiden).
Daher hätte es auch Die von Dir vermutete Bedeutung haben können. Ich
habe das irgendwie wohl nicht klar genug dargestellt.
Ich habe - wohl fälschlicherweise - vorausgesetzt, dass man das
Ausführungsmodell nicht erwähnen muss.
Es ist durchaus richtig, das man damit rechnen muss, das Wertänderungen
je nach Ausführungsmodell auch auf andere Speicherstellen oder Register
übertragen werden, obwohl man das nicht explizit hingeschrieben hat.
Das Gegenteil schien mir hier selbstverständlich; für einem Anfänger
jedenfalls naheliegend, weil es sehr wahrscheinlich das einzige
Ausführungsmodell ist, dass er kennt - der irgendwann mal gehört haben
sollte/müsste/könnte, das ein Prozessor Befehle einfach Schritt für
Schritt nacheinander ausführt - und sonst eben noch nichts.
Ich stimme dem Grunde nach dem Absatz von Dir, beginnend mit "Ich finde
es erklärungstechnisch...", den ich hier zuletzt zitiert habe, zu.
Mir schien es in meinem Beitrag vom 17.06.2015 21:15, als ich
Voraussetzungen definiert habe und erklärt, was auf dem Stack geschieht
(der Absatz der mit "Nimm einmal an, dass ..." beginnt), hinreichend
klar, dass wenn ich nicht sage, dass der Wert bei Funktionsende wieder
zurück kopiert wird, das vielmehr bei einem Literal ein Widerspruch
dadurch entsteht, dass es dann ja verändert werden müsste, dies auch
nicht geschieht. Das ist so argumentiert, als wenn nicht sein kann, was
nicht sinnvoll ist und so doch ein wenig - naja - à la Morgenstern
argumentiert.
OK. Hätte klarer sein können.
Wenn ich es mir jetzt in der Zusammenfassung überlege, dann schien es
mir sehr problematisch zwischen Annahmen des TO über die tatsächlichen
Vorgänge auf Maschinenebene und denen, die die Sprachdefinition erlaubt
und jenen die "dem Anschein nach geschehen" bzw, "die man so realisieren
könnte" zu unterscheiden. Die Sprachdefinition sagt nur das die
Änderungen an Parametern nicht persistent ist. Sie sagt nicht wie das
erreicht wird. Genauso wenig, wie sie sagt, das Wert kopiert werden oder
freigegeben oder sonst was. Meint der TO also mit "freigeben"
tatsächlich eine Verwaltungsfunktion oder nur, dass irgend wo drauf
nicht mehr zugegriffen wird? Ist der Unterschied in den Gedanken des TOs
relevant oder nicht?
Deine Erklärungen sind oft wesentlich näher an den Erlebnissen der
Fragesteller, soviel muss ich sagen. Allerdings, widerstreben mir solche
Weglassungen oder ich sage mal Abstraktionen (ich meine das nicht
negativ, aber kritisch, Karl Heinz). Und wenn ich dann, der Not
gehorchend, was weglasse, wird es von K.H.B. prompt missverstanden,
obwohl ich mich bemühe nur das wegzulassen, was aber nun auch "wirklich"
nicht falsch vermutet werden kann. :-)
Naja. Ich denke viel mehr lässt sich über das Thema nicht sagen. Du bist
oberflächlich und ich erzähle viel Unnötiges. :-)