1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
<h1 id="firstHeading" class="firstHeading">Member access operators</h1> <p>Member access operators allow access to the members of their operands.</p>
<table class="wikitable"> <tr style="text-align:center"> <th> Operator </th> <th> Operator name </th> <th> Example </th> <th> Description </th>
</tr> <tr style="text-align:center"> <td> <code>[]</code> </td> <td> array subscript </td> <td> <code>a[b]</code> </td> <td> access the <b>b</b>th element of array <b>a</b> </td>
</tr> <tr style="text-align:center"> <td> <code>*</code> </td> <td> pointer dereference </td> <td> <code>*a</code> </td> <td> dereference the pointer <b>a</b> to access the object or function it refers to </td>
</tr> <tr style="text-align:center"> <td> <code>&</code> </td> <td> address of </td> <td> <code>&a</code> </td> <td> create a pointer that refers to the object or function <b>a</b> </td>
</tr> <tr style="text-align:center"> <td> <code>.</code> </td> <td> member access </td> <td> <code>a.b</code> </td> <td> access member <b>b</b> of <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> <b>a</b> </td>
</tr> <tr style="text-align:center"> <td> <code>-></code> </td> <td> member access through pointer </td> <td> <code>a->b</code> </td> <td> access member <b>b</b> of <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> pointed to by <b>a</b> </td>
</tr>
</table> <h3 id="Subscript"> Subscript</h3> <p>The array subscript expression has the form</p>
<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <span class="t-spar">pointer-expression</span> <code>[</code> <span class="t-spar">integer-expression</span> <code>]</code> </td> <td> (1) </td> <td class="t-sdsc-nopad"> </td>
</tr> <tr class="t-sdsc"> <td> <span class="t-spar">integer-expression</span> <code>[</code> <span class="t-spar">pointer-expression</span> <code>]</code> </td> <td> (2) </td> <td class="t-sdsc-nopad"> </td>
</tr>
</table> <p>where</p>
<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">pointer-expression</span> </td> <td> - </td> <td> an <a href="expressions" title="c/language/expressions">expression</a> of type pointer to complete object </td>
</tr> <tr class="t-par"> <td> <span class="t-spar">integer-expression</span> </td> <td> - </td> <td> an <a href="expressions" title="c/language/expressions">expression</a> of integer type </td>
</tr>
</table> <p>The subscript operator expression is an <a href="value_category" title="c/language/value category">lvalue expression</a> whose type is the type of the object pointed to by <span class="t-spar">pointer-expression</span>.</p>
<p>By definition, the subscript operator <code>E1[E2]</code> is exactly identical to <code>*((E1)+(E2))</code>. If <span class="t-spar">pointer-expression</span> is an array expression, it undergoes <a href="conversion" title="c/language/conversion">lvalue-to-rvalue conversion</a> and becomes a pointer to the first element of the array.</p>
<p>Due to the definition of the <a href="operator_arithmetic" title="c/language/operator arithmetic">addition between a pointer and an integer</a>, the result is the element of the array with the index equal to the result of <span class="t-spar">integer-expression</span> (or, if <span class="t-spar">pointer-expression</span> was pointing at ith element of some array, the index of the result is i plus the result of <span class="t-spar">integer-expression</span>)</p>
<p>Note: see <a href="array" title="c/language/array">array</a> for the details on multidimensional arrays.</p>
<div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h>
int main(void)
{
int a[3] = {1,2,3};
printf("%d %d\n", a[2], // n == 3
2[a]); // same, n == 3
a[2] = 7; // subscripts are lvalues
int n[2][3] = {{1,2,3},{4,5,6}};
int (*p)[3] = &n[1]; // elements of n are arrays
printf("%d %d %d\n", (*p)[0], p[0][1], p[0][2]); // access n[1][] via p
int x = n[1][2]; // applying [] again to the array n[1]
printf("%d\n", x);
printf("%c %c\n", "abc"[2], 2["abc"]); // string literals are arrays too
}</pre></div> <p>Output:</p>
<div class="text source-text"><pre data-language="c">3 3
4 5 6
6
c c</pre></div> </div> <h3 id="Dereference"> Dereference</h3> <p>The <i>dereference</i> or <i>indirection</i> expression has the form</p>
<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <code>*</code> <span class="t-spar">pointer-expression</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td>
</tr>
</table> <p>where</p>
<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">pointer-expression</span> </td> <td> - </td> <td> an <a href="expressions" title="c/language/expressions">expression</a> of any pointer type </td>
</tr>
</table> <p>If <span class="t-spar">pointer-expression</span> is a pointer to function, the result of the dereference operator is a function designator for that function.</p>
<p>If <span class="t-spar">pointer-expression</span> is a pointer to object, the result is an <a href="value_category" title="c/language/value category">lvalue expression</a> that designates the pointed-to object.</p>
<p>Dereferencing a null pointer, a pointer to an object outside of its lifetime (a dangling pointer), a misaligned pointer, or a pointer with indeterminate value is undefined behavior, except when the dereference operator is nullified by applying the address-of operator to its result, as in <code>&*E</code>.</p>
<div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h>
int main(void)
{
int n = 1;
int* p = &n;
printf("*p = %d\n", *p); // the value of *p is what's stored in n
*p = 7; // *p is lvalue
printf("*p = %d\n", *p);
}</pre></div> <p>Output:</p>
<div class="text source-text"><pre data-language="c">*p = 1
*p = 7</pre></div> </div> <h3 id="Address_of"> Address of</h3> <p>The address-of expression has the form</p>
<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <code>&</code> <span class="t-spar">function</span> </td> <td> (1) </td> <td class="t-sdsc-nopad"> </td>
</tr> <tr class="t-sdsc"> <td> <code>&</code> <span class="t-spar">lvalue-expression</span> </td> <td> (2) </td> <td class="t-sdsc-nopad"> </td>
</tr> <tr class="t-sdsc"> <td> <code>&</code> <code>*</code> <span class="t-spar">expression</span> </td> <td> (3) </td> <td class="t-sdsc-nopad"> </td>
</tr> <tr class="t-sdsc"> <td> <code>&</code> <span class="t-spar">expression</span> <code>[</code> <span class="t-spar">expression</span> <code>]</code> </td> <td> (4) </td> <td class="t-sdsc-nopad"> </td>
</tr>
</table> <div class="t-li1">
<span class="t-li">1)</span> address of a function</div> <div class="t-li1">
<span class="t-li">2)</span> address of an object</div> <div class="t-li1">
<span class="t-li">3)</span> special case: <code>&</code> and <code>*</code> cancel each other, neither one is evaluated</div> <div class="t-li1">
<span class="t-li">4)</span> special case: <code>&</code> and the <code>*</code> that is implied in <code>[]</code> cancel each other, only the addition implied in <code>[]</code> is evaluated.</div> <p>where</p>
<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">lvalue-expression</span> </td> <td> - </td> <td> an <a href="value_category" title="c/language/value category">lvalue</a> expression of any type that is not a <a href="bit_field" title="c/language/bit field">bit-field</a> and does not have <a href="storage_duration" title="c/language/storage duration">register</a> storage class </td>
</tr>
</table> <p>The address-of operator produces the <a href="value_category" title="c/language/value category">non-lvalue</a> address of its operand, suitable for initializing a pointer to the type of the operand. If the operand is a function designator <span class="t-v">(1)</span>, the result is a pointer to function. If the operand is an object <span class="t-v">(2)</span>, the result is a pointer to object.</p>
<p>If the operand is the dereference operator, no action is taken (so it's okay to apply &* to a null pointer), except that the result is not an lvalue.</p>
<p>If the operand is an array index expression, no action is taken other than the array-to-pointer conversion and the addition, so &a[N] is valid for an array of size N (obtaining a pointer one past the end is okay, dereferencing it is not, but dereference cancels out in this expression).</p>
<div class="t-example"> <div class="c source-c"><pre data-language="c">int f(char c) { return c;}
int main(void)
{
int n = 1;
int *p = &n; // address of object n
int (*fp)(char) = &f; // address of function f
int a[3] = {1,2,3};
int *beg=a, *end=&a[3]; // same as end = a+3
}</pre></div> </div> <h3 id="Member_access"> Member access</h3> <p>The member access expression has the form</p>
<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <span class="t-spar">expression</span> <code>.</code> <span class="t-spar">member-name</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td>
</tr>
</table> <p>where</p>
<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">expression</span> </td> <td> - </td> <td> an expression of <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> type </td>
</tr> <tr class="t-par"> <td> <span class="t-spar">member-name</span> </td> <td> - </td> <td> an <a href="identifier" title="c/language/identifier">identifier</a> that names a member of the struct or union designated by <span class="t-spar">expression</span> </td>
</tr>
</table> <p>The member access expression designates the named member of the <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> designated by its left operand. It has the same <a href="value_category" title="c/language/value category">value category</a> as its left operand.</p>
<p>If the left operand is <a href="const" title="c/language/const">const</a> or <a href="volatile" title="c/language/volatile">volatile</a> qualified, the result is also qualified. If the left operand is <a href="atomic" title="c/language/atomic">atomic</a>, the behavior is undefined.</p>
<p>Note: besides identifiers that name objects of struct or union type, the following expressions may have struct or union types: <a href="operator_assignment" title="c/language/operator assignment">assignment</a>, <a href="operator_other#Function_call" title="c/language/operator other">function call</a>, <a href="operator_other#Comma_operator" title="c/language/operator other">comma operator</a>, <a href="operator_other#Conditional_operator" title="c/language/operator other">conditional operator</a>, and <a href="compound_literal" title="c/language/compound literal">compound literal</a>.</p>
<div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h>
struct s {int x;};
struct s f(void) { return (struct s){1}; }
int main(void)
{
struct s s;
s.x = 1; // ok, changes the member of s
int n = f().x; // f() is an expression of type struct s
// f().x = 1; // Error: this member access expression is not an lvalue
const struct s sc;
// sc.x = 3; // Error: sc.x is const, can't be assigned
union { int x; double d; } u = {1};
u.d = 0.1; // changes the active member of the union
}</pre></div> </div> <h3 id="Member_access_through_pointer"> Member access through pointer</h3> <p>The member access expression has the form</p>
<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <span class="t-spar">expression</span> <code>-></code> <span class="t-spar">member-name</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td>
</tr>
</table> <p>where</p>
<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">expression</span> </td> <td> - </td> <td> an expression of type <a href="pointer" title="c/language/pointer">pointer</a> to <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> </td>
</tr> <tr class="t-par"> <td> <span class="t-spar">member-name</span> </td> <td> - </td> <td> an <a href="identifier" title="c/language/identifier">identifier</a> that names a member of the struct or union pointed by <span class="t-spar">expression</span> </td>
</tr>
</table> <p>The member access through pointer expression designates the named member of the <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> type pointed to by its left operand. Its value category is always <a href="value_category" title="c/language/value category">lvalue</a></p>
<p>If the type pointed to by the left operand is <a href="const" title="c/language/const">const</a> or <a href="volatile" title="c/language/volatile">volatile</a> qualified, the result is also qualified. If the type pointed to by the left operand is <a href="atomic" title="c/language/atomic">atomic</a>, the behavior is undefined.</p>
<div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h>
struct s {int x;};
int main(void)
{
struct s s={1}, *p = &s;
p->x = 7; // changes the value of s.x through the pointer
printf("%d\n", p->x); // prints 7
}</pre></div> </div> <h3 id="Defect_reports"> Defect reports</h3> <p>The following behavior-changing defect reports were applied retroactively to previously published C standards.</p>
<table class="dsctable"> <tr> <th>DR </th> <th>Applied to </th> <th>Behavior as published </th> <th>Correct behavior </th>
</tr> <tr> <td>
<a rel="nofollow" class="external text" href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_076.html">DR 076</a> </td> <td>C89 </td> <td>unnessary indirection could not be cancelled by <code>&</code> </td> <td>made cancellable </td>
</tr>
</table> <h3 id="References"> References</h3> <ul>
<li> C17 standard (ISO/IEC 9899:2018): </li>
<ul>
<li> 6.5.2.1 Array subscripting (p: 57-58) </li>
<li> 6.5.2.3 Structure and union members (p: 58-59) </li>
<li> 6.5.3.2 Address and indirection operators (p: 59-61) </li>
</ul>
<li> C11 standard (ISO/IEC 9899:2011): </li>
<ul>
<li> 6.5.2.1 Array subscripting (p: 80) </li>
<li> 6.5.2.3 Structure and union members (p: 82-84) </li>
<li> 6.5.3.2 Address and indirection operators (p: 88-89) </li>
</ul>
<li> C99 standard (ISO/IEC 9899:1999): </li>
<ul>
<li> 6.5.2.1 Array subscripting (p: 70) </li>
<li> 6.5.2.3 Structure and union members (p: 72-74) </li>
<li> 6.5.3.2 Address and indirection operators (p: 78-79) </li>
</ul>
<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
<ul>
<li> 3.3.2.1 Array subscripting </li>
<li> 3.3.2.3 Structure and union members </li>
<li> 3.3.3.2 Address and indirection operators </li>
</ul>
</ul> <h3 id="See_also"> See also</h3> <ul><li> <a href="operator_precedence" title="c/language/operator precedence">Operator precedence</a> </li></ul> <table class="wikitable"> <tr style="text-align:center"> <th colspan="7"> Common operators </th>
</tr> <tr style="text-align:center"> <td> <a href="operator_assignment" title="c/language/operator assignment"> assignment</a> </td> <td> <a href="operator_incdec" title="c/language/operator incdec"> increment<br>decrement</a> </td> <td> <a href="operator_arithmetic" title="c/language/operator arithmetic"> arithmetic</a> </td> <td> <a href="operator_logical" title="c/language/operator logical"> logical</a> </td> <td> <a href="operator_comparison" title="c/language/operator comparison"> comparison</a> </td> <td> <strong class="selflink"> member<br>access</strong> </td> <td> <a href="operator_other" title="c/language/operator other"> other</a> </td>
</tr> <tr style="text-align:center"> <td> <p><code>a = b a += b a -= b a *= b a /= b a %= b a &= b a |= b a ^= b a <<= b a >>= b</code></p>
</td> <td> <p><code>++a --a a++ a--</code></p>
</td> <td> <p><code>+a -a a + b a - b a * b a / b a % b ~a a & b a | b a ^ b a << b a >> b</code></p>
</td> <td> <p><code>!a a && b a || b</code></p>
</td> <td> <p><code>a == b a != b a < b a > b a <= b a >= b</code></p>
</td> <td> <p><code>a[b] *a &a a->b a.b</code></p>
</td> <td> <p><code>a(...) a, b (type) a a ? b : c sizeof</code><br><br> <code>_Alignof</code><br><span class="t-mark-rev t-since-c11">(since C11)</span></p>
</td>
</tr> </table> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/operator_member_access" title="cpp/language/operator member access">C++ documentation</a></span> for <span class=""><span>Member access operators</span></span> </td>
</tr> </table> <div class="_attribution">
<p class="_attribution-p">
© cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br>
<a href="https://en.cppreference.com/w/c/language/operator_member_access" class="_attribution-link">https://en.cppreference.com/w/c/language/operator_member_access</a>
</p>
</div>
|