Forum: Compiler & IDEs Pointer direkt anlegen oder so?


von Ulrich (Gast)


Lesenswert?

Eigentlich habe ich alles rum um die Pointer verstanden.

Aber jetzt würde ich gerne diese beide Befehle zu einem zusammenfassen:
1
type_t variable;
2
type_t *pointer=&variable;

Wie geht das?

von Joerg (Gast)


Lesenswert?

Ganz einfach.

type_t *pointer=Speicheradresse;

von Karl H. (kbuchegg)


Lesenswert?

1) Gar nicht

   So ein Konstrukt braucht man manchmal, wenn man je nach
   einer Bedingung den Pointer auf entweder die eine
   oder die andere Variable zeigen lassen möchte


   type_t Var1;
   type_t Var2;

   type_t* pVar;


   if( irgendwas )
     pVar = &Var1;
   else
     pVar = &Var2;

   *pVar = irgendein type_t Wert


   Das stellt sich aber dein Problem gar nicht.

2) type_t *pointer = malloc( sizeof( type_t ) );

   .....

   free( pointer );


von Ulrich (Gast)


Lesenswert?

was du sagt ist für mih bereits klar. Aber ich benötige einen Pointer 
auf einen Speicher der noch nicht reserviert wurde.

Jetzt will ich in einer Zeile den Speicher reservieren und dabei die 
Adresse dem Pointer zuweisen.

Eventuell finde ich auch keine Lösung weil das gar nicht geht....

von Walter (Gast)


Lesenswert?

wo ist eigentlich dein Problem?

von Ulrich (Gast)


Lesenswert?

Eigenltich habe ich kein wirkliches Problem.


1. Ich verwende im Rest vom code Funktionen denen ich den pointer 
übergebe.
2. Ich will die 2 Zeilen in einerzeile haben. umso kleiner desto 
schicker finde ich. Natürlich weiß ich das dies nicht die *.hex größe 
beeinflusst....

Wenns nicht geht ist dies auch kein Beinbruch...

von Karl H. (kbuchegg)


Lesenswert?

> 1. Ich verwende im Rest vom code Funktionen denen ich den pointer
> übergebe.

Dazu brauchst du keine explizite Pointer Variable


void foo( int* a )
{
  *a = 5;
}

int main()
{
  int i;

  foo( &i );
}

So ist dann auch an der Aufrufstelle klarer, dass foo()
die Möglichkeit hat, i zu verändern. Mit einer zusätzlichen
Pointer Variable verschleierst du das nur.


von Ulrich (Gast)


Lesenswert?

Jo ich glaube so mache ich es.


Nur so aus interesse ich könnte doch auch das & in die Funktion selbst 
mit reinschreiben?

von Karl H. (kbuchegg)


Lesenswert?

Nein, kannst du nicht. (Es sei denn du programmierst in C++
und nicht in C)

Zieh dir das Kapitel über Pointer noch mal rein.

Der Witz an der ganzen Sache ist, dass man der Funktion
eine Adresse übergibt. Also muss der Aufrufer auch eine
Adresse angeben. Zb die Adresse einer Variablen. Und die
kriegt man mit einem &

von Walter (Gast)


Lesenswert?

Du kannst's auch so machen

void foo( int& a )
{
  a = 5;
}

int main()
{
  int i;

  foo( i );
}

von Ulrich (Gast)


Lesenswert?

Das ist mir gerade aufgefallen:
1
type_t variable;
2
type_t *var=&variable;
3
4
funktion(var);

benötigt 6bytes mehr Flash
und 2 bytes mehr Ram
(laut avr-size)

als dies hier:
1
type_t var
2
3
funktion(&var);

Jetzt ist es klar das ich es wie von "Karl heinz Buchegger" 
vergeschlagen mache.

Aber wieso ist das Platzsparender? Ich dache so ein "pipfax-code" wird 
vom Optimierer komplett optimiert????

von Walter (Gast)


Lesenswert?

das mehr RAM gebraucht wird ist klar, scjließlich hast du durch den 
Pointer eine weitere Variable die Platz braucht

und mehr Code brauchts da du neben dem Funtktionsaufruf ja auch noch 
eine zuweisung hast

von Ulrich (Gast)


Lesenswert?

insgesamt nun 240Bytes kleiner, hat sich also richtig gelohnt..
Danke an alle Schreiber der Beiträge....

von Karl H. (kbuchegg)


Lesenswert?

> Du kannst's auch so machen
>
> void foo( int& a )

Wusste gar nicht, dass es in C jetzt auch Referenzen gibt.

von Simon K. (simon) Benutzerseite


Lesenswert?

Karl Heinz! :-)

Was mich schon immer interessiert hat, was bedeutet dieses "int& xyz" ? 
Was ist eine Referenz? Wie geht das? Wofür ist das gut?

Lese das eigentlich immer nur bei objektorientierten Programmen.

von Karl heinz B. (kbucheg)


Lesenswert?

Die konzeptionelle C++ Sicht der Dinge:

Eine Referenz ist 'ein anderer Name' für ein Objekt.

Konkret

void foo( int& a )
{
  a = 5;
}

int main()
{
  int i;

  foo( i );
}

Beim Aufruf von foo() wird die Referenz gebunden, d.h. innerhalb
von foo ist a ein anderer Name für main::i. Damit sind a und i
identisch und ein und dieselbe Variable.
Eine Referenz muss bei ihrer Definition initialisiert werden,
d.h. eine Referenz verweist immer auf ein anderes Objekt. Es
ist nicht möglich (mit legalen C++ Mitteln) eine Referenz
zu erzeugen, die nicht identisch mit einem anderen Objekt
ist.

int main()
{
  int i;
  int& a;       /* nicht legal: eine Referenz mzss bei der
                   Initialisierung auf ein anderes Objekt
                   verweisen */
  int& b = i;   /* ist so ok. Ab sofort ist b ein anderer Name
                   für i. Was immer ich mit b mache, mache ich
                   in Wirklichkeit mit i. b und i sind
                   dieselbe Variable
                */
}

Im letzten Beispiel besteht die Referenz lediglich aus einem
Eintrag in der Symbol-Tabelle des Compilers.

Im Beispiel mit dem Funktionsaufruf ist es etwas komplizierter.
Es wird zwar dem Compilerbauer nicht vorgeschrieben, wie er eine
Refernz zu implementieren hat, allerdings machen es alle
Compiler gleich: In diesem Fall ist eine Referenz einfach
nur ein versteckter Pointer.

void foo( int& a )
{
  a = 5;
}

int main()
{
  int i;

  foo( i );
}

Der Compiler reserviert für a einen Pointer. Beim Aufruf wird
die Adresse vom Argument in diesem Pointer gespeichert und
bei allen Verwendungen von a innerhalb der Funktion wird
der Pointer automatisch vom Compiler dereferenziert.

Das ist im Grunde alles, was es zu Referenzen zu sagen gibt.
Ist eigentlich sehr simpel. Die Frage ist nur: Warum der
ganze Aufwand?
Es geht im wesentlichen um die Aufrufsyntax. Dort ist es
wichtig, dass kein Adress-of Operator vorkommt. Denn das
ermöglicht den Weg hin zu Copy-Konstruktor und vor allen
Dingen Operator-Overloading.

Ein netter 'Neben'-Effekt ist es, dass in C++ das Pointer-
geschehen deutlich abnimmt. Die Daumen-Regel ist sehr einfach:
Soll eine Funktion das Objekt des Aufrufers verändern können,
dann wird das Objekt per Referenz übergeben
Soll sie das nicht können, so übergibt man
  * bei kleinen Objekten oder eingebauten Datentypen
    wie in C durch Übergabe per Value
  * bei größeren Objekten, bei denen das Erzeugen einer
    Kopie teuer wäre, übergibt man per const Referenz.

C Puristen werfen gerne das Argument in die Waagschale, dass
man bei der Übergabe per Pointer, durch den notwendigen
Address-of Operator, auch beim Aufrufer sehr schön sieht, ob
die aufgerufene Funktion die Möglichkeit hat das Argument beim
Aufrufer zu verändern.

    foo1( i );     /* diese Funktion kann i nicht verändern */
    foo2( &i );    /* diese Funktion kann i potentiell verändern */

Im Grunde ist diese Argumentation auch richtig. Allerdings war
das in der Praxis in all den Jahren in denen ich C++ programmiere
nie wirklich ein Problem. Durch den Zusammenhang in dem die
Funktion aufgerufen wird, durch Dinge wie vernünftigen Funktions-
namen und Argumentnamen ist es in der Praxis überhaupt kein
Problem das auseinanderzuhalten, bzw. überhaupt wissen zu
müssen.

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.