[C - Zeiger] - Übung im Tutorial

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Ersti
Beiträge: 3
Registriert: Fr Dez 19, 2014 1:51 pm

[C - Zeiger] - Übung im Tutorial

Beitrag von Ersti » Fr Dez 19, 2014 2:23 pm

Hallo liebe Community :),

erstmal ein nettes 'Hallo' an alle und dankeschön für diese Seite. Ich habe proggen in den letzten Woche (aufgrund meines Studiums) wirklich zu schätzen gelernt. Bis jetzt kam ich mit den Tutorien sehr gut zurecht.
Doch seit der Zeiger Thematik komme ich nicht mehr so ganz zurecht. Schon die Übung erschließt sich mir nicht so ganz =/.

//Lösung

Code: Alles auswählen

#include <stdlib.h>
#include <stdio.h>
 
int* add(int a, int b, int *sum){
	
	*sum = 4 + 5;
	return sum;

}

int main()
{
	int sum = 4711;

	add(4,5,&sum);

	printf("%i", sum);
    return EXIT_SUCCESS; 
} 
Mein Problem ist momentan, dass ich nicht 100%ig nachvollziehen kann was genau passiert. Meiner Vermutung nach übergebe ich die Adresse der Variable 'sum' an die add - Funktion und ich überschreibe den Wert hinter der Adresse (also 4711 mit 9). Aber bei der Übergabe steht der Operator &.

Dadurch liest sich der Code (für mich), als würde ich den Wert 4711 übergeben, davon wird die Adresse gespeichert und um 9 erhöht =/

Vielen dank für eine aufschlussreiche Antwort die etwas Licht ins Dunkel bringt :)

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: [C - Zeiger] - Übung im Tutorial

Beitrag von cloidnerux » Fr Dez 19, 2014 3:00 pm

Hi und Willkommen im Forum :D

Pointer sind mitunter nicht so leicht, aber auch keine schwarze Magie.

Grundsätzlich bei der Arbeit mit Pointer triffst du auf folgende 3 Symbole:

Code: Alles auswählen

*
&
->
Der Stern hat zwei Bedeutungen, ersten kennzeichnet er einen Pointer bei der Initialisierung:

Code: Alles auswählen

int * myPointer;
zweitens Dereferenziert er einen Pointer:

Code: Alles auswählen

*myPointer = 10;   //Den Inhalt auf den myPointer zeigt auf 10 setzten
Mit dem Dereferenzieren greifst du also auf die Variable zu, auf die der Pointer Zeigt.

Das & hat auch zwei Bedeutungen, sofern du mit C++ arbeitest.
Zum einen ist es der Referenzierungsoperator, macht also genau das umgekehrt des Dereferenzierungsoperators.
Mit dem & vor einer Variable greifst du auf dessen Adresse zu und nicht den Inhalt:

Code: Alles auswählen

int myInt;
int * myPointer;
myPointer = &myInt;  //myPointer zeigt auf myInt
Zum anderen kennzeichnet das & eine Referenz beim Initialisieren. Eine Referenz ist auch ein Pointer, der aber bestimmte Bedingungen voraussetzt und ist teil von C++, kommt also etwas später im Tutorial.
Der "->" ist auch eine Dereferenzierung, aber im Kontext von Strukturen und klassen.
Wenn du einen Pointer auf eine Struktur hast, musst du nicht diesen Pointer dereferenzieren und dann auf ein Element aus dieser Struktur zugreifen, sondern mit dem "->" direkt:

Code: Alles auswählen

struct myStruct
{
    int myInt;
};

struct myStruct _myStruct;
struct myStrcut * myStructPointer = &_myStruct;
(*myStructPointer).myInt = 5;
myStructPointer->myInt = 5;
Ich hoffe ich konnte dir deine Fragen beantworten.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: [C - Zeiger] - Übung im Tutorial

Beitrag von Xin » Fr Dez 19, 2014 3:00 pm

Moin Ersti und willkommen im Forum :-)
Ersti hat geschrieben:erstmal ein nettes 'Hallo' an alle und dankeschön für diese Seite. Ich habe proggen in den letzten Woche (aufgrund meines Studiums) wirklich zu schätzen gelernt. Bis jetzt kam ich mit den Tutorien sehr gut zurecht.
Freud mich: Wenn Du Dritti oder Vierti bist, wäre es schön, wenn Du Dich beteiligst :-)
Ersti hat geschrieben:Doch seit der Zeiger Thematik komme ich nicht mehr so ganz zurecht. Schon die Übung erschließt sich mir nicht so ganz =/.

//Lösung

Code: Alles auswählen

	int sum = 4711;

	add(4,5,&sum);

	printf("%i", sum);
    return EXIT_SUCCESS;
Mein Problem ist momentan, dass ich nicht 100%ig nachvollziehen kann was genau passiert. Meiner Vermutung nach übergebe ich die Adresse der Variable 'sum' an die add - Funktion und ich überschreibe den Wert hinter der Adresse (also 4711 mit 9).
Deine Vermutung ist richtig.
Ersti hat geschrieben:Aber bei der Übergabe steht der Operator &.
Dadurch liest sich der Code (für mich), als würde ich den Wert 4711 übergeben, davon wird die Adresse gespeichert und um 9 erhöht =/
Der &-Operator heißt "AdressOf". Du übergibst die Adresse der Variable "sum" und in dieser Variable/Speicherposition ist der Wert 4711 gespeichert, welcher als Datentyp int vorliegt. Die Funktion bekommt daher als drittes Argument einen Zeiger auf int: "int *", den Du mit dem Variablennamen "sum" ansprichst (was in der Funktion add ein (int*) ist und nicht das gleiche wie das sum in main, welches ein (int) ist.)

In der Funktion add() dereferenzierst Du dann (int *)sum. Du sagst also 'addiere 4 und 5' (das sind nicht die Parameter a und b) und das Ergebnis der Addition (9) schreibst dahin (*), wo sum hinzeigt. Also steht an der Speicherstelle auf die der Zeiger "sum" zeigt und wo zuvor 4711 stand, nun 9.

In main gibst Du nun die int-Variable sum aus. sum liegt an der Speicherstelle, die Du mit add() überschrieben hast. Wenn Du also die Speicherstelle, die du "sum" nennst ausgibst, dann befindet sich dort die 9 als int drin.

Erhöht wird hier ansonsten nix!?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Ersti
Beiträge: 3
Registriert: Fr Dez 19, 2014 1:51 pm

Re: [C - Zeiger] - Übung im Tutorial

Beitrag von Ersti » Fr Dez 19, 2014 3:39 pm

Erstmal vielen dank für die ausführlichen Antworten :). Ich hoffe ich kann mich später auch bisschen einbringen und hilfreiche Antworten geben :)

Die 2 Antworten habe mehr geholfen als 4 Wochen Vorlesung. Mit & kann ich also auf die Adresse einer Variable zu greifen.

Allerdings verstehe ich die 2 Code Zeilen nicht ganz.
Der Stern hat zwei Bedeutungen, ersten kennzeichnet er einen Pointer bei der Initialisierung:

int * myPointer;
*myPointer = 10; Den Inhalt auf den myPointer zeigt auf 10 setzten

Mit dem Dereferenzieren greifst du also auf die Variable zu, auf die der Pointer Zeigt.
Kann ich dem Pointer auch so einen Wert übergeben? Ich dachte das funktioniert nur mit dem "AdressOf" Operator.

Code: Alles auswählen

int x = 10;
int* myPointer;
myPointer = &x;
Ansonsten ist es (für den Moment) soweit klar :) Nochmals vielen dank. Gut das jetzt erstmal vorlesungsfreie Zeit ist. Da hat man neben dem ganzen Weihnachtsstress etwas nacharbeiten. Es kommen noch Funktionszeiger =/

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: [C - Zeiger] - Übung im Tutorial

Beitrag von Xin » Fr Dez 19, 2014 3:50 pm

Ersti hat geschrieben:Kann ich dem Pointer auch so einen Wert übergeben? Ich dachte das funktioniert nur mit dem "AdressOf" Operator.
Pointer sind ganz normale Variablen. Du musst halt drauf achten, dass Du die gleichen Datentypen benutzt:

Code: Alles auswählen

int Integer;
int * pInt = &Integer;
int * pInt2;

pInt2 = pInt;  // normale Zuweisung.
Du kannst auch mit Adressen rechnen:

Code: Alles auswählen

int array[10];
int * pBegin = &array[0];
int * pEnd = &array[9];

printf( "Größe des Arrays: %d integers\n", pEnd - pBegin );
Für Pointer Arithmetik sollte man sich aber erstmal mit Pointern sicher fühlen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Laura Palmer
Beiträge: 5
Registriert: Mi Jan 07, 2015 4:52 pm

Re: [C - Zeiger] - Übung im Tutorial - die Add-Funktion

Beitrag von Laura Palmer » Di Jan 13, 2015 1:13 pm

Hallo,

auch ich stehe etwas auf dem Schlauch.
Die Funktion "add" soll zwei Zahlen addieren und das Ergebnis an die Adresse liefern, an der 'sum' steht. Soweit okay.
Wenn ich das richtig verstehe, muss ein Zeiger auf 'sum' erst initialisiert werden (int *sum als Übergabeparamter in der add-Funktion am Anfang des Programmes reicht dafür bereits aus?) und dem Zeiger dann in der add-Funktion eine konkrete Adresse übergeben werden. (Oder wird erst hier durch das '&sum' die Adresse von 'sum' an eine variable die nur zufällig '*sum' heißt, aber auch einfach '*memory_Adress' heißen könnte übergeben?)
Gelöst habe ich das so:

Code: Alles auswählen

#include <stdlib.h>
#include <stdio.h>

int add( int left, int right, int *sum )
{
return *sum = left+ right;
}

int main()
{
  int sum = 4711;
  add( 4, 5, &sum );
  printf( "Die Summe betraegt: %d\n", sum );
  return EXIT_SUCCESS; 
} 
Wann gebe ich in der Funktion denn nun "*sum" und wann "sum" (wie bei Erstis-Add-Funktion) zurück?
Oder ist folgendes genau das Selbe:

Code: Alles auswählen

int add( int left, int right, int *memory_address )
{
return *memory_address = left+ right;
}

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: [C - Zeiger] - Übung im Tutorial

Beitrag von cloidnerux » Di Jan 13, 2015 1:24 pm

Oder ist folgendes genau das Selbe:

Code: Alles auswählen

int add( int left, int right, int *memory_address )
{
return *memory_address = left+ right;
}
Es ist das selbe.

Du hast ja einen Bezeichner, der einmal "sum" und in deinem zweiten Beispiel "memory_address" heißt. Der Bezeichner ist nur ein Weg für den Compiler zu verstehen, auf was genau du dich beziehst.

Dann hast du die Operatoren * und &.
Das Sternchen bei der Deklaration der Variablen:

Code: Alles auswählen

int * pointer;
gibt an, dass es sich bei der Variable um einen Pointer handelt.

Das Sternchen vor einem Pointer an sich:

Code: Alles auswählen

*sum = left + right;
*sum += *sum;
bedeutet, dass du auf das Ziel des Pointers zugreifen willst, damit dereferenzierst du den Pointer

Das "&" referenziert eine Variable:

Code: Alles auswählen

int a;
int *p = &a
Daher das & vor der Variablen weist den Compiler an, an dieser Stelle die Adresse statt dem Inhalt einer Variablen zurück zu geben.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Antworten