diff options
Diffstat (limited to 'devdocs/c/language%2Foperator_member_access.html')
| -rw-r--r-- | devdocs/c/language%2Foperator_member_access.html | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/devdocs/c/language%2Foperator_member_access.html b/devdocs/c/language%2Foperator_member_access.html new file mode 100644 index 00000000..f455d3f8 --- /dev/null +++ b/devdocs/c/language%2Foperator_member_access.html @@ -0,0 +1,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> |
