PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Unterschied zwischen Call by Value und Call by Reference



chrisavr1981
25.12.2014, 17:14
Hallo zusammen,

da ich im Moment zwischen dem vielen Essen und trinken ein wenig Zeit habe, mich mit meiner Schaltung und meinem Code auseinander zu setzen.
Kommen mir ein paar Fragen auf, die ich gerne verstehen würde.

Folgender Code verstehe ich, aber die nachfolgende Meldung des Compilers verstehe ich nicht... seht selbst.

Aktueller Code worum es geht:


unsigned char special[8][8] = { { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' },
{ 'I', 'J' ,'K' ,'L', 'M', 'N', 'O', 'P' },
{ 'Q', 'R' ,'S' ,'T', 'U' ,'V', 'W', 'X' },
{ 'Y', 'Z' ,'a' ,'b', 'c' ,'d', 'e', 'f' },
{ 'g', 'h' ,'i' ,'j', 'k' ,'l', 'm', 'o' },
{ 'p', 'q' ,'r' ,'s', 't' ,'u', 'v', 'w' },
{ 'x', 'y' ,'z' ,'1', '2' ,'3', '4', '5' },
{ '6', '7' ,'8' ,'9', '0' ,'*', '+', '-' }
};

// define a pointer for Array
unsigned char* special_ref;

void specialcarachter (unsigned char* character)
{
unsigned char memoryplace[8] = { '0','1','2','3','4', '5', '6', '7' };

int i = 0, j=0;

for (j=0; j<=7;j++)
{
printf ("This is the place: %c \n", memoryplace[j]);
for (i=0; i<=7;i++)
{
// why does this is a correct ???
printf ("This is a test === %c \n", character[j*8+i]);
// ok, i walk through the memory with eight steps, because one of these character J, are eight characters long:
// character[0*8+0] == 'A'
// character[1*8+1] == 'B'
// character[2*8+2] == 'C'
// why does this is incorrect, it is easier, but wrong???
//printf ("This is a test === %c \n", character[j][i]);

}
}
}

int main (void)
{
special_ref = special;

specialcarachter(special_ref);

return 1;
}


Meine 1. Frage, warum wird eine Warnung für diesen Pointer ausgegeben?
special_ref = special;


warning: assignment from incompatible pointer type [enabled by default]
special_ref = special;


Meine 2. Frage, macht es einen Unterschied, ob ich ein Array an die Funktion übergebe



void specialcarachter (unsigned char character[8][8])

oder


void specialcarachter (unsigned char* character)

einen Pointer auf ein Array? Mir geht es hierbei darum, weil die Aussage in "allen" C-Büchern besteht, dass Arrays vom Compiler als Pointer auf ein Array gesehen wird.
Für mich ist die 1. Schreibweise wesentlich "leichter" zu interpretieren. Wenn ich aber mit der Pointer Schreibweise, aufgrund der nicht durchzuführenden Kopie des Arrays, da es ja eine Call by reference Durchführung ist, Speicherplatz im RAM spare ist mir die 2. Schreibweise lieber!

Und die 3. Frage, wahrscheinlich schon im Text erkannt, warum kann ich in der Funktion mit den übergebenen Pointern, dass Array nicht über die Ebenen ansprechen und warum muss ich hier über die Speicherstellen gehen?



// why does this is incorrect, it is easier, but wrong???
printf ("this is a test === %c \n", character[j][i]);

printf ("This is a test === %c \n", character[j*8+i]);
// ok, i walk through the memory with eight steps, because one of these character J, are eight characters long:
// character[0*8+0] == 'A'
// character[1*8+1] == 'B'
// character[2*8+2] == 'C'


Vielen Dank für die Erläuterungen und Erklärungen.

Und einen wirklich schönen Feiertag!

Klebwax
25.12.2014, 17:43
Wenn ich aber mit der Pointer Schreibweise, aufgrund der nicht durchzuführenden Kopie des Arrays, da es ja eine Call by reference Durchführung ist, Speicherplatz im RAM spare ist mir die 2. Schreibweise lieber!

Der benötigte Speicherplatz ist eher unerheblich. Der wichtige Aspekt ist:
arbeite ich mit einer Kopie und ändere diese, bleibt das Orginal erhalten. Arbeite ich über einen Zeiger mit dem Original, ändere ich das Original unwiederuflich.
Umgekehrt heißt es aber auch, bekommt die Funktion (nur) eine Kopie, kann sie das Original nicht ändern. Außerdem bedeuted es, sie kann den Wert nach Belieben ändern, ohne das das Original beschädigt wird.

MfG Klebwax

chrisavr1981
25.12.2014, 18:11
Hallo Klebwax,

danke für deine Rückmeldung!!
Ok, das mit den Call by Value und Call by Reference und deren Vor,- und Nachteilen sind mir bekannt.
Also mit der Arbeit des Originalen Werts oder mit der Kopie.... .


Der benötigte Speicherplatz ist eher unerheblich. Der wichtige Aspekt ist:
arbeite ich mit einer Kopie und ändere diese, bleibt das Orginal erhalten. Arbeite ich über einen Zeiger mit dem Original, ändere ich das Original unwiederuflich.
Umgekehrt heißt es aber auch, bekommt die Funktion (nur) eine Kopie, kann sie das Original nicht ändern. Außerdem bedeuted es, sie kann den Wert nach Belieben ändern, ohne das das Original beschädigt wird.

MfG Klebwax

Mir war nur nicht bewusst, ob durch die Art der Übergabe der Speicherverbrauch sinkt oder gleichbleibend ist.

Vielen Dank für die Rückmeldung.

Klebwax
25.12.2014, 18:36
Mir war nur nicht bewusst, ob durch die Art der Übergabe der Speicherverbrauch sinkt oder gleichbleibend ist.


Es wird genausoviel Speicher verwendet, wie das Objekt groß ist. Ein int hat eine Größe, ein Array auch und ebenso eine Referenz bzw ein Pointer (sind ja auch nur Bytes im Speicher). Mit sizeof() kann man sich das auf der jeweiligen Architektur ansehen. Der Speicherverbrauch ist eigentlich auch kein Verbrauch, nach dem return steht er ja wieder zur Verfügung.

MfG Klebwax

Unregistriert
03.01.2015, 16:32
Hallo ChrisAVR1981,

wie du schon festgestellt hat, ist beides ein Pointer auf das erste Element des Arrays. Also braucht beides bei der Übergabe nur den Platz für den Adresswert des ersten Elements.
Ich würde trotzdem die Schreibweise vorziehen die zeigt, dass ein Zeiger übergeben wird.

Viele Grüße
Günter

chrisavr1981
04.01.2015, 22:41
Hallo zusammen,

ja, das stimmt:



Hallo ChrisAVR1981,

wie du schon festgestellt hat, ist beides ein Pointer auf das erste Element des Arrays. Also braucht beides bei der Übergabe nur den Platz für den Adresswert des ersten Elements.
Ich würde trotzdem die Schreibweise vorziehen die zeigt, dass ein Zeiger übergeben wird.

Viele Grüße
Günter


Man muss sich aber erst einmal noch an die Schreibweise gewöhnen.
Das fällt mir noch ein wenig schwer.