Schleife, die bei -1 beginnt, gibt nichts aus [duplicate]

Lesezeit: 4 Minuten

Benutzeravatar von rohit kumar
rohit kumar

Dieses Programm soll die Elemente von ausdrucken arrayaber wenn es ausgeführt wird, wird keine Ausgabe angezeigt.

#include <stdio.h>

#define TOTAL_ELEMENTS  (sizeof(array) / sizeof(array[0]))

int array[] = { 23, 34, 12, 17, 204, 99, 16 };

int main() {
    int d;
    for (d = -1; d <= (TOTAL_ELEMENTS - 2); d++) 
        printf("%d\n", array[d + 1]);
    return 0;
}

Warum zeigt dieses Programm keine Ausgabe an?

  • Ein Makro mit einem fest codierten Variablennamen verursacht Probleme.

    – Jackarms

    13. August 2017 um 5:54 Uhr

  • Ändern d=0 gibt aber Dinge aus

    – Tony Tannous

    13. August 2017 um 5:56 Uhr

  • @TonyTannous, aber es erklärt nicht, was das Problem im OP ist

    – CIsForCookies

    13. August 2017 um 5:59 Uhr

  • @CIsForCookies es ist der Kommentarbereich. Ich habe ihm nicht gesagt, dass er sich ändern soll d=0 oder eine Lösung anbieten. Ich habe mich nur gefragt.

    – Tony Tannous

    13. August 2017 um 5:59 Uhr


  • Fragen Sie Ihren Compiler. Es wird Ihnen oft sagen, was das Problem ist. Auch in diesem Fall. Zum gcc und klirren verwenden -Wall -Wextrazumindest für Visual C(++). /W3vorzugsweise /W4 zumindest bei der Fehlersuche.

    – Hyde

    13. August 2017 um 6:17 Uhr

Benutzeravatar von cs95
cs95

sizeof gibt eine Ganzzahl ohne Vorzeichen zurück, also TOTAL_ELEMENTS ist ebenfalls unsigniert.

d ist unterschrieben. Anfänglich, d ist -1. Allerdings, wenn Sie den Vergleich machen, d wird implizit in unsigned umgewandelt, also nicht mehr -1 beim Vergleich mit TOTAL_ELEMENTSist es tatsächlich UINT_MAX (welches ist 4294967295 auf meiner Maschine, kann aber bei anderen abweichen).

Ebenfalls,

Wenn Sie dies beheben möchten, geben Sie eine Typumwandlung ein TOTAL_ELEMENTS zu int:

for(d = -1; d <= (int)(TOTAL_ELEMENTS - 2); d++) 

Dies wird gedruckt:

23
34
12
17
204
99
16

Wie Sie es erwarten würden. Sie können sich auch Vergleichsoperationen für Ganzzahlen ohne Vorzeichen und mit Vorzeichen ansehen, um weitere Informationen zum Thema Vergleiche mit Vorzeichen und ohne Vorzeichen zu erhalten.

Es ist erwähnenswert, dass das Aktivieren von Compiler-Warnungen Ihnen geholfen hätte, herauszufinden, was los war (wie von Hyde in seinem Kommentar beobachtet):

$ gcc -Wall -Wextra test.c
test.c:7:17: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
      for(d = 0; d < TOTAL_ELEMENTS; d++) 
              ~ ^ ~~~~~~~~~~~~~~
1 warning generated.

Alternativ, warum nicht anfangen d bei 0 und lauf zu TOTAL_ELEMENTS - 1 stattdessen? Sie können sogar die Typumwandlung weglassen, die nur für den Eckfall von erforderlich ist d = -1.

for(d = 0; d < TOTAL_ELEMENTS; d++) 
    printf("%d\n", array[d]);

Als Fußnote hier die relevanten Auszüge aus dem C99-Standard:

  1. 6.3.1.8p2 definiert die Umwandlung von signiertem in unsignierten Typ.

    Wenn der Rang des Operanden vom Typ Ganzzahl ohne Vorzeichen größer oder gleich dem Rang des Typs des anderen Operanden ist, wird der Operand vom Typ Ganzzahl mit Vorzeichen in den Typ des Operanden vom Typ Ganzzahl ohne Vorzeichen konvertiert.

  2. 6.3.1.3p2 legt fest, wie die Konvertierung erfolgt: Durch Hinzufügen UINT_MAX + 1 zur unterschriebenen Vertretung.

    Wenn der neue Typ vorzeichenlos ist, wird der Wert konvertiert, indem wiederholt eins mehr als der maximale Wert, der im neuen Typ dargestellt werden kann, addiert oder subtrahiert wird, bis der Wert im Bereich des neuen Typs liegt.

    So -1 => -1 + (UINT_MAX + 1) = UINT_MAXfür dieses Szenario.

Benutzeravatar von CIsForCookies
CIsForCookies

Mein gcc gibt diese Warnung aus:

warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
      for(d = 0; d < TOTAL_ELEMENTS; d++) 

was bedeutet, dass (TOTAL_ELEMENTS-2) ist unsigned int während d ist signed int. Dies macht den Ausdruck immer false für den Anfangswert von dseit (unsigned int)(-1) > (TOTAL_ELEMENTS-2).

  • ja. Die Lektion: Immer alle Warnungen aktivieren und lesen

    – phuklv

    13. August 2017 um 11:47 Uhr

  • Der Ausdruck ist es nicht immer falschist es falsch für den Anfangswert von d.

    – chqrlie

    13. August 2017 um 14:14 Uhr


Binäre Operationen zwischen verschiedenen ganzzahligen Typen werden innerhalb eines “gemeinsamen” Typs durchgeführt, der durch sogenannte gewöhnliche arithmetische Umwandlungen definiert ist. Int d ist also vom singenden Typ, der mit dem Wert -1 initialisiert wird. Bei der Konvertierung in unsigned int wird ein Maximum von unsigned int zurückgegeben, das viel viel größer ist als der von TOTAL_ELEMENTS zurückgegebene Wert.

  • unsigned int in Ihrer Antwort sollte sein size_t. Abgesehen davon sind Sie auf dem Punkt.

    – StoryTeller – Unslander Monica

    13. August 2017 um 9:38 Uhr


1412110cookie-checkSchleife, die bei -1 beginnt, gibt nichts aus [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy