Forum: Mikrocontroller und Digitale Elektronik c code: Priorität & Lebensdauer Variable im Funktionsaufruf


von c schüler (Gast)


Lesenswert?

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
void main(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
return daten;
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
return daten;
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!

von Dirk B. (dirkb2)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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.

von Irgendwer (Gast)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

Ä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.

von Dirk B. (dirkb2)


Lesenswert?

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.

von Irgendwer (Gast)


Lesenswert?

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).

von Dirk B. (dirkb2)


Lesenswert?

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.

von Fragezeichen (Gast)


Lesenswert?


von c schüler (Gast)


Lesenswert?

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
1
for (i=0; i<sizeof(daten); i++) printf("%02x",daten[i]);



die volle 20 bzw 24 Zeichenlänge.
1
for (i=0; i<strlen(daten); i++) printf("%02x ",daten[i]);


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 -

von Dirk B. (dirkb2)


Lesenswert?

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.

von c schüler (Gast)


Lesenswert?

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 ) :
1
void main(void) {
2
3
char daten [20] = {0};
4
5
dump(daten);
6
7
}
8
9
10
11
void dump ( *daten ) {
12
13
int i;
14
15
16
for (i=0; i<strlen(daten); i++) printf("%02x ",daten[i]);
17
18
}

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
void main(void) {
2
3
char *ptr;
4
char daten[20] = {0};
5
ptr = &daten;
6
7
dump (*ptr);
8
9
}
10
11
12
13
void dump(*ptr) {
14
15
int i;
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?

von Nosnibor (Gast)


Lesenswert?

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.

von Dirk B. (dirkb2)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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.

von c schüler (Gast)


Lesenswert?

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
void main(void) {
2
3
char daten [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! ;)

von Dirk B. (dirkb2)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

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 ...

von Karl H. (kbuchegg)


Lesenswert?

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
void foo( char* txt )
2
{
3
  mach irgendwas mit sizeof(txt)
4
}
5
6
int main()
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.

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

> 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.

von Klaus (Gast)


Lesenswert?

@ 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! :-)

von Klaus (Gast)


Lesenswert?

Was ich noch sagen wollte: Meiner Ansicht nach! Durchaus! Allerdings!

Latürnich!

:-)

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

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. :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.