C-typesystemet er en implementering af konceptet for en datatype i programmeringssproget C. Sproget i sig selv giver grundlæggende aritmetiske typer samt en syntaks til at skabe arrays og sammensatte typer. Nogle header-filer fra C-standardbiblioteket indeholder typedefinitioner med yderligere egenskaber [1] [2] .
C-sproget giver mange grundlæggende typer. De fleste af dem er dannet ved hjælp af en af fire aritmetiske typespecifikationer, ( char, int, floatog double) og valgfrie specifikatorer ( signed, unsigned, shortog long). Selvom standarden specificerer et område beregnet ud fra formlen fra −(2 n−1 −1) til 2 n−1 −1 , tillader alle kendte compilere ( gcc , clang og Microsoft compiler ) intervallet fra −(2 n−1 ) til 2 n −1 −1 , hvor n er typens bitbredde.
Tabellen nedenfor antager, at 1 byte = 8 bit.
På langt de fleste moderne platforme er dette sandt, men det er muligt, at 1 byte er lig med 16 bit eller et andet tal, normalt en potens på to.
Type | Forklaring | Formatspecifikation |
---|---|---|
char | Heltal, den mindst mulige adresserbare type. Kan indeholde basistegnsættet. Kan være enten underskrevet eller usigneret, implementeringsafhængig. Indeholder CHAR_BIT(normalt 8) bits. [3] | %c |
signed char | Samme størrelse som char, men er garanteret signeret. Kan tage værdier fra mindst området [−127, +127][3] , normalt i implementeringer [4][−128, +127] | %c (også %deller %hhi( %hhx, %hho) for numerisk output) |
unsigned char | Samme størrelse som char, men er garanteret usigneret. Rækkevidde: [3] . Som regel,[0, 2CHAR_BIT − 1][0, 255] | %c (eller %hhufor numerisk output) |
short short int signed short signed short int |
Typen af et fortegnet kort heltal. Kan indeholde tal fra mindst området [−32767, +32767][3] , typisk i [4] implementeringer . Så det er mindst 16 bit (2 bytes).[−32768, +32767] | %hi |
unsigned short unsigned short int |
Samme som shortmen usigneret. Rækkevidde:[0, +65535] | %hu |
int signed signed int |
Den grundlæggende type af et signeret heltal. Kan indeholde tal fra mindst området [−32767, +32767][3] . Så det er mindst 16 bit (2 bytes). Typisk 4 bytes i størrelse og rækkevidde på moderne compilere til 32-bit og højere platforme [−2 147 483 648, +2 147 483 647], men typisk 2 bytes i rækkevidde på 16- og 8-bit platforme [−32768, +32767], hvilket ofte forårsager forvirring og fører til inkompatibilitet dårligt skrevet kode | %ieller%d |
unsigned unsigned int |
Samme som intmen usigneret. Rækkevidde:[0, +4 294 967 295] | %u |
long long int signed long signed long int |
Signeret lang heltal type . Kan indeholde tal i det mindste i området [−2 147 483 647, +2 147 483 647]. [3] [4] [5] Så det er mindst 32 bit (4 bytes). | %lieller%ld |
unsigned long unsigned long int |
Samme som longmen usigneret. Rækkevidde:[0, +4 294 967 295] | %lu |
long long long long int signed long long signed long long int |
Den lange lange ( dobbelt lange ) fortegnede heltalstype. Kan indeholde tal i det mindste i området [−9 223 372 036 854 775 808, +9 223 372 036 854 775 807]. [3] [4] Så det er mindst 64 bit. Godkendt i C99-standarden . |
%llieller%lld |
unsigned long long unsigned long long int |
Ligner long longmen usigneret. Rækkevidde [0, 18 446 744 073 709 551 615]:. | %llu |
float | En type reelt flydende decimaltal, almindeligvis omtalt som en enkeltpræcisions flydende taltype. Detaljerede egenskaber er ikke specificeret i standarden (bortset fra minimumsgrænser), men på de fleste systemer er det IEEE 754 enkelt-præcision flydende-komma binære format . Dette format er påkrævet for valgfri Annex F "IEC 60559 flydende komma aritmetik" flydende komma aritmetik. | %f (konverteres automatisk til doublefor printf()) |
double | En ægte flydende-komma-type, almindeligvis omtalt som en flydende-komma-type med dobbelt præcision. På de fleste systemer overholder IEEE 754 dobbeltpræcision binært flydende komma-format . | %f( %F)
( %lf( %lF) for scanf()) |
long double | En rigtig flydende taltype, normalt afbildet til det højpræcise flydende talformat. I modsætning til og , kan være 80-bit flydende komma, ikke-IEEE "dobbelt-dobbelt" eller "IEEE 754 quad-præcision binært flydende komma". Hvis der ikke er angivet et mere præcist format, svarer det til . Se artiklen om long double for detaljer.floatdoubledouble | %Lf %LF %Lg %LG %Le %LE[6] |
Følgende typespecifikationer blev heller ikke nævnt: ( %sfor strenge, %pfor pointere, %x( %X) for hexadecimal repræsentation, %ofor oktal.
Den faktiske størrelse af heltalstyper er implementeringsafhængig. Standarden fastlægger kun forholdet i størrelse mellem typer og minimumsramme for hver type:
Så long longmå ikke være mindre long, som igen må ikke være mindre int, som igen må være mindre short. Da char det er den mindst mulige adresserbare type, kan ingen andre typer være mindre end den.
Minimumsstørrelsen for char er 8 bit, for shortog int er 16 bit, for long er 32 bit, og for long long er 64 bit.
Det er ønskeligt, at typen inter en heltalstype, som processoren arbejder mest effektivt med. Dette giver mulighed for høj fleksibilitet, for eksempel kan alle typer være 64 bit. Der er dog populære skemaer, der beskriver størrelserne af heltalstyper. [7]
I praksis betyder det, at det chartager 8 bits i stedet shortfor 16 bits (ligesom deres usignerede modstykker). intpå de fleste moderne platforme tager det 32 bit i stedet long longfor 64 bit. Længden longvarierer: for Windows er det 32 bit, for UNIX-lignende systemer er det 64 bit.
C99-standarden inkluderer nye rigtige typer: float_tog double_t, defineret i <math.h>. Det omfatter også komplekse typer: float _Complex, double _Complex, long double _Complex.
Den boolske type blev tilføjet i C99_Bool . Desuden definerer en ekstra header-fil <stdbool.h>et alias for den bool, såvel som makroer true(sand) og false(falsk). _Boolopfører sig ligesom en normal indbygget type, med én undtagelse: enhver ikke-null (ikke-falsk) tildeling _Boolgemmes som en. Denne adfærd beskytter mod overløb. For eksempel:
usigneret char b = 256 ; hvis ( b ) { /* gør noget */ }bbetragtes som falsk, hvis det unsigned chartager 8 bit. Ændring af typen gør imidlertid variablen sand:
_Bool b = 256 ; hvis ( b ) { /* gør noget */ }C-sprogspecifikationen inkluderer typebetegnelser (typedef) size_tog ptrdiff_t. Deres størrelse bestemmes i forhold til processorens aritmetiske evner. Begge disse typer er defineret i <stddef.h>( cstddeffor C++).
size_t er en heltalstype uden fortegn designet til at repræsentere størrelsen af ethvert objekt i hukommelsen (inklusive arrays) i en bestemt implementering. Operatøren sizeofreturnerer en værdi af type size_t. Den maksimale størrelse size_ter skrevet i en makrokonstant SIZE_MAXdefineret i <stdint.h>( cstdintfor C++). size_tskal være mindst 16 bit. Derudover inkluderer POSIX ssize_t, som er en indbygget signeret type størrelse size_t.
ptrdiff_t er en indbygget signeret type, der definerer forskellen mellem pointere. Den virker med garanti på pointere af samme type. Aritmetik mellem pointere af forskellige typer er implementeringsafhængig.
Oplysninger om de faktiske egenskaber, såsom størrelse, af de grundlæggende indbyggede typer gives gennem makrokonstanter i to overskrifter: en header <limits.h>( climitsi C++) definerer makroer for heltaltyper, en header <float.h>( cfloati C++) definerer makroer for reelle typer. Specifikke værdier er implementeringsafhængige.
Egenskaber for heltalstyperC99-standarden indeholder definitioner for flere nye heltalstyper for at forbedre programportabiliteten. [2] De heltalsbasetyper, der allerede var tilgængelige, blev betragtet som utilfredsstillende, fordi deres størrelse var implementeringsafhængig. De nye typer er meget brugt i indlejrede systemer. Alle nye typer er defineret i en header-fil <inttypes.h>( cinttypesi C++) og er også tilgængelige i <stdint.h>( cstdinti C++). Typer kan opdeles i følgende kategorier:
Følgende tabel viser disse typer ( N står for antallet af bits):
Type kategori | Signerede typer | Usignerede typer | ||||
---|---|---|---|---|---|---|
Type | Minimumsværdi | Maksimal værdi | Type | Minimumsværdi | Maksimal værdi | |
Præcis størrelse | intN_t | INTN_MIN | INTN_MAX | uintN_t | 0 | UINTN_MAX |
Minimum størrelse | int_leastN_t | INT_LEASTN_MIN | INT_LEASTN_MAX | uint_leastN_t | 0 | UINT_LEASTN_MAX |
hurtigste | int_fastN_t | INT_FASTN_MIN | INT_FASTN_MAX | uint_fastN_t | 0 | UINT_FASTN_MAX |
Pointer | intptr_t | INTPTR_MIN | INTPTR_MAX | uintptr_t | 0 | UINTPTR_MAX |
Maksimal størrelse | intmax_t | INTMAX_MIN | INTMAX_MAX | uintmax_t | 0 | UINTMAX_MAX |
Header-filen <inttypes.h>( cinttypesi C++) udvider mulighederne for de typer, der er defineret i <stdint.h>. De omfatter makroer, der definerer typespecifikationer for printf- og scanf-formatstrengen, og flere funktioner, der fungerer på intmax_tog -typerne uintmax_t. Denne overskriftsfil blev tilføjet i C99 .
printf-formatstrengMakroer er defineret i formatet . Her betyder {fmt} outputformatet og tilhører (decimal), (hexadecimal), (oktal), (ufortegn) eller (heltal). {type} angiver typen af argumentet og hører til , , , eller , hvor er antallet af bits. PRI{fmt}{type}dxouiNFASTNLEASTNPTRMAXN
scanf-formatstrengMakroer er defineret i formatet . Her betyder {fmt} outputformatet og tilhører (decimal), (hexadecimal), (oktal), (ufortegn) eller (heltal). {type} angiver typen af argumentet og hører til , , , eller , hvor er antallet af bits. SCN{fmt}{type}dxouiNFASTNLEASTNPTRMAXN
FunktionerStrukturer i C giver dig mulighed for at gemme flere felter i en enkelt variabel. Kan kaldes optegnelser eller tuples på andre sprog. For eksempel gemmer denne struktur en persons navn og fødselsdato:
struktur fødselsdag { char navn [ 20 ]; int dag ; int måned ; int år ; };Strukturdeklarationer i et programs brødtekst skal altid begynde med nøglestrukturen ( valgfrit i C++). Strukturmedlemmer tilgås ved hjælp af operatøren . eller -> , hvis vi arbejder med en pointer til en struktur. Strukturer kan indeholde pointere til sig selv, hvilket gør det muligt at implementere mange datastrukturer baseret på linkede lister. Denne mulighed kan virke modstridende, men alle pointere optager det samme antal bytes, så størrelsen af dette felt vil ikke ændre sig med antallet af strukturfelter.
Strukturer optager ikke altid antallet af bytes, der er lig med summen af deres elementers bytes. Compileren justerer normalt elementer i blokke på 4 bytes. Det er også muligt at begrænse antallet af bit, der er allokeret til et bestemt felt, for dette skal du angive feltstørrelsen i bit efter feltnavnet, adskilt af et kolon. Denne funktion giver dig mulighed for at oprette bitfelter .
Nogle funktioner i strukturer:
For hver type T , bortset fra tomrum og funktionstyper, er der en "array af N elementer af typen T ". Et array er en samling af værdier af samme type gemt sekventielt i hukommelsen. En matrix af størrelse N indekseres med et heltal fra 0 til N-1 . Arrays er også mulige med en størrelse ukendt for compileren. Størrelsen af et array skal være en konstant. Eksempler
int kat [ 10 ] = { 5 , 7 , 2 }; // række af 10 elementer, hver af typen int int bob []; // array med et ukendt antal elementer af typen 'int'.Arrays kan initialiseres med en initialiseringsliste, men kan ikke tildeles hinanden. Arrays sendes til funktioner ved hjælp af en pointer til det første element (navnet på arrayet er adressen på det første element). Multidimensionelle arrays er arrays af arrays. Eksempler:
int a [ 10 ][ 8 ]; // matrix af 10 elementer, hver af typen 'array af 8 int elementer' float f [][ 32 ] = {{ 0 },{ 4 , 5 , 6 }};For enhver type T er der en type "pointer to T ".
Variabler kan erklæres som pointere til værdier af forskellige typer ved hjælp af *. For at definere typen af en variabel som en pointer, skal du foran dens navn med en stjerne.
char bogstav C = 'C' ; char * bogstav = & bogstav C ; //at tage adressen på bogstavet C og tildele det til bogstavet printf ( "Denne kode er skrevet i %c." , * bogstavet ); //"Denne kode er skrevet i C."Ud over standardtyper kan du erklære pejlemærker til strukturer og fagforeninger:
struct Punkt { int x , y ; } A ; A. _ x = 12 ; A. _ y = 34 _ struct Punkt * p = & A ; printf ( "X: %d, Y: %d" , ( * p ). x , ( * p ). y ); //"X: 12, Y: 34"For at få adgang til felterne i en struktur ved hjælp af markøren er der en pileoperator ->, synonymt med den forrige post: (*p).x - den samme som p->x.
Da en pointer også er en type variabel, gælder reglen "for enhver type T " også for dem: du kan erklære pointere til pointere. For eksempel kan du bruge int***:
int w = 100 ; int * x = & w ; int ** y = & x ; int *** z = & y ; printf ( "w indeholder %d." , *** z ); //"w indeholder 100."Der er også pointere til arrays og til funktioner. Array-pointere har følgende syntaks:
char * pc [ 10 ]; // række af 10 pointere til char char ( * pa )[ 10 ]; // peger på en matrix med 10 tegnvariablerpc - et array af pointere, der optager en 10 * sizeof(char*)byte (på almindelige platforme - normalt 40 eller 80 bytes), og pa - dette er én pointer; det optager normalt 4 eller 8 bytes, men det giver dig adgang til et array, der optager 10 bytes: sizeof(pa) == sizeof(int*)men sizeof(*pa) == 10 * sizeof(char). Pointere til arrays adskiller sig fra pointere til det første element i aritmetik. For eksempel, hvis pointerne papeger på adresse 2000, vil markøren pa+1pege på adresse 2010.
char ( * pa )[ 10 ]; char array [ 10 ] = "Wikipedia" ; pa = & array ; printf ( "Et eksempel for %s. \n " , * pa ); //"Et eksempel til Wikipedia." printf ( "%c %c %c" , ( * pa )[ 1 ], ( * pa )[ 3 ], ( * pa )[ 7 ]); //"ii i"Fagforeninger er specielle strukturer, der tillader forskellige felter at dele en fælles hukommelse. Det er således kun et af felterne, der kan gemmes i fagforeningen. Fagforeningens størrelse er lig med størrelsen af det største felt. Eksempel:
union { int i ; flyde f ; struct { usigneret int u ; dobbelt d ; } s ; } u ;I eksemplet ovenfor uer størrelsen u.s(hvis størrelse er summen af u.s.uog u.s.d), da s er større end iog f. At læse fra en fagforening involverer ikke typekonverteringer.
Enums giver dig mulighed for at definere brugerdefinerede typer i din kode. Eksempel:
enum { rød , grøn = 3 _ blå } farve ;Enums forbedrer kodens læsbarhed, men de er ikke typesikre (for eksempel er for system 3 og grøn det samme. I C ++ blev enum-klasser introduceret for at rette op på denne mangel), da de er heltal. I dette eksempel er værdien af rød nul, og værdien af blå er fire.
Funktionsmarkører giver dig mulighed for at videregive en funktion til en anden og implementere en tilbagekaldsmekanisme . Funktionsmarkører giver dig mulighed for at henvise til funktioner med en bestemt signatur. Et eksempel på oprettelse af en pointer til en funktion abs, der tager en int og returnerer en int ved navn my_int_f:
int ( * my_int_f )( int ) = & abs ; // operatoren & er valgfri, men gør det tydeligt ved eksplicit at vise, at vi videregiver en adresseFunktionsmarkører kaldes ved navn ligesom normale funktionskald. Funktionsmarkører er adskilt fra almindelige pointere og pointere til ugyldige.
Mere komplekst eksempel:
char ret_a ( int x ) { returner 'a' + x ; } typedef char ( * fptr )( int ); fptr another_func ( float a ) { returnere & ret_a ; }Her har vi for nemheds skyld lavet et alias kaldet fptr for en pointer til en funktion, der returnerer en char og tager en int. Uden typedef ville syntaksen være sværere at læse:
char ret_a ( int x ) { returner 'a' + x ; } char ( * func ( float a , int b ))( int ) { char ( * fp )( int ) = & ret_a ; returnere fp ; } char ( * ( * superfunc ( double a ))( float , int ))( int ) { char ( * ( * fpp )( float , int ))( int ) =& func ; returnere fpp ; }Func-funktionen returnerer ikke et tegn, som det kan se ud, men en pointer til en funktion, der returnerer et tegn og accepterer en int. Og accepterer float og int.
Ovenstående typer kan have forskellige typekvalifikationer. Ifølge C11 -standarden er der fire typekvalifikationer:
Også siden standard 99 er der tilføjet en funktionskvalifikation inline, som er et hint til compileren om at inkludere kode fra funktionens krop i stedet for at kalde selve funktionen.
En variabel kan have flere kvalifikationer. Eksempel:
const flygtig int a = 5 ; flygtig int const * b = &a ; //pointer til const flygtig int int * const c = NULL ; // const pointer til intDer er også fire opbevaringsklasser i C:
C programmeringssprog | |
---|---|
Kompilere |
|
Biblioteker | |
Ejendommeligheder | |
Nogle efterkommere | |
C og andre sprog |
|
Kategori:C programmeringssprog |