2015-07-11 6 views
5

Ich Analyse ein Szenario:Was ist der Wert von strlen (str) - 1 in einer For-Schleife, wenn str leer ist?

char str[] = ""; // Understand 

Wenn ich strlen(str) verstehen, es kommt 0. Dies ist in Ordnung zu sein.

printf(" %d, %ul, %u, %d, %ul, %u", 
    strlen(str), 
    strlen(str), 
    strlen(str), 
    strlen(str) - 1, 
    strlen(str) - 1, 
    strlen(str) - 1); 

Ausgang ist:

0, 0l, 0, -1, 4294967295l, 4294967295

ich diese auch verstehen.

for (int i = 0; i < strlen(str) - 1; i++) 
{ 
} 

Hier verstehe ich nicht, was der Wert von strlen(str) - 1 im for Schleifenbedingung wäre.

strlen(str) - 1 gibt den Wert 4294967295 in der for-Schleife. Warum ist das? Warum nicht -1?

+1

Angst vor Debugger neu schreiben? Versuche zu treten! – Olaf

+0

Ich trete auch ein. In gdb, wenn ich p strlen (str) -1 mache, gibt dies mir einen int-Wert. Ich versuche nur zu verstehen, was der Wert in der for-Schleife ist. Ich habe überprüft, dass strlen (str) 0 ist, sogar im for-loop-Zustand. strlen (str) -1 ist 4294967295 ... warum passiert das? –

+0

Überprüfen Sie, welcher Ergebnistyp 'strlne' tatsächlich zurückgibt. Dann lesen Sie im [Standard] (http://port70.net/~nsz/c/c11/n1570.html), wie sich dieser Typ auf Unterlauf verhält (Hinweis: es ist _well defined_). Dann können Sie Ihre Frage selbst beantworten. Hinweis: "Ich" hat den falschen Typ! – Olaf

Antwort

3

Diese Aussage

printf(" %d, %ul, %u, %d, %ul, %u", strlen(str),strlen(str),strlen(str),strlen(str)-1,strlen(str)-1,strlen(str)-1); 

zeigt, dass, wenn strlen(str) - 1 wie unsigned integer beispielsweise unter Verwendung von Format-Spezifizierer %ul seinen Wert 4294967295l ist

outputed ist

In dem Zustand der Schleife

for (int i=0;i<strlen(str)-1;i++) 

die Der Compiler muss den gemeinsamen Typ der linken und rechten Operanden bestimmen, um die Ty zu bestimmen pe des Ergebnisses der Bedingung

i<strlen(str)-1 

Der rechte Operand strlen(str)-1size_t Typ hat (der Rückgabetyp der Funktion strlen ist size_t). Es ist in der Regel ein vorzeichenloser Integer-Typ, der unsigned long entspricht. Es kann keine negativen Werte haben. Jeder Wert, der in einem Objekt dieses Typs gespeichert ist, wird als nicht-negativer Wert interpretiert und als Ausgabe zeigt der Wert strlen(str)-1 gleich 4294967295l. (Der tatsächliche Wert kann man erhalten, wenn Sie Typspezifizierer verwendet %zu weil nicht ausgeschlossen werden kann, dass size_t lang sogar in unsigned long entsprechen kann)

Der rechte Operand hat int eingeben. Ihr Rang ist mindestens nicht größer als der Rang von size_type. Daher werden die beiden Operanden in den Typ size_t konvertiert und haben nicht negative Werte.

Diese Prozedur zur Bestimmung des gemeinsamen Typs wird als die üblichen arithmetischen Umwandlungen bezeichnet. Es ist offensichtlich, dass 4294967295l größer als 0 ist. So wird die Schleife 4294967295l mal durchlaufen, wenn es keine break-Anweisung hat.

Sie könnten das erwartete Ergebnis, wenn man die Bedingung in der Schleife die folgende Art und Weise

for (int i = 0; i < (int)strlen(str) - 1; i++) 
+0

Was ist der Kleinbuchstabe 'l' für '4294967295'? –

16

strlen gibt size_t zurück, das eine vorzeichenlose Ganzzahl ist. So würde strlen(str)-1SIZE_MAX produzieren (der maximale Wert size_t kann halten) wenn strlen(str)0 ist.

Sie sollten %zu verwenden, um size_t Werte zu drucken.

Verwandte Themen