2016-04-12 9 views
0

Ich verwende Codeblocks und den GNU-Compiler auf einem Windows-Computer. Wenn der Compiler läuft, tut sie dies unter den folgenden Bedingungen:Wie verwende ich größere Ganzzahlen in einem C-Programm?

mingw32-gcc.exe -Wall -g -std=c11 <filename> -o obj\Debug\main.o 

Mein Code ist wie folgt:

#include <stdio.h> 
#include <limits.h> 

int main() 
{ 
    printf("INTEGER min: %d\n", INT_MIN); 
    printf("INTEGER max: %d\n\n", INT_MAX); 
    printf("UNSIGNED INTEGER max: %u\n\n", UINT_MAX); 
    printf("LONG INTEGER min: %ld\n", LONG_MIN); 
    printf("LONG INTEGER max: %ld\n\n", LONG_MAX); 
    //printf("LONG LONG INTEGER min: %lld\n", LONG_LONG_MIN); 
    //printf("LONG LONG INTEGER max: %lld\n\n", LONG_LONG_MAX); 
    printf("UNSIGNED LONG INTEGER max: %lu\n\n", ULONG_MAX); 
    //printf("UNSIGNED LONG LONG INTEGER max: %lld\n", ULONG_LONG_MAX); 
    printf("\n"); 
    return 0; 
} 

Meine Ausgabe für diesen Code:

INTEGER min: -2147483648 
INTEGER max: 2147483648 

UNSIGNED INTEGER max: 4294967295 

LONG INTEGER min: -2147483648 
LONG INTEGER max: 2147483648 

UNSIGNED LONG INTEGER max: 4294967295 

Die Linien unter Bezugnahme auf LONG LONG Ganzzahlen sind auskommentiert, weil der Compiler Fehler ausgegeben hat:

error: 'LONG_LONG_MIN' undeclared (first use in this function) 
error: 'LONG_LONG_MAX' undeclared (first use in this function) 
error: 'ULONG_LONG_MAX' undeclared (first use in this function) 

CodeBlocks lieferte Code-Hinweise während der Eingabe des Codes Code, der angibt, dass ich tatsächlich die LONG_LONG-Konstanten verwenden konnte. Daher brauche ich Antworten auf die folgenden Fragen:

  1. Warum haben die ganzen Zahlen und lange Ganzzahlen die gleichen Grenzen? Sollten die langen Ganzzahlen nicht einen größeren Wertebereich haben?
  2. Warum habe ich Probleme mit den LONG_LONG Konstanten? Bedeutet das, dass ich keine langen ganzen Zahlen verwenden kann?

Dank

+0

Mögliche doppelte Frage. Schauen Sie sich http://StackOverflow.com/questions/13590735/printf-long-long-int-in-c-with-gcc –

+0

@JamesMcCormac: verwandt, aber definitiv eine andere Frage. –

Antwort

9

Die Konstanten, die Sie suchen sind LONG_LONG_... nicht genannt. Überprüfen Sie Ihre limits.h Kopfzeile. Wahrscheinlich sind Sie nach ULLONG_MAX, LLONG_MAX usw.

+0

Danke ... das hat die zweite Frage gelöst. Wie steht es aber mit dem ersten? –

+0

Auch habe ich die LONG_LONG Konstanten von 'limits.h'. Es enthält beide Sätze von Konstanten. Offensichtlich habe ich keine Ahnung warum. :) –

4

Die Konstanten sind LLONG_MAX, ULLONG_MAX usw.

Wie, warum int und long int den gleichen Wert haben, die Schuld der C-Standard: es ist kein definieren feste Anzahl von Bits für jeden Datentyp, nur die minimale Anzahl von Bits:

  • int müssen mindestens 16 Bits
  • long int sein muss, eine sein, t mindestens 32 Bits
  • long long int müssen mindestens 64 Bits

Die genaue Anzahl von Bits unterscheiden sich von OS OS sein.

#include <stdio.h> 
#include <limits.h> 

int main() 
{ 
    printf("INTEGER min: %d\n", INT_MIN); 
    printf("INTEGER max: %d\n\n", INT_MAX); 
    printf("UNSIGNED INTEGER max: %u\n\n", UINT_MAX); 
    printf("LONG INTEGER min: %ld\n", LONG_MIN); 
    printf("LONG INTEGER max: %ld\n\n", LONG_MAX); 
    printf("LONG LONG INTEGER min: %lld\n", LLONG_MIN); 
    printf("LONG LONG INTEGER max: %lld\n\n", LLONG_MAX); 
    printf("UNSIGNED LONG INTEGER max: %lu\n\n", ULONG_MAX); 
    printf("UNSIGNED LONG LONG INTEGER max: %llu\n", ULLONG_MAX); 
    printf("\n"); 
    return 0; 
} 

Auf meinem Mac OS X, 64-bit, dass Drucke:

INTEGER min: -2147483648 
INTEGER max: 2147483647 

UNSIGNED INTEGER max: 4294967295 

LONG INTEGER min: -9223372036854775808 
LONG INTEGER max: 9223372036854775807 

LONG LONG INTEGER min: -9223372036854775808 
LONG LONG INTEGER max: 9223372036854775807 

UNSIGNED LONG INTEGER max: 18446744073709551615 

UNSIGNED LONG LONG INTEGER max: 18446744073709551615 

Edit: wenn Sie portablen Code schreiben möchten und haben mit fester Breite ganzen Zahlen, verwenden stdint.h :

#include <stdint.h> 

printf("int64_t max : %lld\n\n", INT64_MAX); // 9223372036854775807 
printf("uint64_t max: %llu\n\n", UINT64_MAX); // 18446744073709551615 
+0

Ok. Nach dem Fixieren der langen langen Konstanten, bekomme ich den gleichen Wert, den du für lange lange ganze Zahlen zeigst. Also, im Grunde, wenn ich eine Ganzzahl größer als INTEGER verwenden muss, muss ich LANG LANG INTEGER verwenden? –

+0

Siehe meine bearbeitete Antwort –

+0

Vielen Dank ... das ist sehr hilfreich. –

2

Warum haben die ganzen Zahlen und langen ganzen Zahlen dieselben Grenzen? Sollten die langen Ganzzahlen nicht einen größeren Wertebereich haben?

Sie sind in eines der Kennzeichen der C-Sprache eingetreten - ihre Anpassungsfähigkeit.

C definiert der Bereich der int mindestens so breit wie short und der Bereich von long zu sein, zumindest so breit wie int zu sein. Alle haben minimale Reichweiten.

Anstatt den Bereich von short, int, long genau zu definieren, entschied sich C für Vielseitigkeit. Auf der OP-Plattform entspricht der Bereich int dem Bereich long (32-Bit). Auf vielen Embedded-Prozessoren von 2016 (und Heimcomputer der 70er, 80er Jahre) entspricht der Bereich von int dem Bereich von short (16-Bit). Auf einigen Plattformen (64-Bit) überschreitet der Bereich von intshort und schmäler alslong. Also direkt zur OP-Frage: int hat nicht immer den gleichen Bereich wie long.

Der Trick ist, dass int nicht nur ein weiterer Strompfad der singed char, short, int, long, long long Leiter ist. Es ist der Integer-Typ. Angesichts der üblichen Integer-Promotionen, fördern alle schmalen Typen int. int ist oft die native Bitbreite des Prozessors.

Die meisten Code wurde mit int als 32-Bit und auch ein großer Prozentsatz als 16-Bit geschrieben. Mit 64-Bit-Prozessoren ist es möglich, int als 64-Bit zu haben, aber das lässt nur 2 Standardtypen für signed char, short für 8, 16 und 32-Bit übrig.

Auch in Zukunft einfache Zählung auf signed char Bereich <= den short Bereich, short Bereich <= die int Bereich, int Bereich <= den long Bereich, etc. Auch die signed char mindestens 8-bit, short, int mindestens 16- Bit, long mindestens 32-Bit, long long mindestens 64-Bit. Wenn der Code explizite Breiten benötigt, verwenden Sie int8_t, int16_t, usw.

Die Tatsache, dass C 40+ Jahre später verwendet wird, bestätigt, dass diese Vielseitigkeit Vorteile hat.

[Die Diskussion enthält unsigned Typen, _Bool_t und char der Kürze halber. Ebenfalls weggelassen sind seltene Nicht-Power-of-2-Typen (9, 18, 24, 36 usw.)]

+1

Beachten Sie auch, dass Windows den Dummy [LLP64] (https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models) ausgewählt hat. Bei LP64 (gewählt von den meisten Linux-Systemen) sind Longs 64-Bit-Integer. – jdarthenay

+0

@jdarthenay Danke für die nützliche Referenz. – chux

1

Neben limits.h auf einem System mit spezifischer Implementierung, überprüfen Sie auch, was der C-Standard die Grenzen definiert die verschiedenen Ganzzahlen:

Die unten angegebenen Werte müssen durch konstante Ausdrücke ersetzt werden, die für die Verwendung in #if Vorverarbeitungsrichtlinien geeignet sind. Mit Ausnahme von CHAR_BIT und MB_LEN_MAX soll der folgende Ausdruck durch Ausdrücke ersetzt werden, die denselben Typ haben wie ein Ausdruck , der ein Objekt des entsprechenden Typs ist, der gemäß der Ganzzahl Promotions konvertiert wurde.Ihre Umsetzung definierte Werte sind gleich groß oder größer sein

(absolute value) to those shown, with the same sign. 
-- number of bits for smallest object that is not a bit-field (byte) 
    CHAR_BIT           8 
-- minimum value for an object of type signed char 
    SCHAR_MIN        -127 // -(27 - 1) 
-- maximum value for an object of type signed char 
    SCHAR_MAX        +127 // 27 - 1 
-- maximum value for an object of type unsigned char 
    UCHAR_MAX         255 // 28 - 1 
-- minimum value for an object of type char 
    CHAR_MIN        see below 
-- maximum value for an object of type char 
    CHAR_MAX        see below 
-- maximum number of bytes in a multibyte character, for any supported locale 
    MB_LEN_MAX         1 
-- minimum value for an object of type short int 
    SHRT_MIN        -32767 // -(215 - 1) 
-- maximum value for an object of type short int 
    SHRT_MAX        +32767 // 215 - 1 
-- maximum value for an object of type unsigned short int 
    USHRT_MAX        65535 // 216 - 1 
-- minimum value for an object of type int 
    INT_MIN         -32767 // -(215 - 1) 
-- maximum value for an object of type int 
    INT_MAX        +32767 // 215 - 1 
-- maximum value for an object of type unsigned int 
    UINT_MAX        65535 // 216 - 1 
-- minimum value for an object of type long int 
    LONG_MIN       -2147483647 // -(231 - 1) 
-- maximum value for an object of type long int 
    LONG_MAX       +2147483647 // 231 - 1 
-- maximum value for an object of type unsigned long int 
    ULONG_MAX       4294967295 // 232 - 1 
-- minimum value for an object of type long long int 
    LLONG_MIN   -9223372036854775807 // -(263 - 1) 
-- maximum value for an object of type long long int 
    LLONG_MAX   +9223372036854775807 // 263 - 1 
-- maximum value for an object of type unsigned long long int 
    ULLONG_MAX   18446744073709551615 // 264 - 1 

Von http://www.iso-9899.info/n1570.html#5.2.4.2.1