非常教程

C参考手册

C 语法

Comparison operators

比较运算符是测试条件的二元运算符,如果该条件为逻辑,则返回1,如果该条件为,则返回0

Operator

Operator name

Example

Description

==

equal to

a == b

a is equal to b

!=

not equal to

a != b

a is not equal to b

<

less than

a < b

a is less than b

greater than

a > b

a is greater than b

<=

less than or equal to

a <= b

a is less than or equal to b

=

greater than or equal to

a >= b

a is greater than or equal to b

关系运算符

关系运算符表达式具有这种形式。

lhs < rhs

(1)

lhs > rhs

(2)

lhs <= rhs

(3)

lhs >= rhs

(4)

1)少于表达式

2)大于表达式

3)较少或相等的表达

4)更大或相等的表达

其中

lhs, rhs

-

expressions that both have real type or both have pointer to object type

任何关系运算符表达式的类型是int,并且其值(不是左值)是1指定的关系成立并且​0​指定的关系不成立时的值。

如果 lhs 和 rhs 是任何实际类型的表达式,那么。

  • 如果 lhs 和 rhs 具有算术类型,则执行通常的算术转换
  • 转换后操作数的值以通常的数学意义进行比较(除了正数和负数比较相等且任何涉及 NaN 值的比较返回零)

请注意,复数和虚数不能与这些运算符进行比较。

如果lhs和rhs是指针类型的表达式,它们必须都是指向兼容类型对象的指针,只是指向对象的限定被忽略。

  • 指向不是数组元素的对象的指针被视为指向具有一个元素的数组元素
  • 如果两个指针指向同一个对象,或者两个指针都指向同一个数组的末尾,则它们会相等
  • 如果两个指针指向相同数组的不同元素,则指向索引较大的元素的指针比较大。
  • 如果一个指针指向一个数组的元素,另一个指针指向一个超过同一个数组的末尾,那么一个过去的末尾指针会比较大
  • 如果两个指针指向同一个结构体的成员,那么稍后在结构体定义中声明的成员指针比先前声明的成员的指针大。
  • 指向同一工会成员的指针相等
  • 所有其他指针比较都会调用未定义的行为
#include <assert.h>
int main(void)
{
    assert(1 < 2);
    assert(2+2 <= 4.0); // int converts to double, two 4.0's compare equal
 
    struct { int x,y; } s;
    assert(&s.x < &s.y); // struct members compare in order of declaration
 
    double d = 0.0/0.0; // NaN
    assert( !(d < d) );
    assert( !(d > d) );
    assert( !(d >= d) );
    assert( !(d >= d) );
 
    float f = 0.1; // f = 0.100000001490116119384765625
    double g = 0.1; // g = 0.1000000000000000055511151231257827021181583404541015625
    assert(f > g); // different values
}

平等操作符

等号运算符表达式具有这种形式。

lhs == rhs

(1)

lhs != rhs

(2)

1)等于表达

2)不等于表达

其中

lhs,rhs

-

具有任何算术类型(包括复数和虚数)的表达式都是指向对象或兼容类型函数的指针,忽略指向类型的限定符一个是指向对象的指针,另一个是指向(可能限定的)void一个是指向对象或函数的指针,另一个是空指针常量,例如NULL

  • 两者都有算术类型(包括复数和虚数)
  • 都是指向兼容类型的对象或函数的指针,而忽略指向类型的限定符
  • 一个是指向对象的指针,另一个指向(可能合格的) void
  • 一个是指向对象或函数的指针,另一个是空指针常量,如 NULL

任何等号运算符表达式的类型是int,并且其值(不是左值)是1指定的关系成立并且​0​指定的关系不成立时的值。

  • 如果两个操作数都具有算术类型,则执行通常的算术转换,并以通常的数学意义对结果值进行比较(除了正数和负数比较相等并且任何涉及NaN值的比较,包括与其自身的相等性返回零)。特别是,如果复数类型的实部比较相等并且它们的虚部比较相等,则复数类型的值是相等的。
  • 如果一个操作数是一个指针而另一个是空指针常量,则空指针常量首先被转换为指针的类型(它给出一个空指针值),并且如下所述比较这两个指针
  • 如果一个操作数是一个指针,而另一个是指向 void 的指针,则非 void 指针转换为指向 void 的指针,并如下所述比较两个指针
  • 如果满足以下任一条件,则两个指针相等:
    • 它们都是它们类型的空指针值
    • 它们都是指向同一个对象的指针
    • 一个指针指向一个 struct / union / array 对象,另一个指向其第一个成员/任何成员/第一个元素
    • 他们都指向一个过去的同一阵列的最后一个元素
    • 一个是一个超过数组的末尾,另一个是不同数组的起始位置(相同类型),它跟随在较大数组中的第一个数组中,或者在没有填充的结构中

(与关系运算符一样,指向不是任何数组元素的对象的指针的行为就像指向大小为1的数组的元素的指针)。

注意

结构类型的对象不会自动比较相等,并且比较它们memcmp是不可靠的,因为填充字节可能有任何值。

由于指针比较与无效指针一起工作,因此NULL可以将宏定义为(void*)0C 语言,尽管在 C ++中无效指针不会隐式转换为类型指针。

在比较浮点值是否相等时必须小心,因为许多操作的结果不能精确表示,必须舍入。在实践中,通常会比较浮点数,以考虑最后一个地方的一个或多个单位的差异。

#include <assert.h>
int main(void)
{
    assert(2+2 == 4.0); // int converts to double, two 4.0's compare equal
 
    int n[2][3] = {1,2,3,4,5,6};
    int* p1 = &n[0][2]; // last element in the first row
    int* p2 = &n[1][0]; // start of second row
    assert(p1+1 == p2); // compare equal
 
    double d = 0.0/0.0; // NaN
    assert( d != d ); // NaN does not equal itself
 
    float f = 0.1; // f = 0.100000001490116119384765625
    double g = 0.1; // g = 0.1000000000000000055511151231257827021181583404541015625
    assert(f != g); // different values
}

参考

  • C11 standard (ISO/IEC 9899:2011):
    • 6.5.8 Relational operators (p: 95-96)
    • 6.5.9 Equality operators (p: 96-97)
  • C99 standard (ISO/IEC 9899:1999):
    • 6.5.8 Relational operators (p: 85-86)
    • 6.5.9 Equality operators (p: 86-87)
  • C89/C90 standard (ISO/IEC 9899:1990):
    • 3.3.8 Relational operators
    • 3.3.9 Equality operators

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.compound literals
31.Conditional inclusion
32.Conformance
33.const type qualifier
34.Constant expressions
35.continue statement
36.Declarations
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 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。