länge eines arrays wird ein element mehr als für mich erwartet

Gast #5868522
Lesenswert?
• ▲
▼
Hallo,
ich habe zwei arrays, die ich einer FUnktion Übergebe. Bei einem Array, 
wird die Anzahl der Elemente in der Funktion aber mehr.
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <stdint.h>
4

5
static void add(char* summe, const char* sum1, const char* sum2);
6

7
int main(void) {
8
  const char sum_1[] = {0x00, 0x10, 0x00, 0x00};
9
  const char sum_2[] = {0x00, 0x11, 0x12};
10
  char sum[1000] = {0};
11

12

13
  for(uint8_t x=0; x<sizeof(sum_2)/sizeof(sum_2[0]); x++)
14
  {
15
    printf("%02x ", sum_2[x]);
16
  }
17
  printf("\r\n\r\n");
18

19
  /* 1052928 */
20
  add(sum, sum_1, sum_2);
21

22
  return EXIT_SUCCESS;
23
}
24

25

26
static void add(char* summe, const char* sum1, const char* sum2)
27
{
28
  const uint32_t length_1 = sizeof(sum1)/sizeof(sum1[0]);
29
  const uint32_t length_2 = sizeof(sum2)/sizeof(sum2[0]);
30
  printf("length1: %d\r\n", length_1);
31
  printf("length2: %d\r\n", length_2);
32

33
  for(uint8_t x=0; x<length_1; x++)
34
  {
35
    printf("%02x ", sum1[x]);
36
  }
37
  printf("\r\n\r\n");
38
  for(uint8_t x=0; x<length_2; x++)
39
  {
40
    printf("%02x ", sum2[x]);
41
  }
42
}

Die Ausgabe sieht wie folgt aus:
00 11 12

length1: 4
length2: 4
00 10 00 00

00 11 12 00

warum ist length2 = 4?

Bevor ich das array der FUnktion übergeben habe, war es ja auch 3.
Gast #5868532
Lesenswert?
• ▲
▼
> static void add(char* summe, const char* sum1, const char* sum2)
> {
[..]
>  const uint32_t length_2 = sizeof(sum2)/sizeof(sum2[0]);
[..]
>  printf("length2: %d\r\n", length_2);
[..]
> length2: 4
[..]
> warum ist length2 = 4?

Weil ein Zeiger bei Dir augenscheinlich 4 Bytes lang ist. Denk drüber 
nach(!).

HTH
Persönliche Seite #5868537
Lesenswert?
• ▲
▼
jan schrieb:
> static void add(char* summe, const char* sum1, const char* sum2)
> {
>   const uint32_t length_1 = sizeof(sum1)/sizeof(sum1[0]);
>   const uint32_t length_2 = sizeof(sum2)/sizeof(sum2[0]);

Das funktioniert nicht. Innerhalb der Funktion ist nicht bekannt, wie 
groß die Arrays sind.

Das ist eine elementare Eigenschaft von Arrays in C; wenn man die Dinger 
einer Funktion übergibt, zerfallen sie zu einem Pointer auf das erste 
Element. Die Größe muss man der Funktion als separaten Parameter 
übergeben.
Gast #5868539
Lesenswert?
• ▲
▼
> warum ist length2 = 4?

Weil dein Rechner 32-bit-Pointer hat: sum2 ist ein char* kein char[3]. 
Arrays werden zu Pointern reduziert, die Länge des Arrays geht dabei 
verloren und muß ggf extra übergeben werden.
Gast #5868618
Lesenswert?
• ▲
▼
Rufus Τ. F. schrieb:
> Das ist eine elementare Eigenschaft von Arrays in C; wenn man die Dinger
> einer Funktion übergibt, zerfallen sie zu einem Pointer auf das erste
> Element. Die Größe muss man der Funktion als separaten Parameter
> übergeben.

Man kann auch die Adresse eines Arrays übergeben (in C++ als Alternative 
eine Referenz) und damit ist die Größe des Arrays in der Funktion 
bekannt.

Beispiel (C):
1
void dir_getfullname_buf(TCHAR (*buf)[MAX_PATH], DIRITEM item);

kann nur aufgerufen werden mit Array von genau MAX_PATH Größe:
1
TCHAR tmp[MAX_PATH];
2
dir_getfullname_buf(&tmp, item);
#5868942
Lesenswert?
• ▲
▼
Rufus Τ. F. schrieb:
> jan schrieb:
>> static void add(char* summe, const char* sum1, const char* sum2)
>> {
>>   const uint32_t length_1 = sizeof(sum1)/sizeof(sum1[0]);
>>   const uint32_t length_2 = sizeof(sum2)/sizeof(sum2[0]);
>
> Das funktioniert nicht. Innerhalb der Funktion ist nicht bekannt, wie
> groß die Arrays sind.

Die Größe ist zwar nicht bekannt, aber das ist nicht der Grund, warum 
das falsche rauskommt. Das liegt eher daran, dass es ein ganz anderer 
Typ ist.

> Das ist eine elementare Eigenschaft von Arrays in C; wenn man die Dinger
> einer Funktion übergibt, zerfallen sie zu einem Pointer auf das erste
> Element. Die Größe muss man der Funktion als separaten Parameter
> übergeben.

Anders gesagt: Der Parameter ist kein Array, sondern ein Zeiger. Steht 
ja auch so da: "const char* sum1" ist ein Zeiger auf einen const char. 
Damit gibt sizeof auch die Größe eines Zeigers auf const char zurück. 
Dass dieser auf den Anfang eines Arrays zeigt, spielt da gar keine 
Rolle.

loeti2 schrieb:
> Man kann auch die Adresse eines Arrays übergeben (in C++ als Alternative
> eine Referenz) und damit ist die Größe des Arrays in der Funktion
> bekannt.

Die Größe ist dann bekannt, aber nur weil sie explizit Teil des 
Parametertyps ist. Damit ist sie auch von der Funktion fest vorgegeben. 
Wenn man ein Array einer anderen Größe übergeben will, muss man erst die 
Funktion ändern.
Persönliche Seite #5869141
Lesenswert?
• ▲
▼
loeti2 schrieb:
> Man kann auch die Adresse eines Arrays übergeben (in C++ als Alternative
> eine Referenz) und damit ist die Größe des Arrays in der Funktion
> bekannt.

Nicht wirklich, denn Du definierst die Funktion so, daß sie einen 
Pointer auf ein Array dieser Größe erwartet.

Das ist was anderes als einer Funktion ein Array beliebiger Größe so 
übergeben zu können, so daß die Funktion herausfinden kann, wie groß 
das Array jeweils ist.
Gast #5869685
Lesenswert?
• ▲
▼
Hallo,
dass die länge in der Funktion nicht bekannt ist, habe ich verstanden. 
Übergebe jetzt auch die länge mit. Allerdings habe ich ein seltsames 
auftreten, welches ich wieder nicht verstehe
1
static void add(char* summe, const uint8_t* length, const char sum1[], const uint8_t length1, const char sum2[], const uint8_t length2)
2
{
3
  uint16_t temp = 0;
4
  uint8_t overflow = 0;
5
  for(uint8_t x=0; x<length2; x++)
6
  {
7
    printf("sum2[%d] = %04x \r\n", length2-1-x, (uint16_t)sum2[length2-1-x]);
8
  }
9
  printf("\r\n");
10
  for(uint8_t x=0; x<length2; x++)
11
  {
12
    temp = (uint16_t)sum1[length1-1-x] + (uint16_t)sum2[length2-1-x] + (uint16_t)overflow;
13
    summe[5-x] = (uint8_t)temp;
14
    overflow = (uint8_t)(temp >> 8);
15

16
    printf("%04x %04x %04x\r\n", (uint16_t)sum1[length1-1-x], (uint16_t)sum2[length2-1-x], (uint16_t)overflow);
17
  }
18
}
1
const char sum_1[] = {0x10, 0x20, 0x30, 0x40};
2
const char sum_2[] = {0x11, 0x11, 0x11};

Was ich nicht verstehe, ist die zweite Ausgabe. Die absolute Ausgabe 
sieht wie folgt aus
sum2[2] = 0011
sum2[1] = 0011
sum2[0] = 0011

0040 0011 0000
0030 0051 0000
0020 ff81 00ff

Im ersten Block lasse ich mir den Inhalt von sum2 ausgeben. Das passt.
Im zweiten lasse ihc mir den Inhalt von sum1 und sum2 ausgeben. Warum 
passen die Werte von sum2 hier nicht mehr? (also warum 0051 und ff81?)
Das verstehe ich nicht.
Ich ändere den Wert doch gar nicht und bei der ersten Ausgabe wird es 
auch richtig gegeben.

Ziel ist es zum schluss den array summe als Ergebnis mit
summe[] = {0x00, 0x10, 0x31,0x41, 0x51}; zu bekommen
Gast #5870795
Lesenswert?
• ▲
▼
> Ich ändere den Wert doch gar nicht [..]

Doch. Wo kommt der Speicher für
    char* summe
her?

>  for(uint8_t x=0; x<length2; x++)
[..]
>    summe[5-x] = (uint8_t)temp;

Und wie weisst Du dass length2 immer kleiner oder gleich 5 ist?

> sum2[length2-1-x]

..und Du wirst Dich wesentlich leichter tun wenn Du die (vermutlich 
arbitrary-length-)Zahlen-Arrays als little endian interpretierst, also 
LSB auf Index 0.
Gast #5870823
Lesenswert?
• ▲
▼
Dirk B. schrieb:
> Wie rufst du die Funktion auf?
>
> Wie sind dort die Variablen definiert.
1
const char sum_1[] = {0x10, 0x20, 0x30, 0x40};
2
const char sum_2[] = {0x11, 0x11, 0x11};
3
char summe[5] = {0};
4
const uint8_t length_1 = sizeof(sum_1)/sizeof(sum_1[0]);
5
const uint8_t length_2 = sizeof(sum_2)/sizeof(sum_2[0]);
6
uint8_t length=0;
7
add(summe, &length, sum_1, length_1, sum_2, length_2);

g457 schrieb:
> Und wie weisst Du dass length2 immer kleiner oder gleich 5 ist?

Das weiß ich noch nicht. Das käme im nächsten schritt. Zunächst weiß ich 
es nur, da ich es so definiert habe. Eigentlich wäre summe eins größer, 
als sum_1 oder sum_2 (je nachdem welcher größer ist).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren