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


von Heinz B. (hez)


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:
1
void main (void)
2
{
3
   unsigned long iSize;
4
5
   char i=0;
6
   char aChar[2];
7
   aChar[0]='a';
8
   aChar[1]='b';
9
10
   iSize=sizeof(aChar); 
11
   printf("size: %lu\n",iSize); // 2
12
}
Übergebe ich jedoch das Array an eine Funktion, zählt er 1 hinzu:
1
void xxx(char aChar[])
2
{
3
   unsigned long iSize;
4
   iSize=sizeof(aChar); 
5
   printf("size: %lu\n",iSize); // 3 !!!!!
6
}
7
void main (void)
8
{
9
   char i=0;
10
   char aChar[2];
11
   aChar[0]='a';
12
   aChar[1]='b';
13
   xxx(aChar);
14
}

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?

von Thomas B. (detritus)


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.

von Heinz B. (hez)


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?

von Thomas B. (detritus)


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 ;)

von Heinz B. (hez)


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.

von Marcel (Gast)


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.

von Mark .. (mork)


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

von Uwe .. (uwegw)


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

von Heinz B. (hez)


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?

von Uwe .. (uwegw)


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

von Mark .. (mork)


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.
1
void xxx(char aChar[], unsigned int n)
2
{
3
   unsigned int iSize = n;
4
   printf("size: %lu\n",iSize); // 3 !!!!!
5
}
6
void main (void)
7
{
8
   char i=0;
9
   char aChar[2];
10
   aChar[0]='a';
11
   aChar[1]='b';
12
   xxx(aChar, sizeof(aChar));
13
   xxx(aChar, 2); // oder
14
}

von Heinz B. (hez)


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! :)

von Peter (Gast)


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.

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.