?
This document uses PHP Chinese website manual Release
聲明是C語言結(jié)構(gòu),介紹一個或多個標(biāo)識符到程序并指定它們的含義和性質(zhì)。
聲明可能出現(xiàn)在任何范圍內(nèi)。每個聲明以分號結(jié)尾(就像聲明一樣),由兩個不同的部分組成:
specifiers-and-qualifiers declarators-and-initializers ; |
---|
其中
符和限定符 | - | 以任何順序,以空格分隔的列表類型說明符:void算術(shù)類型的名稱原子類型的名稱以前由typedef聲明引入的名稱struct,union或enum說明符零個或一個存儲類說明符:typedef ,auto,register,static,extern,thread_local零個或多個類型限定符:const,volatile,restrict,_Atomic(僅在聲明函數(shù)時),零個或多個函數(shù)限定符:inline,noreturn零個或多個對齊指定符:alignas |
---|---|---|
聲明符-和初始化 | - | 用逗號分隔的聲明者列表(每個聲明者提供附加的類型信息和/或聲明的標(biāo)識符)。聲明者可能伴隨著初始值。枚舉,結(jié)構(gòu)和聯(lián)合聲明可以省略聲明符,在這種情況下,它們只引入枚舉常量和/或標(biāo)記。 |
類型說明符:
void
算術(shù)類型的名稱
原子類型的名稱
一個由typedef聲明引入的名稱
結(jié)構(gòu)體,聯(lián)合體或枚舉說明符
零個或一個存儲類說明符:typedef,auto,register,static,extern,thread_local
零個或多個類型限定符:const,volatile,restrict,_Atomic
(僅在聲明函數(shù)時),零個或多個函數(shù)限定符:inline,noreturn
零或多個對齊說明符:alignas
declarators-and-initializers - comma-separated list of declarators (each declarator provides additional type information and/or the identifier to declare). Declarators may be accompanied by [initializers](initialization). The [enum](enum), [struct](struct), and [union](union) declarations may omit declarators, in which case they only introduce the enumeration constants and/or tags.
例如,
int a, *b=NULL; // "int" is the type specifier, // "a" is a declarator // "*b" is a declarator and NULL is its initializerconst int *f(void); // "int" is the type specifier // "const" is the type qualifier // "*f(void)" is the declaratorenum COLOR {RED, GREEN, BLUE} c; // "enum COLOR {RED, GREEN, BLUE}" is the type specifier // "c" is the declarator
聲明中引入的每個標(biāo)識符的類型由類型說明符指定的類型和其聲明者應(yīng)用的類型修改組合確定。
每個聲明符是以下之一:
identifier | (1) | |
---|---|---|
( declarator ) | (2) | |
* qualifiers(optional) declarator | (3) | |
noptr-declarator static(optional) qualifiers(optional) expression noptr-declarator qualifiers(optional) * | (4) | |
noptr-declarator ( parameters-or-identifiers ) | (5) |
1)這個聲明者介紹的標(biāo)識符。
2)任何申報人可以用括號括起來; 這是需要引入指向數(shù)組的指針和指向函數(shù)的指針。
3)指針聲明符:聲明S * cvr D
; 聲明D
為由cvr限定的類型的指針S
。
4)數(shù)組聲明符:聲明S D[N]
聲明為由D
數(shù)組N
確定的類型的對象S
。noptr-declarator 是除 unparenthesized 指針聲明符之外的任何其他聲明符。
5)函數(shù)聲明符:將聲明S D(params)
聲明D
為一個帶參數(shù)params
并返回的函數(shù)S
。noptr-declarator 是除 unparenthesized 指針聲明符之外的任何其他聲明符。
這種語法背后的原因是,當(dāng)由聲明者聲明的標(biāo)識符出現(xiàn)在與聲明者相同形式的表達(dá)式中時,它將具有由類型說明符序列指定的類型。
struct C { int member; // "int" is the type specifier // "member" is the declarator} obj, *pObj = &obj;// "struct C { int member; }" is the type specifier// declarator "obj" defines an object of type struct C// declarator "*pObj" declares a pointer to C,// initializer "= &obj" provides the initial value for that pointer int a = 1, *p = NULL, f(void), (*pf)(double);// the type specifier is "int"// declarator "a" defines an object of type int// initializer "=1" provides its initial value// declarator "*p" defines an object of type pointer to int// initializer "=NULL" provides its initial value// declarator "f(void)" declares a function taking void and returning int// declarator "(*pf)(double)" defines an object of type pointer// to function taking double and returning int int (*(*foo)(double))[3] = NULL;// the type specifier is int// 1. declarator "(*(*foo)(double))[3]" is an array declarator:// the type declared is "/nested declarator/ array of 3 int"// 2. the nested declarator is "*(*foo)(double))", which is a pointer declarator// the type declared is "/nested declarator/ pointer to array of 3 int"// 3. the nested declarator is "(*foo)(double)", which is a function declarator// the type declared is "/nested declarator/ function taking double and returning// pointer to array of 3 int"// 4. the nested declarator is "(*foo)" which is a (parenthesized, as required by// function declarator syntax) pointer declarator.// the type declared is "/nested declarator/ pointer to function taking double// and returning pointer to array of 3 int"// 5. the nested declarator is "foo", which is an identifier.// The declaration introduces the identifier "foo" to refer to an object of type// "pointer to function taking double and returning pointer to array of 3 int"// The initializer "= NULL" provides the initial value of this pointer. // If "foo" is used in an expression of the form of the declarator, its type would be// int.int x = (*(*foo)(1.2))[0];
每個不屬于另一個聲明符的聲明符的結(jié)尾都是一個序列點(diǎn)。
一個定義是,提供有關(guān)它聲明的標(biāo)識符的所有信息的聲明。
每個枚舉或 typedef 的聲明都是一個定義。
對于函數(shù),包含函數(shù)體的聲明是一個函數(shù)定義:
int foo(double); // declarationint foo(double x){ return x; } // definition
對于對象來說,分配存儲空間的聲明(自動或靜態(tài),但不是 extern)是一個定義,而不分配存儲空間的聲明(外部聲明)則不是。
extern int n; // declarationint n = 10; // definition
對于結(jié)構(gòu)體和聯(lián)合體,指定成員列表的聲明是定義:
struct X; // declarationstruct X { int n; }; // definition
如果同一范圍內(nèi)的同一標(biāo)識符的另一個聲明較早出現(xiàn),則聲明不能引入標(biāo)識符。
可以重復(fù)使用鏈接(外部或內(nèi)部)聲明對象:
extern int x;int x = 10; // OKextern int x; // OK static int n;static int n = 10; // OKstatic int n; // OK
非 VLA typedef 可以重復(fù),只要它命名相同的類型即可:
typedef int int_t; typedef int int_t; // OK
結(jié)構(gòu)和聯(lián)合聲明可以重復(fù):
struct X;struct X { int n; };struct X;
這些規(guī)則簡化了頭文件的使用。
在C89中,在任何語句之前,任何復(fù)合語句(塊范圍)內(nèi)的聲明都必須出現(xiàn)在塊的開頭。另外,在C89中,返回int的函數(shù)可以由函數(shù)調(diào)用操作符隱式聲明,并且在使用舊式函數(shù)定義時不必聲明int類型的函數(shù)參數(shù)。 | (直到C99) |
---|
空宣布者是被禁止的; 一個聲明必須是一個 static_assert 聲明或者(因為C11)至少有一個聲明器或聲明至少一個 struct / union / enum 標(biāo)記,或者至少引入一個枚舉常量。
如果聲明符的任何部分是 VLA 數(shù)組聲明符,則整個聲明符的類型稱為“可變更改類型”。從可變修改類型定義的類型也是可變修改的(VM)。任何可變修改類型的聲明可能只出現(xiàn)在塊作用域或函數(shù)原型范圍內(nèi),并且不能是結(jié)構(gòu)體或聯(lián)合體的成員。盡管 VLA 只能具有自動存儲持續(xù)時間,但 VM 類型(例如指向VLA的指針)可能是靜態(tài)的。使用 VM 類型還有其他限制,請參閱轉(zhuǎn)到,切換。longjmp 的。 | (自C99以來) |
---|
從C語法的角度來看,static_assert被認(rèn)為是聲明(這樣它們可以出現(xiàn)在聲明的任何地方),但是它們不引入任何標(biāo)識符,也不遵循聲明語法。 | (自C11以來) |
---|
C11 standard (ISO/IEC 9899:2011):
6.7 Declarations (p: 108-145)
C99 standard (ISO/IEC 9899:1999):
6.7 Declarations (p: 97-130)
C89/C90 standard (ISO/IEC 9899:1990):
3.5 Declarations