非常教程

C参考手册

C 语法

Value categories

C中的每个表达式(带有参数的运算符,函数调用,常量,变量名等)都由两个独立的属性表征:一个类型和一个值类别。

每个表达式都属于三个值类别之一:左值,非左值对象(右值)和函数指示符。

左值表达式

Lvalue表达式是任何具有与该类型不同的对象类型的表达式void,它可能指定一个对象(如果左值在计算时没有实际指定对象,那么该行为是未定义的)。换句话说,左值表达式评估为对象身份。此值类别的名称(“左值”)具有历史意义,反映了在CPL编程语言中使用左值表达式作为赋值运算符的左侧操作数。

左值表达式可用于以下左值上下文中

  • 作为地址运算符的操作数(除非左值指定了一个位域或被声明为寄存器)。
  • 作为前/后增量和减量运算符的操作数。
  • 作为成员访问(点)运算符的左侧操作数。
  • 作为赋值和复合赋值操作符的左侧操作数。

如果在除sizeof,_Alignof或上面列出的运算符之外的任何上下文中使用了左值表达式,则任何完整类型的非数组左值都会进行左值转换,该值会模拟对象值的存储器负载。同样地,在比其他任何上下文中使用时阵列的左值经历阵列到指针转换sizeof_Alignof,操作者从一个字符串数组初始化地址。

const / volatile / restrict-qualifiers和原子类型的语义只适用于左值(左值转换去除限定符并删除原子性)。

以下表达式是左值:

  • 标识符,包括函数参数,只要它们被声明为指定对象(而不是函数)
  • 字符串文字
  • (C99)复合文字
  • 如果未隐含的表达式是左值,则用括号表示
  • 如果它的左边参数是左值,则为成员访问(点)运算符的结果
  • 通过指针->操作符访问成员的结果
  • 将间接(一元*)运算符的结果应用于指向对象的指针
  • 订阅运算符([])的结果

可修改的左值表达式

一个可修改的左值是完整非数组类型的非常量限定的左值表达式,如果它是结构体/联合体,则不具有常量限定的成员,即递归。

只有可修改的左值表达式可以用作递增/递减的参数,以及作为赋值和复合赋值操作符的左侧参数。

非左值对象表达式

通俗地称为rvalues,非左值对象表达式是不指定对象的对象类型的表达式,而是没有对象标识或存储位置的值。无法取得非左值对象表达式的地址。

以下表达式是非左值对象表达式:

  • 整数,字符和浮点常量
  • 没有指定返回左值的所有运算符,包括
    • 任何函数调用表达式
    • 任何演员表达(注意复合文字,看起来相似,是左值)
    • 成员访问运算符(点)施加到非左值结构/联合,f().x(x,s1).as1=s2).m
    • 所有算术,关系,逻辑和位运算符
    • 递增和递减运算符(注意:预格式是C ++中的左值)
    • 赋值和复合赋值运算符(注意:它们是C ++中的左值)
    • 条件运算符(注意:可能是C ++中的左值)
    • 逗号运算符(注意:可能是C ++中的左值)
    • 操作符的地址,即使它被应用到一元运算*符的结果中

作为一种特殊情况,类型的表达式void被假定为非左值对象表达式,它产生一个没有表示并且不需要存储的值。

请注意,具有数组类型成员(可能嵌套)的struct / union rvalue事实上指定了具有临时生存期的对象。该对象可以通过索引数组成员或通过数组成员的指针转换所获得的指针间接形成的左值表达式来访问。

函数指示符表达式

函数指示符(由函数声明引入的标识符)是函数类型的表达式。当在除address-of运算符,sizeof和_Alignof之外的任何上下文中使用时(最后两个在应用于函数时会生成编译错误),函数标识符总是被转换为非左值指针来运行。请注意,函数调用操作符是为指向函数的指针定义的,而不是函数指示符本身。

参考

  • C11标准(ISO / IEC 9899:2011):
    • 6.3.2.1左值,数组和函数指示符(p:54-55)
  • C99标准(ISO / IEC 9899:1999):
    • 6.3.2.1左值,数组和函数指示符(p:46)
  • C89 / C90标准(ISO / IEC 9899:1990):
    • 3.2.2.1左值和函数指示符

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.Declarations
38.do-while loop
39.Enumerations
40.Escape sequences
41.Expressions
42.External and tentative definitions
43.File scope
44.floating constant
45.for loop
46.Function declarations
47.Function definitions
48.Functions
49.Generic selection
50.goto statement
51.Identifier
52.if statement
53.Implicit conversions
54.Increment/decrement operators
55.Initialization
56.inline function specifier
57.integer constant
58.Lifetime
59.Logical operators
60.Lookup and name spaces
61.Main function
62.Member access operators
63.Memory model
64.Objects and alignment
65.Order of evaluation
66.Other operators
67.Phases of translation
68.Pointer declaration
69.Preprocessor
70.restrict type qualifier
71.return statement
72.Scalar initialization
73.Scope
74.sizeof operator
75.Statements
76.static assert declaration
77.Static storage duration
78.Storage-class specifiers
79.string literals
80.Struct and union initialization
81.Struct declaration
82.switch statement
83.Thread storage duration
84.Type
85.Type
86.Typedef declaration
87.Undefined behavior
88.Union declaration
89.Variadic arguments
90.volatile type qualifier
91.while loop
92._Alignof operator
93._Noreturn function specifier
C

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