访问运算符
成员访问操作符(dot .
和 arrow ->
)用于访问 struct
的成员。
对象的成员
计算表示作为被访问对象成员的对象的左值。
struct MyStruct
{
int x;
int y;
};
struct MyStruct myObject;
myObject.x = 42;
myObject.y = 123;
printf(".x = %i, .y = %i\n", myObject.x, myObject.y); /* Outputs ".x = 42, .y = 123". */
指向对象的成员
用于解除引用的语法糖,然后是成员访问。实际上,x->y
形式的表达式是 (*x).y
的简写 - 但是箭头操作符更清晰,特别是如果结构指针是嵌套的。
struct MyStruct
{
int x;
int y;
};
struct MyStruct myObject;
struct MyStruct *p = &myObject;
p->x = 42;
p->y = 123;
printf(".x = %i, .y = %i\n", p->x, p->y); /* Outputs ".x = 42, .y = 123". */
printf(".x = %i, .y = %i\n", myObject.x, myObject.y); /* Also outputs ".x = 42, .y = 123". */
地址的
一元 &
运算符是运算符的地址。它计算给定的表达式,其中结果对象必须是左值。然后,它计算一个对象,其类型是指向结果对象类型的指针,并包含结果对象的地址。
int x = 3;
int *p = &x;
printf("%p = %p\n", (void *)&x, (void *)p); /* Outputs "A = A", for some implementation-defined A. */
提领
一元*
运算符取消引用指针。它计算从解除引用评估给定表达式得到的指针得到的左值。
int x = 42;
int *p = &x;
printf("x = %d, *p = %d\n", x, *p); /* Outputs "x = 42, *p = 42". */
*p = 123;
printf("x = %d, *p = %d\n", x, *p); /* Outputs "x = 123, *p = 123". */
索引
索引是指针添加的语法糖,然后是解除引用。实际上,形式 a[i]
的表达式相当于*(a + i)
- 但显式的下标符号是首选。
int arr[] = { 1, 2, 3, 4, 5 };
printf("arr[2] = %i\n", arr[2]); /* Outputs "arr[2] = 3". */
索引的可互换性
添加指向整数的指针是可交换操作(即操作数的顺序不会改变结果)所以 pointer + integer == integer + pointer
。
其结果是 arr[3]
和 3[arr]
是等价的。
printf("3[arr] = %i\n", 3[arr]); /* Outputs "3[arr] = 4". */
通常不建议使用表达式 3[arr]
而不是 arr[3]
,因为它会影响代码的可读性。它在混淆的编程竞赛中往往很受欢迎。