www.mikrocontroller.net

Forum: Compiler & IDEs Pointer direkt anlegen oder so?


Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eigentlich habe ich alles rum um die Pointer verstanden.

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

Wie geht das?

Autor: Joerg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz einfach.

type_t *pointer=Speicheradresse;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 );


Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wo ist eigentlich dein Problem?

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.


Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo ich glaube so mache ich es.


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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 &

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst's auch so machen

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

int main()
{
  int i;

  foo( i );
}

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist mir gerade aufgefallen:
type_t variable;
type_t *var=&variable;

funktion(var);

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

als dies hier:
type_t var

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

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ulrich (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Du kannst's auch so machen
>
> void foo( int& a )

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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.