Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Typkvalificerare ger en av två egenskaper till en identifierare. Typkvalificeraren const deklarerar att ett objekt inte kan modifieras. Typkvalificeraren volatile deklarerar ett objekt vars värde kan ändras av något som ligger utanför kontrollen för programmet där det visas, till exempel en tråd som körs samtidigt.
Typkvalificerarna , const, restrictoch volatile, kan bara visas en gång i en deklaration. Typkvalificerare kan visas med valfri typspecificerare. De kan dock inte visas efter det första kommatecknet i en deklaration med flera objekt. Följande deklarationer är till exempel lagliga:
typedef volatile int VI;
const int ci;
Dessa deklarationer är inte lagliga:
typedef int *i, volatile *vi;
float f, const cf;
Typkvalificerare är endast relevanta vid åtkomst till identifierare som l-värden i uttryck. Mer information om l-värden och uttryck finns i L-Value och R-Value Expressions .
Syntax
type-qualifier:
const
restrict
volatile
const och volatile
Följande är juridiska const och volatile deklarationer:
int const *p_ci; // Pointer to constant int
int const (*p_ci); // Pointer to constant int
int *const cp_i; // Constant pointer to int
int (*const cp_i); // Constant pointer to int
int volatile vint; // Volatile integer
Om specifikationen för en matristyp innehåller typkvalificerare är elementet kvalificerat, inte matristypen. Om specifikationen för funktionstypen innehåller kvalificerare är beteendet odefinierat.
volatile och const påverkar inte objektets värdeintervall eller aritmetiska egenskaper.
Nyckelordet
constkan användas för att ändra en grundläggande eller aggregerad typ, eller en pekare till ett objekt av någon typ eller entypedef. Om ett objekt deklareras med endastconsttypkvalificeraren anses dess typ vara const int. Enconstvariabel kan initieras eller placeras i en skrivskyddad lagringsregion. Nyckelordetconstär användbart för att deklarera pekare tillconsteftersom det kräver att funktionen inte ändrar pekaren på något sätt.Kompilatorn förutsätter att en
volatilevariabel när som helst i programmet kan nås av en okänd process som använder eller ändrar dess värde. Oavsett vilka optimeringar som anges på kommandoraden måste koden för varje tilldelning till eller referens för envolatilevariabel genereras även om den inte verkar ha någon effekt.
Om volatile används ensamt int antas. Typspecificeraren volatile kan användas för att ge tillförlitlig åtkomst till särskilda minnesplatser. Använd volatile med dataobjekt som kan kommas åt eller ändras av signalhanterare, genom att köra program samtidigt eller av särskild maskinvara som minnesmappade I/O-kontrollregister. Du kan deklarera en variabel som volatile för dess livslängd, eller så kan du omvandla en enda referens till volatile.
- Ett objekt kan vara både
constochvolatile, i vilket fall objektet inte kunde ändras legitimt av sitt eget program, men kan ändras av någon asynkron process.
restrict
Typkvalificeraren restrict , som introducerades i C99 och är tillgänglig i /std:c11 eller /std:c17 läge, kan tillämpas på pekardeklarationer. Den kvalificerar pekaren, inte vad den pekar på.
restrict är ett optimeringstips till kompilatorn om att ingen annan pekare i det aktuella omfånget refererar till samma minnesplats. Det vill: endast pekaren eller ett värde som härleds från det (till exempel pekare + 1) används för att komma åt objektet under pekarens livslängd. Detta hjälper kompilatorn att skapa mer optimerad kod. C++ har en motsvarande mekanism, __restrict
Tänk på att det restrict är ett kontrakt mellan dig och kompilatorn. Om du använder alias som en pekare markerad med restrictär resultatet odefinierat.
Här är ett exempel som använder restrict:
void test(int* restrict first, int* restrict second, int* val)
{
*first += *val;
*second += *val;
}
int main()
{
int i = 1, j = 2, k = 3;
test(&i, &j, &k);
return 0;
}
// Marking union members restrict tells the compiler that
// only z.x or z.y will be accessed in any scope, which allows
// the compiler to optimize access to the members.
union z
{
int* restrict x;
double* restrict y;
};