diff options
Diffstat (limited to 'devdocs/c/language%2Foperator_assignment.html')
| -rw-r--r-- | devdocs/c/language%2Foperator_assignment.html | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/devdocs/c/language%2Foperator_assignment.html b/devdocs/c/language%2Foperator_assignment.html new file mode 100644 index 00000000..3d44f9ef --- /dev/null +++ b/devdocs/c/language%2Foperator_assignment.html @@ -0,0 +1,139 @@ + <h1 id="firstHeading" class="firstHeading">Assignment operators</h1> <p>Assignment and compound assignment operators are binary operators that modify the variable to their left using the value to their right.</p> +<table class="wikitable"> <tr style="text-align:center"> <th> Operator </th> <th> Operator name </th> <th> Example </th> <th> Description </th> <th> Equivalent of </th> +</tr> <tr style="text-align:center"> <td> <code>=</code> </td> <td> basic assignment </td> <td> <code>a = b</code> </td> <td> <b>a</b> becomes equal to <b>b</b> </td> <td class="table-na"> <small>N/A</small> </td> +</tr> <tr style="text-align:center"> <td> <code>+=</code> </td> <td> addition assignment </td> <td> <code>a += b</code> </td> <td> <b>a</b> becomes equal to the addition of <b>a</b> and <b>b</b> </td> <td> <code>a = a + b</code> </td> +</tr> <tr style="text-align:center"> <td> <code>-=</code> </td> <td> subtraction assignment </td> <td> <code>a -= b</code> </td> <td> <b>a</b> becomes equal to the subtraction of <b>b</b> from <b>a</b> </td> <td> <code>a = a - b</code> </td> +</tr> <tr style="text-align:center"> <td> <code>*=</code> </td> <td> multiplication assignment </td> <td> <code>a *= b</code> </td> <td> <b>a</b> becomes equal to the product of <b>a</b> and <b>b</b> </td> <td> <code>a = a * b</code> </td> +</tr> <tr style="text-align:center"> <td> <code>/=</code> </td> <td> division assignment </td> <td> <code>a /= b</code> </td> <td> <b>a</b> becomes equal to the division of <b>a</b> by <b>b</b> </td> <td> <code>a = a / b</code> </td> +</tr> <tr style="text-align:center"> <td> <code>%=</code> </td> <td> modulo assignment </td> <td> <code>a %= b</code> </td> <td> <b>a</b> becomes equal to the remainder of <b>a</b> divided by <b>b</b> </td> <td> <code>a = a % b</code> </td> +</tr> <tr style="text-align:center"> <td> <code>&=</code> </td> <td> bitwise AND assignment </td> <td> <code>a &= b</code> </td> <td> <b>a</b> becomes equal to the bitwise AND of <b>a</b> and <b>b</b> </td> <td> <code>a = a & b</code> </td> +</tr> <tr style="text-align:center"> <td> <code>|=</code> </td> <td> bitwise OR assignment </td> <td> <code>a |= b</code> </td> <td> <b>a</b> becomes equal to the bitwise OR of <b>a</b> and <b>b</b> </td> <td> <code>a = a | b</code> </td> +</tr> <tr style="text-align:center"> <td> <code>^=</code> </td> <td> bitwise XOR assignment </td> <td> <code>a ^= b</code> </td> <td> <b>a</b> becomes equal to the bitwise XOR of <b>a</b> and <b>b</b> </td> <td> <code>a = a ^ b</code> </td> +</tr> <tr style="text-align:center"> <td> <code><<=</code> </td> <td> bitwise left shift assignment </td> <td> <code>a <<= b</code> </td> <td> <b>a</b> becomes equal to <b>a</b> left shifted by <b>b</b> </td> <td> <code>a = a << b</code> </td> +</tr> <tr style="text-align:center"> <td> <code>>>=</code> </td> <td> bitwise right shift assignment </td> <td> <code>a >>= b</code> </td> <td> <b>a</b> becomes equal to <b>a</b> right shifted by <b>b</b> </td> <td> <code>a = a >> b</code> </td> +</tr> +</table> <h3 id="Simple_assignment"> Simple assignment</h3> <p>The simple assignment operator expressions have the form</p> +<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <span class="t-spar">lhs</span> <code>=</code> <span class="t-spar">rhs</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">lhs</span> </td> <td> - </td> <td> <a href="value_category" title="c/language/value category">modifiable lvalue</a> expression of any complete object type </td> +</tr> <tr class="t-par"> <td> <span class="t-spar">rhs</span> </td> <td> - </td> <td> expression of any type <a href="conversion" title="c/language/conversion">implicitly convertible</a> to <span class="t-spar">lhs</span> or <a href="type#Compatible_types" title="c/language/type">compatible</a> with <span class="t-spar">lhs</span> </td> +</tr> +</table> <p>Assignment performs <a href="conversion" title="c/language/conversion">implicit conversion</a> from the value of <span class="t-spar">rhs</span> to the type of <span class="t-spar">lhs</span> and then replaces the value in the object designated by <span class="t-spar">lhs</span> with the converted value of <span class="t-spar">rhs</span>.</p> +<p>Assignment also returns the same value as what was stored in <code>lhs</code> (so that expressions such as <code>a = b = c</code> are possible). The <a href="value_category" title="c/language/value category">value category</a> of the assignment operator is non-lvalue (so that expressions such as <code>(a=b)=c</code> are invalid).</p> +<p><span class="t-spar">rhs</span> and <span class="t-spar">lhs</span> must satisfy one of the following:</p> +<ul> +<li> both <span class="t-spar">lhs</span> and <span class="t-spar">rhs</span> have <a href="type#Compatible_types" title="c/language/type">compatible</a> <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> type, or.. </li> +<li> <span class="t-spar">rhs</span> must be <a href="conversion" title="c/language/conversion">implicitly convertible</a> to <span class="t-spar">lhs</span>, which implies </li> +<ul> +<li> both <span class="t-spar">lhs</span> and <span class="t-spar">rhs</span> have <a href="arithmetic_types" title="c/language/arithmetic types">arithmetic types</a>, in which case <span class="t-spar">lhs</span> may be <a href="volatile" title="c/language/volatile">volatile</a>-qualified<span class="t-rev-inl t-since-c11"><span> or <a href="atomic" title="c/language/atomic">atomic</a></span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> </li> +<li> both <span class="t-spar">lhs</span> and <span class="t-spar">rhs</span> have <a href="pointer" title="c/language/pointer">pointer</a> to <a href="type#Compatible_types" title="c/language/type">compatible</a> (ignoring qualifiers) types, or one of the pointers is a pointer to void, and the <a href="conversion" title="c/language/conversion">conversion</a> would not add qualifiers to the pointed-to type. <span class="t-spar">lhs</span> may be <a href="volatile" title="c/language/volatile">volatile</a><span class="t-rev-inl t-since-c99"><span> or <a href="restrict" title="c/language/restrict">restrict</a></span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>-qualified<span class="t-rev-inl t-since-c11"><span> or <a href="atomic" title="c/language/atomic">atomic</a></span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span>. </li> +<li> <span class="t-spar">lhs</span> is a (possibly qualified<span class="t-rev-inl t-since-c11"><span> or atomic</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span>) pointer and <span class="t-spar">rhs</span> is a null pointer constant such as <code><a href="../types/null" title="c/types/NULL">NULL</a></code> <span class="t-rev-inl t-since-c23"><span>or a <code><a href="../types/nullptr_t" title="c/types/nullptr t">nullptr_t</a></code> value</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> </li> +</ul> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <ul><li> <span class="t-spar">lhs</span> has type (possibly qualified<span class="t-rev-inl t-since-c11"><span> or atomic</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span>) <code>_Bool</code> and <span class="t-spar">rhs</span> is a pointer <span class="t-rev-inl t-since-c23"><span>or a <code><a href="../types/nullptr_t" title="c/types/nullptr t">nullptr_t</a></code> value</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> </li></ul> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <table class="t-rev-begin"> <tr class="t-rev t-since-c23"> +<td> <ul><li> <span class="t-spar">lhs</span> has type (possibly qualified or atomic) <code><a href="../types/nullptr_t" title="c/types/nullptr t">nullptr_t</a></code> and <span class="t-spar">rhs</span> has type <code><a href="../types/nullptr_t" title="c/types/nullptr t">nullptr_t</a></code> </li></ul> </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <h4 id="Notes"> Notes</h4> <p>If <span class="t-spar">rhs</span> and <span class="t-spar">lhs</span> overlap in memory (e.g. they are members of the same union), the behavior is undefined unless the overlap is exact and the types are <a href="type#Compatible_types" title="c/language/type">compatible</a>.</p> +<p>Although arrays are not assignable, an array wrapped in a struct is assignable to another object of the same (or compatible) struct type.</p> +<p>The side effect of updating <span class="t-spar">lhs</span> is <a href="eval_order" title="c/language/eval order">sequenced after</a> the value computations, but not the side effects of <span class="t-spar">lhs</span> and <span class="t-spar">rhs</span> themselves and the evaluations of the operands are, as usual, unsequenced relative to each other (so the expressions such as <code>i=++i</code>; are undefined)</p> +<p>Assignment strips extra range and precision from floating-point expressions (see <code><a href="../types/limits/flt_eval_method" title="c/types/limits/FLT EVAL METHOD">FLT_EVAL_METHOD</a></code>).</p> +<p>In C++, assignment operators are lvalue expressions, not so in C.</p> +<div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h> + +int main(void) +{ + // integers + int i = 1, j = 2, k = 3; // initialization, not assignment + + i = j = k; // values of i and j are now 3 +// (i = j) = k; // Error: lvalue required + printf("%d %d %d\n", i, j, k); + + // pointers + const char c = 'A'; // initialization; not assignment + const char *p = &c; // initialization; not assignment + const char **cpp = &p; // initialization; not assignment + +// cpp = &p; // Error: char** is not convertible to const char** + *cpp = &c; // OK, char* is convertible to const char* + printf("%c \n", **cpp); + cpp = 0; // OK, null pointer constant is convertible to any pointer + + // arrays + int arr1[2] = {1,2}, arr2[2] = {3, 4}; +// arr1 = arr2; // Error: cannot assign to an array + printf("arr1[0]=%d arr1[1]=%d arr2[0]=%d arr2[1]=%d\n", + arr1[0], arr1[1], arr2[0], arr2[1]); + + struct { int arr[2]; } sam1 = { {5, 6} }, sam2 = { {7, 8} }; + sam1 = sam2; // OK: can assign arrays wrapped in structs + + printf("%d %d \n", sam1.arr[0], sam1.arr[1]); +}</pre></div> <p>Output:</p> +<div class="text source-text"><pre data-language="c">3 3 3 +A +arr1[0]=1 arr1[1]=2 arr2[0]=3 arr2[1]=4 +7 8</pre></div> </div> <h3 id="Compound_assignment"> Compound assignment</h3> <p>The compound assignment operator expressions have the form</p> +<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <span class="t-spar">lhs</span> <span class="t-spar">op</span> <span class="t-spar">rhs</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">op</span> </td> <td> - </td> <td> one of <code>*=</code>, <code>/=</code> <code>%=</code>, <code>+=</code> <code>-=</code>, <code><<=</code>, <code>>>=</code>, <code>&=</code>, <code>^=</code>, <code>|=</code> </td> +</tr> <tr class="t-par"> <td> <span class="t-spar">lhs</span>, <span class="t-spar">rhs</span> </td> <td> - </td> <td> expressions with <a href="arithmetic_types" title="c/language/arithmetic types">arithmetic types</a> (where <span class="t-spar">lhs</span> may be qualified or atomic), except when <span class="t-spar">op</span> is <code>+=</code> or <code>-=</code>, which also accept pointer types with the same restrictions as + and - </td> +</tr> +</table> <p>The expression <span class="t-spar">lhs</span> <span class="t-spar">@=</span> <span class="t-spar">rhs</span> is exactly the same as <span class="t-spar">lhs</span> <code>=</code> <span class="t-spar">lhs</span> <span class="t-spar">@</span> <code>(</code> <span class="t-spar">rhs</span> <code>)</code>, except that <span class="t-spar">lhs</span> is evaluated only once.</p> +<table class="t-rev-begin"> <tr class="t-rev t-since-c11"> +<td> <p>If <span class="t-spar">lhs</span> has <a href="atomic" title="c/language/atomic">atomic</a> type, the operation behaves as a single atomic read-modify-write operation with memory order <code><a href="../atomic/memory_order" title="c/atomic/memory order">memory_order_seq_cst</a></code>.</p> +<p>For integer atomic types, the compound assignment <code>@=</code> is equivalent to:</p> +<div class="c source-c"><pre data-language="c">T1* addr = &lhs; +T2 val = rhs; +T1 old = *addr; +T1 new; +do { new = old @ val } while (!atomic_compare_exchange_strong(addr, &old, new);</pre></div> </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td> +</tr> </table> <div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h> + +int main(void) +{ + int x = 10; + int hundred = 100; + int ten = 10; + int fifty = 50; + + printf("%d %d %d %d\n", x, hundred, ten, fifty); + + hundred *= x; + ten /= x; + fifty %= x; + + printf("%d %d %d %d\n", x, hundred, ten, fifty); + + return 0; +}</pre></div> <p>Output:</p> +<div class="text source-text"><pre data-language="c">10 100 10 50 +10 1000 1 0</pre></div> </div> <h3 id="References"> References</h3> <ul> +<li> C17 standard (ISO/IEC 9899:2018): </li> +<ul><li> 6.5.16 Assignment operators (p: 72-73) </li></ul> +<li> C11 standard (ISO/IEC 9899:2011): </li> +<ul><li> 6.5.16 Assignment operators (p: 101-104) </li></ul> +<li> C99 standard (ISO/IEC 9899:1999): </li> +<ul><li> 6.5.16 Assignment operators (p: 91-93) </li></ul> +<li> C89/C90 standard (ISO/IEC 9899:1990): </li> +<ul><li> 3.3.16 Assignment operators </li></ul> +</ul> <h3 id="See_Also"> See Also</h3> <p><a href="operator_precedence" title="c/language/operator precedence"> Operator precedence</a></p> +<table class="wikitable"> <tr style="text-align:center"> <th colspan="7"> Common operators </th> +</tr> <tr style="text-align:center"> <td> <strong class="selflink"> assignment</strong> </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> <a href="operator_member_access" title="c/language/operator member access"> member<br>access</a> </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> <h3 id="See_also_2"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/operator_assignment" title="cpp/language/operator assignment">C++ documentation</a></span> for <span class=""><span>Assignment 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_assignment" class="_attribution-link">https://en.cppreference.com/w/c/language/operator_assignment</a> + </p> +</div> |
