mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Anzahl der Arrayelemente in einer Funktion ermitteln


Autor: Heinz B. (hez)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hello,

ich schon wieder. Ich scheitere schon seit 3 Stunden daran, die Anzahl 
von Arrayelementen richtig zu ermitteln. Das Ding, das mich hasst und 
mit dem ich unglücklicherweise arbeite, nennt sich Keil-Compiler.

Mache ich die Ausgabe im Hauptprogramm, ist es ok:
void main (void)
{
   unsigned long iSize;

   char i=0;
   char aChar[2];
   aChar[0]='a';
   aChar[1]='b';

   iSize=sizeof(aChar); 
   printf("size: %lu\n",iSize); // 2
}
Übergebe ich jedoch das Array an eine Funktion, zählt er 1 hinzu:
void xxx(char aChar[])
{
   unsigned long iSize;
   iSize=sizeof(aChar); 
   printf("size: %lu\n",iSize); // 3 !!!!!
}
void main (void)
{
   char i=0;
   char aChar[2];
   aChar[0]='a';
   aChar[1]='b';
   xxx(aChar);
}

Hilfe, Hilfe, bitte Hilfe! Ich würde noch gerne in diesem Jahrtausend 
mit meinem Ringbuffer fertig werden schnüff

Kann mir wer einen Tip geben, warum das so ist und was ich falsch mache?

Autor: Thomas B. (detritus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du in reinem C ein Array verwendest, weisst nur du, wieviele 
Elememte es hat. Der Compiler/Rechner hat davon keine Ahnung und daher 
kannst auch du den Wert nicht im Nachhinein "ermitteln". Deshalb musst 
du z.B selbst aufpassen, dass nicht über die Arraygrenze 
hinwegaddressiert wird.

Verwendest du dagegen einen String (also ein Array, in dem das letzte 
Element den Wert Null hat), kann dir die Funktion strlen (aus der 
string.h) weiterhelfen.

Dein Programm allerdings gibt dir wohl aus, wieviele Bytes ein Pointer 
auf deinem System braucht.

Autor: Heinz B. (hez)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber ich habe ja gar keinen String. Nur ein Array an Chars. Ein \0 
definiere ich ja gar nicht.?.? Und ich verwende, wie definiert, auch 
immer nur 2 Elemente.

Aber du könntest irgendwie Recht haben. Vielleicht hängt der KEIL 
automatisch ein \0 an das Arrayelement an. Aber das wäre dann doch total 
ein Bug, oder?

Autor: Thomas B. (detritus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heinz B. schrieb:
> Aber ich habe ja gar keinen String. Nur ein Array an Chars. Ein \0
> definiere ich ja gar nicht.?.?

Jo, das könntest du z.b. aber mal machen ;)


> Aber du könntest irgendwie Recht haben. Vielleicht hängt der KEIL
> automatisch ein \0 an das Arrayelement an. Aber das wäre dann doch total
> ein Bug, oder?

Wäre doch sehr ungewöhnlich.

Auf jeden Fall wird dir der sizeof hier nicht weiterhelfen. Vielleicht 
solltest du mal präzise formulieren, was du genau erreichen willst und 
wie deine Eingangsgrösse aussieht. Oft platzt dann der Knoten von 
selbst. Ansonsten hier rein schreiben ;)

Autor: Heinz B. (hez)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ich machen will, sieht man ja an meinem zweiten Beispiel. Ich will 
ein char-Array einer Funktion übergeben, die dann die Anzahl der 
Elemente ermitteln soll.

Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vll. mit verketteten Listen arbeiten? Erzeugt zwar bei diesem Beispiel 
einen riesigen Overhead, es wäre jedoch problemlos möglich.

Warum du nicht einfach hingehst und die Zahl der vorhandenen Argumente 
mit übergibst, da du ja schließlich irgendwann mal den Speicherplatz 
reserviert hast, wirst du ihn also zwangsläufig kennen, weiß ich 
allerdings nicht.

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Was ich machen will, sieht man ja an meinem zweiten Beispiel. Ich will
>ein char-Array einer Funktion übergeben, die dann die Anzahl der
>Elemente ermitteln soll.

Das geht in C nicht. Weder das Übergeben des Arrays noch die Ermittlung 
der Elemente. In C übergibt man einen Zeiger auf das erste Element des 
Array, also z.b. char *. Das wird in Deinem Beispiel auch gemacht, 
char[] als Parameter ist nur eine andere Schreibweise für char*. Und nur 
aus einer Adresse kann man die Anzahl der gültigen Elemente, die 
dahinterstecken, nicht ermitteln. Du musst also die Anzahl manuell 
übergeben, oder eben ein 0 am Ende anfügen und über das 0 das Arrayende 
erkennen. Dies setzt natürlich voraus, dass dazwischen keine 0-s sein 
dürfen.

sizeof() liefert die Größe eines Etwas, in Deinem Fall die Größe eines 
char*, der auf Deinem System anscheinend 3 Bytes belegt.

MfG Mark

Autor: Uwe ... (uwegw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Funktion wird dir wohl eher die Größe eines Pointers 
zurückgegeben. Bei mir auf dem PC bekomme ich dort ne 4.

Strenggenommen gibt es in C weder Arrays noch Strings. Das ist alles nur 
syntax sugar für Pointerarithmetik. Es gibt bei der Übergabe eines 
Arrays an eine Fiunktion keinerlei Möglichkeit für die Funktion, die 
Größe des Arrays festzustellen.

Von daher sollte das Objekt deines Hasses nicht der Compiler sein, 
sondern die Sprache. Dabei hilft folgendes: 
http://www.henning-thielemann.de/CHater.html

Autor: Heinz B. (hez)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> In C übergibt man einen Zeiger auf das erste Element des
>> Array
Kann man das wieder irgendwie "dezeigerisieren", damit dann sizeof 
wirklich mit den richtigen Daten arbeitet?

Autor: Uwe ... (uwegw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, dazu ist C zu primitiv. Man muss immer ne separate Variable 
übergeben, um die Größe des Arrays in die Funkion zu bekommen.

void xxx(char aChar[])
ist übrigens nichts anderes als
void xxx(char * aChar)

Und
aChar[1]
ist gleich
*(aChar+1)

Richtig amüsant wird es dann erst bei mehrdimensionalen Feldern...

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Kann man das wieder irgendwie "dezeigerisieren", damit dann sizeof
>wirklich mit den richtigen Daten arbeitet?

Nein kann man nicht. Aber was bitteschön hindert Dich daran, die Anzahl 
der Elemente mit zu übergeben?? Wie Marcel schon gesagt hat, irgendwo 
musst Du ja das Array deklariert haben, also muss die aufrufende 
Funktion auch Anzahl kennen.
void xxx(char aChar[], unsigned int n)
{
   unsigned int iSize = n;
   printf("size: %lu\n",iSize); // 3 !!!!!
}
void main (void)
{
   char i=0;
   char aChar[2];
   aChar[0]='a';
   aChar[1]='b';
   xxx(aChar, sizeof(aChar));
   xxx(aChar, 2); // oder
}

Autor: Heinz B. (hez)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich finde das ein wenig ... seltsam, wenn eine Programmiersprache nicht 
zählen kann. Ab OK. Muss ich wohl so hinnehmen beim C.

Allen Danke für die Infos! :)

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es liegt nicht daran das es nicht zählen kann, sondern das es keine 
liste/array gibt. Es gibt nur ein Zeiger.

Und einer Adresse sieht man nun mal nicht an, wie lang der speicher 
bereich ist.

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.