Schleife, die bei -1 beginnt, gibt nichts aus [duplicate]
Lesezeit: 4 Minuten
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
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:
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.
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.
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
14121100cookie-checkSchleife, die bei -1 beginnt, gibt nichts aus [duplicate]yes
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 -Wextra
zumindest für Visual C(++)./W3
vorzugsweise/W4
zumindest bei der Fehlersuche.– Hyde
13. August 2017 um 6:17 Uhr