www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik char* an Funktionübergeben


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte einen Pointer auf eine Zeichenkette an ein Unterprogramm 
übergeben, nur leider scheint das SO nicht zu klappen. Der Pointer im 
Unterprogramm zeigt irgendwo hin. Deswegen liefert sizeof() auch zB 2 
anstatt 3.

Wie muss es richtig lauten?
extern int8_t unterprogramm(char* buffer)
{
   return sizeof(buffer);
}

int main(void)
{
   int8_t u;
   char test[] = {0x0E,0x02,0x21};
   u = unterprogramm(test);
   .
   .
   .
}

Autor: Lukas K. (carrotindustries)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
 u = unterprogramm(test);
ersetzen durch
 u = unterprogramm(&test);

Autor: Marius Wensing (mw1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann so ja auch nicht funktionieren. Test ist ja halt nur ein 
Pointer, der eben aufm AVR 16-bit groß ist. Also liefert sizeof völlig 
korrekt den Wert 2.

Die Funktion kann ja mit allen möglichen char * Pointern aufgerufen 
werden. Beim Aufruf übergibst du einfach den Pointer und verlierst die 
Größeninformation eines Arrays. Das sizeof eines Arrays funktioniert nur 
dann richtig, wenn die Größe zur Compile-Zeit bekannt ist.

MfG
Marius

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der Pointer im Unterprogramm zeigt irgendwo hin.

Nö, der an Deine Funktion übergebene Pointer zeigt dahin, wo er soll.

> Deswegen liefert sizeof() auch zB 2 anstatt 3.

sizeof liefert die Größe des übergebenen Pointers, und der ist auf einem 
16-Bit-System nunmal 2 Bytes groß.

Das ist also korrekt.

Daß der Pointer auf ein Array mit n Elementen zeigt, das ist in Deiner 
Funktion nicht bekannt, und die Anzahl der Elemente lässt sich so auch 
nicht mit sizeof bestimmen.

Wenn buffer ein String (eine Zeichenkette) sein soll, dann lässt sich 
die Stringlänge mit der C-Runtime-Funktion strlen bestimmen.

In Deinem Beispiel aber ist das Array test kein String, da es nicht 
mit Null terminiert ist (und außerdem mehrere nicht darstellbare Zeichen 
enthält).

Deiner Funktion musst Du beim Aufruf neben dem Pointer auf das Array 
auch dessen Größe mitteilen:
int8_t unterprogramm(char* buffer, int size)
{
   return size;
}

int main(void)
{
   int8_t u;
   char test[] = {0x0E,0x02,0x21};
   u = unterprogramm(test, sizeof (test));
   .
   .
   .
}

Damit gewinnt allerdings das Beispiel an Sinnlosigkeit (warum einer 
Funktion, die anscheinend die Länge eines Arrays bestimmen soll, 
dessen Länge mitteilen?).


Abschließend:
Das Schlüsselwort extern ist hier vollkommen fehl am Platze.

Autor: bloat (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest nochmal das Kapitel über Datentypen und Pointer 
durcharbeiten.

Luk4s K. schrieb:
> Datum: 05.10.2010 21:58
>

>        u = unterprogramm(test);ersetzen durch u = unterprogramm(&test);


das ist ebenfalls Quatsch! test ist schon ein pointer und zwar der 
pointer auf das array test[], daher richtig ohne "AdressOf"(&) Operator

Autor: Bernhard R. (barnyhh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan schrieb:
> Hallo,
>
> ich möchte einen Pointer auf eine Zeichenkette an ein Unterprogramm
> übergeben, nur leider scheint das SO nicht zu klappen. Der Pointer im
> Unterprogramm zeigt irgendwo hin. Deswegen liefert sizeof() auch zB 2
> anstatt 3.
>
> Wie muss es richtig lauten?
> extern int8_t unterprogramm(char* buffer)
> {
>    return sizeof(buffer);
> }
>
> int main(void)
> {
>    int8_t u;
>    char test[] = {0x0E,0x02,0x21};
>    u = unterprogramm(test);
>    .
>    .
>    .
> }

Das Programm tut genau das, was Du ihm aufträgst. Die Funktion 
unterprogramm soll die Größe eines Pointers (auf ein char) zurückgeben. 
Die Größe dieses Pointers ist 2.

Was Du erreichen wolltest, ist vermutlich etwas völlig anderes. Dich 
scheint die Länge des char arrays test zu interessieren. Nimm Dein 
C-Lehrbuch und schaue nach, wie Du Dein Problem löst.

Bernhard

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnellen Antworten

das "extern" war nur ein überbleibsel vom richtigen Programm, hab ich 
vergessen weg zu machen

Da ich offensichtlich vergessen hatte wie sizeof() funktioniert ist mir 
nun auch klar warum 2 raus kam als Ergebnis

Aber warum liefert es hier den korrekten Wert 4?
int main(void)
{
  char test[] = {0x0E,0x02,0x21,0x66};
  int8_t bufferlength = sizeof(test);
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil du es hier auf das Array anwendest, nicht auf einen Zeiger.

Merke (steht fast überall): Ein Feld ist in C ein Zeiger.
Merke 2: Stimmt nur bedingt, hier nicht.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard R. schrieb:
> Nimm Dein
> C-Lehrbuch und schaue nach, wie Du Dein Problem löst.

Joa, ich könnte wohl künstlich ein StringendeZeichen einfügen und dann 
strlen(), oder wie schon erwähnt die Anzahl als extra Parameter 
übergeben

Mehr fällt mir jetzt grad auch nicht ein

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan schrieb:
> StringendeZeichen

Das ist in C halt das Nullbyte.
Genau dafür wurde die Null von den Indern erfunden.

Autor: bloat (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sizeof ist nicht wirklich eine funktion. Es ist vielmehr eine Art Makro, 
die den compiler veranlasst, mal nachzuschauen, wie gross deine 
Variablen sind und der Wert wird dann an der Stelle des sizeof 
eingesetzt. Das heisst, es ist wie eine Konstante, wenn das Programm 
erstmal kompiliert ist.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bloat schrieb:
> sizeof ist nicht wirklich eine funktion. Es ist vielmehr eine Art Makro,

Stimmt, es ist keine Funktion.
Aber nein, es ist keine Art Makro, sondern ein Operator wie + oder
- auf Konstanten, der zur Übersetzungszeit vom Compiler ausgewertet
wird.

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.