非常教程

C参考手册

C 语法

Declarations

声明是C语言结构,介绍一个或多个标识符到程序并指定它们的含义和性质。

声明可能出现在任何范围内。每个声明以分号结尾(就像声明一样),由两个不同的部分组成:

specifiers-and-qualifiers declarators-and-initializers ;

其中

符和限定符

-

以任何顺序,以空格分隔的列表类型说明符:void算术类型的名称原子类型的名称以前由typedef声明引入的名称struct,union或enum说明符零个或一个存储类说明符:typedef ,auto,register,static,extern,thread_local零个或多个类型限定符:const,volatile,restrict,_Atomic(仅在声明函数时),零个或多个函数限定符:inline,noreturn零个或多个对齐指定符:alignas

声明符-和初始化

-

用逗号分隔的声明者列表(每个声明者提供附加的类型信息和/或声明的标识符)。声明者可能伴随着初始值。枚举,结构和联合声明可以省略声明符,在这种情况下,它们只引入枚举常量和/或标记。

  • 类型说明符:
    • void
    • 算术类型的名称
    • 原子类型的名称
    • 一个由typedef声明引入的名称
    • 结构体,联合体或枚举说明符
  • 零个或一个存储类说明符:typedef,auto,register,static,extern,thread_local
  • 零个或多个类型限定符:const,volatile,restrict,_Atomic
  • (仅在声明函数时),零个或多个函数限定符: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 initializer
const int *f(void); // "int" is the type specifier
                    // "const" is the type qualifier
                    // "*f(void)" is the declarator
enum COLOR {RED, GREEN, BLUE} c; // "enum COLOR {RED, GREEN, BLUE}" is the type specifier
                                 // "c" is the declarator

声明中引入的每个标识符的类型由类型说明符指定的类型和其声明者应用的类型修改组合确定。

声明符

每个声明符是以下之一:

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)这个声明者介绍的标识符。

2)任何申报人可以用括号括起来; 这是需要引入指向数组的指针和指向函数的指针。

3)指针声明符:声明S * cvr D; 声明D为由cvr限定的类型的指针S

4)数组声明符:声明S D[N]声明为由D数组N确定的类型的对象S。noptr-declarator 是除 unparenthesized 指针声明符之外的任何其他声明符。

5)函数声明符:将声明S D(params)声明D为一个带参数params并返回的函数S。noptr-declarator 是除 unparenthesized 指针声明符之外的任何其他声明符。

这种语法背后的原因是,当由声明者声明的标识符出现在与声明者相同形式的表达式中时,它将具有由类型说明符序列指定的类型。

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];

每个不属于另一个声明符的声明符的结尾都是一个序列点。

定义

一个定义是,提供有关它声明的标识符的所有信息的声明。

每个枚举或 typedef 的声明都是一个定义。

对于函数,包含函数体的声明是一个函数定义:

int foo(double); // declaration
int foo(double x){ return x; } // definition

对于对象来说,分配存储空间的声明(自动或静态,但不是 extern)是一个定义,而不分配存储空间的声明(外部声明)则不是。

extern int n; // declaration
int n = 10; // definition

对于结构体和联合体,指定成员列表的声明是定义:

struct X; // declaration
struct X { int n; }; // definition

重声明

如果同一范围内的同一标识符的另一个声明较早出现,则声明不能引入标识符。

  • 可以重复使用链接(外部或内部)声明对象:
extern int x;
int x = 10; // OK
extern int x; // OK
 
static int n;
static int n = 10; // OK
static int n; // OK
  • 非 VLA typedef 可以重复,只要它命名相同的类型即可:
typedef int int_t; 
typedef int int_t; // OK
  • 结构和联合声明可以重复:
struct X;
struct X { int n; };
struct X;

这些规则简化了头文件的使用。

注意

在C89中,在任何语句之前,任何复合语句(块范围)内的声明都必须出现在块的开头。另外,在C89中,返回int的函数可以由函数调用操作符隐式声明,并且在使用旧式函数定义时不必声明int类型的函数参数。

(直到C99)

空宣布者是被禁止的; 一个声明必须是一个 static_assert 声明或者(因为C11)至少有一个声明器或声明至少一个 struct / union / enum 标记,或者至少引入一个枚举常量。

如果声明符的任何部分是 VLA 数组声明符,则整个声明符的类型称为“可变更改类型”。从可变修改类型定义的类型也是可变修改的(VM)。任何可变修改类型的声明可能只出现在块作用域或函数原型范围内,并且不能是结构体或联合体的成员。尽管 VLA 只能具有自动存储持续时间,但 VM 类型(例如指向VLA的指针)可能是静态的。使用 VM 类型还有其他限制,请参阅转到,切换。longjmp 的。

(自C99以来)

从C语法的角度来看,static_assert被认为是声明(这样它们可以出现在声明的任何地方),但是它们不引入任何标识符,也不遵循声明语法。

(自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

C 语法相关

1.#define directive
2.#elif directive
3.#else directive
4.#endif directive
5.#error directive
6.#if directive
7.#ifdef directive
8.#ifndef directive
9.#include directive
10.#line directive
11.#pragma directive
12.alignas
13.Alternative operators and tokens
14.Analyzability
15.Arithmetic operators
16.Arithmetic types
17.Array declaration
18.Array initialization
19.ASCII Chart
20.Assignment operators
21. types
22.Basic concepts
23.Bit fields
24.break statement
25.C language
26.C Operator Precedence
27.cast operator
28.character constant
29.Comments
30.Comparison operators
31.compound literals
32.Conditional inclusion
33.Conformance
34.const type qualifier
35.Constant expressions
36.continue statement
37.do-while loop
38.Enumerations
39.Escape sequences
40.Expressions
41.External and tentative definitions
42.File scope
43.floating constant
44.for loop
45.Function declarations
46.Function definitions
47.Functions
48.Generic selection
49.goto statement
50.Identifier
51.if statement
52.Implicit conversions
53.Increment/decrement operators
54.Initialization
55.inline function specifier
56.integer constant
57.Lifetime
58.Logical operators
59.Lookup and name spaces
60.Main function
61.Member access operators
62.Memory model
63.Objects and alignment
64.Order of evaluation
65.Other operators
66.Phases of translation
67.Pointer declaration
68.Preprocessor
69.restrict type qualifier
70.return statement
71.Scalar initialization
72.Scope
73.sizeof operator
74.Statements
75.static assert declaration
76.Static storage duration
77.Storage-class specifiers
78.string literals
79.Struct and union initialization
80.Struct declaration
81.switch statement
82.Thread storage duration
83.Type
84.Type
85.Typedef declaration
86.Undefined behavior
87.Union declaration
88.Value categories
89.Variadic arguments
90.volatile type qualifier
91.while loop
92._Alignof operator
93._Noreturn function specifier
C

C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。