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 per char tillhandahålls av CHAR_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. */
C99
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
C99
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

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.

C99
/* only two narrow or two wide string literals may be concatenated */
char* s = "Hello, " "World";
C99
/* 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";
C11
/* 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)

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 tar void og återgår int ;
  • ptr : en pekare till en int ;
  • fp : en pekare till en funktion som tar int och returnerar int ;
  • 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];


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow