非常教程

C参考手册

C 语法

Pointer declaration

指针是一种引用另一种类型的函数或对象的对象类型,可能会添加限定符。指针也可能指什么都没有,它由特殊的空指针值表示。

句法

在指针声明的声明语法中,类型说明符序列指定指向类型(可能是函数或对象类型,可能不完整),声明符的形式如下:

* qualifiers(optional) declarator

(1)

其中声明符可以是标识正在声明的指针的标识符,包括另一个指针声明符(它将指示指向指针的指针):

float *p, **pp; // p is a pointer to float
                // pp is a pointer to a pointer to float
int (*fp)(int); // fp is a pointer to function with type int(int)

出现在*和标识符(或其他嵌套声明符)之间的限定符限定了正在声明的指针的类型:

int n;
const int * pc = &n; // pc is a non-const pointer to a const int
// *pc = 2; // Error: n cannot be changed through p without a cast
pc = NULL; // OK: pc itself can be changed
 
int * const cp = &n; // cp is a const pointer to a non-const int
*cp = 2; // OK to change n through cp
// cp = NULL; // Error: cp itself cannot be changed
 
int * const * pcp = &cp; // non-const pointer to const pointer to non-const int

说明

指针用于间接寻址,这是一种无处不在的编程技术; 它们可用于实现传递引用语义,访问具有动态存储持续时间的对象,以实现“可选”类型(使用空指针值),结构之间的聚合关系,回调(使用指向函数的指针),通用接口(使用指针void)等等。

指向对象

指向对象的指针可以用应用于对象类型表达式(可能不完整)的地址 - 运算符的结果初始化:

int n;
int *np = &n; // pointer to int
int *const *npp = &np; // non-const pointer to const pointer to non-const int
 
int a[2];
int (*ap)[2] = &a; // pointer to array of int
 
struct S { int n; } s = {1}
int* sp = &s.n; // pointer to the int that is a member of s

指针可能作为操作数出现在间接操作符(一元*)上,后者返回标识指向对象的左值:

int n;
int* p = &n;     // pointer p is pointing to n
*p = 7;         // stores 7 in n
printf("%d\n", *p); // lvalue-to-rvalue conversion reads the value from n

指向结构和联合类型对象的指针也可以作为通过指针运算符访问成员的左侧操作数->

由于数组到指针的隐式转换,可以使用数组类型的表达式初始化指向数组第一个元素的指针:

int a[2];
int *p = a; // pointer to a[0]
 
int b[3][3];
int (*row)[3] = b; // pointer to b[0]

某些加法,减法,复合赋值,增量和减量运算符是为指向数组元素的指针定义的。

在某些情况下,为指向对象的指针定义比较运算符:表示相同地址的两个指针比较相等,两个空指针值相等,指向同一数组元素的指针与这些元素的数组索引相同,以及指向struct成员按照这些成员的声明顺序进行比较。

许多实现还提供了随机起源指针的严格总排序,例如,如果它们被实现为连续(“平坦”)虚拟地址空间内的地址。

指向功能

指向函数的指针可以用函数的地址初始化。由于功能到指针的转换,操作符的地址是可选的:

void f(int);
void (*pf1)(int) = &f;
void (*pf2)(int) = f; // same as &f

与函数不同,指向函数的指针是对象,因此可以存储在数组中,复制,分配,作为参数传递给其他函数等。

指向函数的指针可以在函数调用操作符的左侧使用; 这会调用指向函数:

#include <stdio.h>
int f(int n)
{
    printf("%d\n", n);
    return n*n;
}
int main(void)
{
    int (*p)(int) = f;
    int x = p(7);
}

解引用函数指针会得到指向函数的函数指示符:

int f();
int (*p)() = f;    // pointer p is pointing to f
(*p)(); // function f invoked through the function designator
p();    // function f invoked directly through the pointer

平等比较运算符定义为指向函数的指针(如果指向相同的函数,则它们相等)。

指针无效

指向任何类型的对象的指针都可以隐式转换为指针void(可以是const或volatile限定的),反之亦然:

int n=1, *p=&n;
void* pv = p; // int* to void*
int* p2 = pv; // void* to int*
printf("%d\n", *p2); // prints 1

void指针用于传递未知类型的对象,这在通用接口中很常见:malloc返回值void*qsort期望用户提供的回调接受两个const void*参数。pthread_create需要用户提供的接受和返回的回调void*。在所有情况下,调用者有责任在使用前将指针转换为正确的类型。

空指针

每种类型的指针都有一个特殊的值,称为该类型的空指针值。值为空的指针不指向对象或函数(取消引用空指针是未定义的行为),并将相同类型的所有指针值相等,其值也为

要将指针初始化为空值或将空值赋予现有指针,可以使用空指针常量(NULL或任何其他具有零值的整数常量)。静态初始化还会初始化指向其空值的指针。

空指针可以指示没有对象或可以用来指示其他类型的错误条件。通常,接收指针参数的函数几乎总是需要检查值是否为空,并以不同的方式处理该情况(例如,free在传递空指针时什么也不做)。

注意

尽管任何指向对象的指针都可以转换为指向不同类型对象的指针,但是取消引用指向与对象的声明类型不同的类型的指针几乎总是未定义的行为。细节请参见严格的别名。

可以通过指针访问对象的函数,这些指针不是别名。详情请参阅限制。

(自C99以来)

数组类型的左值表达式在大多数上下文中使用时,会经历到指向数组第一个元素的指针的隐式转换。详情请看阵列。

char *str = "abc"; // "abc" is a char[4] array, str is a pointer to 'a'

指向char的指针通常用于表示字符串。为了表示一个有效的字节串,一个指针必须指向一个字符,它是一个char数组的元素,并且在某个索引处必须有一个char值为零的char大于或等于指针。

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.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 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。