C Language
Datatyper
Sök…
Anmärkningar
- Medan
char
måste vara en byte, är ett byte behöver inte vara 8 bitar (ofta även kallad en oktett), även om de flesta moderna datorplattformar definiera det som 8 bitar. Implementeringens antal bitar perchar
tillhandahålls avCHAR_BIT
, definierad i<limits.h>
. POSIX kräver att 1 byte är 8 bitar. - Heltalstyper med fast bredd ska användas glesigt, C: s inbyggda typer är utformade för att vara naturliga i varje arkitektur, de fasta breddstyperna ska bara användas om du uttryckligen behöver ett specifikt heltal (till exempel för nätverk).
Heltalstyper och konstanter
Undertecknade heltal kan vara av dessa typer ( int
efter short
, eller long
är valfritt):
signed char c = 127; /* required to be 1 byte, see remarks for further information. */
signed short int si = 32767; /* required to be at least 16 bits. */
signed int i = 32767; /* required to be at least 16 bits */
signed long int li = 2147483647; /* required to be at least 32 bits. */
signed long long int li = 2147483647; /* required to be at least 64 bits */
Var och en av dessa signerade heltalstyper har en osignerad version.
unsigned int i = 65535;
unsigned short = 2767;
unsigned char = 255;
För alla typer men char
antas den signed
versionen om den signed
eller unsigned
delen utelämnas. char
utgör en tredje karaktärstyp som skiljer sig från signed char
och unsigned char
och signaturen (eller inte) beror på plattformen.
Olika typer av heltalskonstanter (kallas bokstäver i C-jargon) kan skrivas i olika baser och olika bredd, baserat på deras prefix eller suffix.
/* the following variables are initialized to the same value: */
int d = 42; /* decimal constant (base10) */
int o = 052; /* octal constant (base8) */
int x = 0xaf; /* hexadecimal constants (base16) */
int X = 0XAf; /* (letters 'a' through 'f' (case insensitive) represent 10 through 15) */
Decimalkonstanter är alltid signed
. Hexadecimala konstanter börjar med 0x
eller 0X
och oktala konstanter börjar bara med en 0
. De två senare är signed
eller unsigned
beroende på om värdet passar in i den signerade typen eller inte.
/* suffixes to describe width and signedness : */
long int i = 0x32; /* no suffix represent int, or long int */
unsigned int ui = 65535u; /* u or U represent unsigned int, or long int */
long int li = 65536l; /* l or L represent long int */
Utan ett suffix har konstanten den första typen som passar dess värde, det vill säga en decimalkonstant som är större än INT_MAX
är av typen long
om möjligt, eller long long
annars.
<limits.h>
beskriver gränserna för heltal på följande sätt. Deras implementeringsdefinerade värden ska vara lika eller större i storlek (absolut värde) som de som visas nedan, med samma tecken.
Makro | Typ | Värde |
---|---|---|
CHAR_BIT | minsta objekt som inte är ett bitfält (byte) | 8 |
SCHAR_MIN | signed char | -127 / - (2 7 - 1) |
SCHAR_MAX | signed char | +127 / 2 7 - 1 |
UCHAR_MAX | unsigned char | 255/2 8 - 1 |
CHAR_MIN | char | se nedan |
CHAR_MAX | char | se nedan |
SHRT_MIN | short int | -32767 / - (2 15 - 1) |
SHRT_MAX | short int | +32767 / 2 15 - 1 |
USHRT_MAX | unsigned short int | 65535/2 16 - 1 |
INT_MIN | int | -32767 / - (2 15 - 1) |
INT_MAX | int | +32767 / 2 15 - 1 |
UINT_MAX | unsigned int | 65535/2 16 - 1 |
LONG_MIN | long int | -2147483647 / - (2 31 - 1) |
LONG_MAX | long int | +2147483647 / 2 31 - 1 |
ULONG_MAX | unsigned long int | 4294967295/2 32 - 1 |
Makro | Typ | Värde |
---|---|---|
LLONG_MIN | long long int | -9223372036854775807 / - (2 63 - 1) |
LLONG_MAX | long long int | +9223372036854775807 / 2 63 - 1 |
ULLONG_MAX | unsigned long long int | 18446744073709551615/2 64 - 1 |
Om värdet på ett objekt av typen char
tecken utökas när det används i ett uttryck, ska värdet på CHAR_MIN
vara detsamma som det för SCHAR_MIN
och värdet på CHAR_MAX
ska vara detsamma som det för SCHAR_MAX
. Om värdet på ett objekt av typen char
inte signalerar ut när det används i ett uttryck, ska värdet på CHAR_MIN
vara 0 och värdet på CHAR_MAX
ska vara detsamma som det för UCHAR_MAX
.
C99-standarden har lagt till en ny rubrik, <stdint.h>
, som innehåller definitioner för heltal med fast bredd. Se fasta breddens heltalsexempel för en mer djupgående förklaring.
String Literals
En strängbokstavlig i C är en sekvens av tecken, avslutas med en bokstavlig noll.
char* str = "hello, world"; /* string literal */
/* string literals can be used to initialize arrays */
char a1[] = "abc"; /* a1 is char[4] holding {'a','b','c','\0'} */
char a2[4] = "abc"; /* same as a1 */
char a3[3] = "abc"; /* a1 is char[3] holding {'a','b','c'}, missing the '\0' */
Strängbokstäver är inte modifierbara (och kan faktiskt placeras i skrivskyddsminne som .rodata). Att försöka ändra sina värden resulterar i odefinierat beteende.
char* s = "foobar";
s[0] = 'F'; /* undefined behaviour */
/* it's good practice to denote string literals as such, by using `const` */
char const* s1 = "foobar";
s1[0] = 'F'; /* compiler error! */
Flera strängbokstäver är sammankopplade vid sammanställningstid, vilket innebär att du kan skriva konstruktioner som dessa.
/* only two narrow or two wide string literals may be concatenated */
char* s = "Hello, " "World";
/* since C99, more than two can be concatenated */
/* concatenation is implementation defined */
char* s1 = "Hello" ", " "World";
/* common usages are concatenations of format strings */
char* fmt = "%" PRId16; /* PRId16 macro since C99 */
Strängbokstäver, samma som karaktärskonstanter, stöder olika karaktärsuppsättningar.
/* normal string literal, of type char[] */
char* s1 = "abc";
/* wide character string literal, of type wchar_t[] */
wchar_t* s2 = L"abc";
/* UTF-8 string literal, of type char[] */
char* s3 = u8"abc";
/* 16-bit wide string literal, of type char16_t[] */
char16_t* s4 = u"abc";
/* 32-bit wide string literal, of type char32_t[] */
char32_t* s5 = U"abc";
Fast bredd heltalstyper (sedan C99)
Rubriken <stdint.h>
ger flera definitioner av heltal med fast bredd. Dessa typer är valfria och tillhandahålls endast om plattformen har en heltalstyp med motsvarande bredd, och om motsvarande signerad typ har en två komplementrepresentation av negativa värden.
Se kommentaravsnittet för bruksanvisningar för typer av fast bredd.
/* commonly used types include */
uint32_t u32 = 32; /* exactly 32-bits wide */
uint8_t u8 = 255; /* exactly 8-bits wide */
int64_t i64 = -65 /* exactly 64 bit in two's complement representation */
Flytande konstanter
C-språket har tre obligatoriska verkliga flytande punkttyper, float
, double
och long double
.
float f = 0.314f; /* suffix f or F denotes type float */
double d = 0.314; /* no suffix denotes double */
long double ld = 0.314l; /* suffix l or L denotes long double */
/* the different parts of a floating point definition are optional */
double x = 1.; /* valid, fractional part is optional */
double y = .1; /* valid, whole-number part is optional */
/* they can also defined in scientific notation */
double sd = 1.2e3; /* decimal fraction 1.2 is scaled by 10^3, that is 1200.0 */
Rubriken <float.h>
definierar olika gränser för flytande punktoperationer.
Flytande aritmetik definieras implementering. De flesta moderna plattformar (arm, x86, x86_64, MIPS) använder emellertid IEEE 754 flytande punktoperationer.
C har också tre valfria komplexa flytpunkttyper som härrör från ovan.
Tolkning av förklaringar
En distinkt syntaktisk egenhet hos C är att förklaringar speglar användningen av det deklarerade objektet som det skulle vara i ett normalt uttryck.
Följande uppsättning operatörer med identisk prioritet och associativitet återanvänds i deklaratorer, nämligen:
- den unary
*
"dereference" -operatören som anger en pekare; - den binära
[]
"array-abonnemang" -operatören som anger en matris; - operatören (1 + n) -ary
()
"funktionssamtal" som anger en funktion; -
()
gruppering av parenteser som åsidosätter företräde och associativitet hos resten av de listade operatörerna.
Ovanstående tre operatörer har följande prioritet och associativitet:
Operatör | Relativ företräde | associativitet |
---|---|---|
[] (arrayabonnemang) | 1 | Vänster till höger |
() (funktionssamtal) | 1 | Vänster till höger |
* (dereference) | 2 | Höger till vänster |
Vid tolkning av deklarationer måste man börja från identifieraren utåt och tillämpa de angränsande operatörerna i rätt ordning enligt tabellen ovan. Varje applikation av en operatör kan ersättas med följande engelska ord:
Uttryck | tolkning |
---|---|
thing[X] | en matris med storlek X av ... |
thing(t1, t2, t3) | en funktion som tar t1 , t2 , t3 och returnerar ... |
*thing | en pekare till ... |
Av detta följer att början på den engelska tolkningen alltid kommer att börja med identifieraren och slutar med den typ som står på vänster sida av deklarationen.
exempel
char *names[20];
[]
har företräde framför *
, så tolkningen är: names
är en matris med storlek 20 på en pekare till char
.
char (*place)[10];
Om du använder parenteser för att åsidosätta företräde, appliceras *
först: place
är en pekare till en matris med storlek 10 på char
.
int fn(long, short);
Det finns inget företräde att oroa sig för här: fn
är en funktion som tar long
, short
och återkommande int
.
int *fn(void);
()
Tillämpas först: fn
är en funktion som tar void
og återgår en pekare till int
.
int (*fp)(void);
Överstyrning av förekomsten av ()
: fp
är en pekare till en funktion som tar void
og återgår int
.
int arr[5][8];
Multidimensionella matriser är inte ett undantag från regeln; []
-operatörerna tillämpas i vänster-till-höger ordning enligt associativiteten i tabellen: arr
är en matris med storlek 5 av en matris med storlek 8 på int
.
int **ptr;
De två dereferensoperatörerna har samma prioritet, så associativiteten träder i kraft. Operatörerna appliceras i höger till vänster ordning: ptr
är en pekare till en pekare till en int
.
Flera förklaringar
Komman kan användas som en separator (* inte * som fungerar som kommatoperatören) för att avgränsa flera deklarationer i ett enda uttalande. Följande uttalande innehåller fem förklaringar:int fn(void), *ptr, (*fp)(int), arr[10][20], num;
De deklarerade objekt i exemplet ovan är:
-
fn
: en funktion som tarvoid
og återgårint
; -
ptr
: en pekare till enint
; -
fp
: en pekare till en funktion som tarint
och returnerarint
; -
arr
: en matris med storlek 10 av en matris med storlek 20 påint
; -
num
:int
.
Alternativ tolkning
Eftersom deklarationer speglar användning kan en deklaration också tolkas i termer av de operatörer som kan tillämpas över objektet och den slutliga resulterande typen av det uttrycket. Den typ som står på vänster sida är det slutliga resultatet som ges efter applicering av alla operatörer.
/*
* Subscripting "arr" and dereferencing it yields a "char" result.
* Particularly: *arr[5] is of type "char".
*/
char *arr[20];
/*
* Calling "fn" yields an "int" result.
* Particularly: fn('b') is of type "int".
*/
int fn(char);
/*
* Dereferencing "fp" and then calling it yields an "int" result.
* Particularly: (*fp)() is of type "int".
*/
int (*fp)(void);
/*
* Subscripting "strings" twice and dereferencing it yields a "char" result.
* Particularly: *strings[5][15] is of type "char"
*/
char *strings[10][20];