Forum: Compiler & IDEs Array Probleme


von Chris (Gast)


Lesenswert?

Hallo, ich habe folgendes Programm:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
#define F_CPU 8e6
5
6
7
int main(void)
8
{
9
  DDRA=0xFF;
10
  DDRB=0x0F;
11
  PORTA=0x00;
12
  PORTB=0x00;
13
  DDRC |=(1<<DDC6);
14
  PORTC |= (1<<PC6); //Empfangen
15
  
16
  //UART Config
17
  UBRRL=51; //Baudrate 9600  
18
  UCSRB|=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
19
  UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
20
  
21
  
22
  char element[] = { 1, 2, 4, 8, 16, 32, 65, 128 };
23
  
24
    while(1)
25
    {
26
    
27
    if(element[8]==128)
28
    {
29
      UDR='A';
30
      PORTA=0x01;
31
    }
32
    else
33
    {
34
      UDR='B';
35
      PORTA=0x02;
36
    }
37
    _delay_ms(5000);
38
        
39
    }
40
}
dieses ist total simpel, jedoch wird bei der IF bedingung immer der else 
Zweig ausgeführt, obwohl das 8. Element 128 ist. Warum funktioniert das 
nicht?

von Karl H. (kbuchegg)


Lesenswert?

Wir fangen in C bei 0 zu zählen an

Zähl mal mit
1
  char element[] = { 1, 2, 4, 8, 16, 32, 65, 128 };
2
3
                     0  |  |  |  |   |    |   |
4
                        1  |  |  |   |    |   |
5
                           2  |  |   |    |   |
6
                              3  |   |    |   |
7
                                 4   |    |   |
8
                                     5    |   |
9
                                          6   |
10
                                              7

Das Array hat zwar 8 Elemente. Aber der höchste Index ist 7


1
   if(element[8]==128)

Mööp. Es gibt kein Array-Element mit dem Index 8

von Peter II (Gast)


Lesenswert?

Chris schrieb:
> obwohl das 8. Element 128 ist.

ist es nicht.

char element[] = { 1, 2, 4, 8, 16, 32, 65, 128 };

char[0] = 1
char[1] = 2
...
char[7] = 128

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Einfach Warnungen beachten:
1
<stdin>:1:1: warning: overflow in implicit constant conversion [-Woverflow]
2
 char element[] = { 1, 2, 4, 8, 16, 32, 65, 128 };
3
 ^

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Einfach Warnungen beachten:

Das ist aber ein ganz anderes Problem und hat nichts mit dem Array 
oder dem Zugriff darauf zu tun.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rufus Τ. Firefly schrieb:
> Johann L. schrieb:
>> Einfach Warnungen beachten:
>
> Das ist aber ein ganz anderes Problem und hat nichts mit dem Array
> oder dem Zugriff darauf zu tun.

Nö, Warnungen nicht zu beachten ist quasi immer ein Problem!

Ins Array wird nämlich keine 128 geschrieben, sondern eine -128.  Mit 
ein paar mehr Zeilen sind wie Warnungen:
1
<stdin>: In function 'main':
2
<stdin>:6:3: warning: overflow in implicit constant conversion [-Woverflow]
3
   char element[] = { 1, 2, 4, 8, 16, 32, 65, 128 };
4
   ^
5
<stdin>:11:5: warning: comparison is always false due to limited range of data type [-Wtype-limits]
6
     if (element[8]==128)

Die Korrektur besteht also zunächst mal darin, einen unsigned char (oder 
uint8_t) für element[] zu verwenden.  Danach werden die Warnmeldungen 
zu:
1
<stdin>: In function 'main':
2
<stdin>:11:16: warning: array subscript is above array bounds [-Warray-bounds]
3
     if (element[8]==128)
4
                ^

Jeder Warnung zeigt ein Problem auf und weist in Richtung der Lösung. 
Nachdem alle Warnungen behoben sind, funktioniert zumindest dieser Teil 
wie er soll.

Wie kommst du darauf, daß diese Warnungen auf ganz andere Probleme 
zeigen?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Wie kommst du darauf, daß diese Warnungen auf ganz andere Probleme
> zeigen?

Du reitest auf dem im Array stehenden Wert herum, das ursprüngliche 
Problem des Threadstarters aber lag in seinem fehlerhaften Arrayzugriff 
über die Arraygrenzen hinaus.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rufus Τ. Firefly schrieb:
> Johann L. schrieb:
>> Wie kommst du darauf, daß diese Warnungen auf ganz andere Probleme
>> zeigen?
>
> Du reitest auf dem im Array stehenden Wert herum, das ursprüngliche
> Problem des Threadstarters aber lag in seinem fehlerhaften Arrayzugriff
> über die Arraygrenzen hinaus.

Nein, ich reite auf jeder Warnung herum, auch auf der, die auf den 
Zugriff jenseits der Arraygrenzen hinweist.

Übrigens wird der der Zugriff elament[8]==128 idR wegoptimiert da der 
Vergleich immer falsch ist (2. Warnung), der Zugriff stellt also 
zunächst kein ein Problem dar, da er nie ausgeführt wird.

von Peter K. (peterka2000)


Lesenswert?

Einmal eine ganz Blöde Frage: Das ist doch ein char-Array. Muss ein Char 
nicht mit '' deklariert werden?

von troll (Gast)


Lesenswert?

Peter K. schrieb:
> Einmal eine ganz Blöde Frage: Das ist doch ein char-Array. Muss ein Char
> nicht mit '' deklariert werden?

Nein. char blub[42] sagt erstmal nur ein Array aus 8-Bit-Zahlen, je nach 
Compiler signed oder unsigned. Da kannst du ganz normal Zahlen von (wenn 
unsigned) 0-255 reintun oder eben mit 'a', 'b', '0' usw. den ASCII-CODE 
einzelner Buchstaben.

von Peter K. (peterka2000)


Lesenswert?

troll schrieb:
> Peter K. schrieb:
>> Einmal eine ganz Blöde Frage: Das ist doch ein char-Array. Muss ein Char
>> nicht mit '' deklariert werden?
>
> Nein. char blub[42] sagt erstmal nur ein Array aus 8-Bit-Zahlen, je nach
> Compiler signed oder unsigned. Da kannst du ganz normal Zahlen von (wenn
> unsigned) 0-255 reintun oder eben mit 'a', 'b', '0' usw. den ASCII-CODE
> einzelner Buchstaben.

Ok, ich bin auch kein C-Profi. Ist mir nur so beim ersten Blick 
aufgefallen.

von Rolf M. (rmagnus)


Lesenswert?

Peter K. schrieb:
> troll schrieb:
>> Peter K. schrieb:
>>> Einmal eine ganz Blöde Frage: Das ist doch ein char-Array. Muss ein Char
>>> nicht mit '' deklariert werden?
>>
>> Nein. char blub[42] sagt erstmal nur ein Array aus 8-Bit-Zahlen, je nach
>> Compiler signed oder unsigned. Da kannst du ganz normal Zahlen von (wenn
>> unsigned) 0-255 reintun oder eben mit 'a', 'b', '0' usw. den ASCII-CODE
>> einzelner Buchstaben.
>
> Ok, ich bin auch kein C-Profi. Ist mir nur so beim ersten Blick
> aufgefallen.

Prinzipiell ist char für den Compiler nur ein Integer-Typ wie die 
anderen auch, mit der Ausnahme, daß er ohne [un]signed-Präfix nicht 
zwingend mit Vorzeichen sein muß.
Aber obwohl der Compiler es zulässt, einem char direkt eine Zahl 
zuzuweisen, ist es durchaus sinnvoll diesen Typ (also ohne signed oder 
unsigned davor) nur für Zeichen zu verwenden.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Eieiei ... was macht den die "65" in dem Array ? ;)

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.