diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/c/language%2Farray_initialization.html | |
new repository
Diffstat (limited to 'devdocs/c/language%2Farray_initialization.html')
| -rw-r--r-- | devdocs/c/language%2Farray_initialization.html | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/devdocs/c/language%2Farray_initialization.html b/devdocs/c/language%2Farray_initialization.html new file mode 100644 index 00000000..c740231b --- /dev/null +++ b/devdocs/c/language%2Farray_initialization.html @@ -0,0 +1,127 @@ + <h1 id="firstHeading" class="firstHeading">Array initialization</h1> <p>When <a href="initialization" title="c/language/initialization">initializing</a> an object of <a href="array" title="c/language/array">array</a> type, the initializer must be either a <a href="string_literal" title="c/language/string literal">string literal</a> (optionally enclosed in braces) or be a brace-enclosed list of initialized for array members:</p> +<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <code>=</code> <span class="t-spar">string-literal</span> </td> <td> (1) </td> <td class="t-sdsc-nopad"> </td> +</tr> <tr class="t-sdsc"> <td> <code>=</code> <code>{</code> <span class="t-spar">expression</span> <code>,</code> <code>...</code> <code>}</code> </td> <td> (2) </td> <td> <span class="t-mark-rev t-until-c99">(until C99)</span> </td> +</tr> <tr class="t-sdsc"> <td> <code>=</code> <code>{</code> <span class="t-spar">designator</span><span class="t-mark">(optional)</span> <span class="t-spar">expression</span> <code>,</code> <code>...</code> <code>}</code> </td> <td> (2) </td> <td> <span class="t-mark-rev t-since-c99">(since C99)</span> </td> +</tr> <tr class="t-sdsc"> <td> <code>=</code> <code>{</code> <code>}</code> </td> <td> (3) </td> <td> <span class="t-mark-rev t-since-c23">(since C23)</span> </td> +</tr> +</table> <div class="t-li1"> +<span class="t-li">1)</span> string literal initializer for character and wide character arrays</div> <div class="t-li1"> +<span class="t-li">2)</span> comma-separated list of <span class="t-rev-inl t-until-c99"><span>constant</span><span><span class="t-mark-rev t-until-c99">(until C99)</span></span></span> expressions that are initializers for array elements<span class="t-rev-inl t-since-c99"><span>, optionally using array designators of the form <code>[</code> <span class="t-spar">constant-expression</span> <code>]</code> <code>=</code> </span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> +</div> <div class="t-li1"> +<span class="t-li">3)</span> empty initializer empty-initializes every element of the array</div> <p>Arrays of known size and arrays of unknown size may be initialized<span class="t-rev-inl t-since-c99 t-until-c23"><span>, but not VLAs</span><span><span class="t-mark-rev t-since-c99">(since C99)</span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span>.<span class="t-rev-inl t-since-c23"><span> A VLA can only be empty-initialized.</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span></p> +<p>All array elements that are not initialized explicitly are <a href="initialization#Empty_initialization" title="c/language/initialization">empty-initialized</a>.</p> +<h3 id="Initialization_from_strings"> Initialization from strings</h3> <p><a href="string_literal" title="c/language/string literal">String literal</a> (optionally enclosed in braces) may be used as the initializer for an array of matching type:</p> +<ul> +<li> ordinary string literals<span class="t-rev-inl t-since-c11"><span> and UTF-8 string literals</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> can initialize arrays of any character type (<code>char</code>, <code>signed char</code>, <code>unsigned char</code>) </li> +<li> L-prefixed wide string literals can be used to initialize arrays of any type compatible with (ignoring cv-qualifications) <code>wchar_t</code> </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c11"> +<td> <ul> +<li> u-prefixed wide string literals can be used to initialize arrays of any type compatible with (ignoring cv-qualifications) <code>char16_t</code> </li> +<li> U-prefixed wide string literals can be used to initialize arrays of any type compatible with (ignoring cv-qualifications) <code>char32_t</code> </li> +</ul> </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td> +</tr> </table> <p>Successive bytes of the string literal or wide characters of the wide string literal, including the terminating null byte/character, initialize the elements of the array:</p> +<div class="c source-c"><pre data-language="c">char str[] = "abc"; // str has type char[4] and holds 'a', 'b', 'c', '\0' +wchar_t wstr[4] = L"猫"; // str has type wchar_t[4] and holds L'猫', '\0', '\0', '\0'</pre></div> <p>If the size of the array is known, it may be one less than the size of the string literal, in which case the terminating null character is ignored:</p> +<div class="c source-c"><pre data-language="c">char str[3] = "abc"; // str has type char[3] and holds 'a', 'b', 'c'</pre></div> <p>Note that the contents of such array are modifiable, unlike when accessing a string literal directly with <code>char* str = "abc";</code>.</p> +<h3 id="Initialization_from_brace-enclosed_lists"> Initialization from brace-enclosed lists</h3> <p>When an array is initialized with a brace-enclosed list of initializers, the first initializer in the list initializes the array element at index zero<span class="t-rev-inl t-since-c99"><span> (unless a designator is specified)</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>, and each subsequent initializer <span class="t-rev-inl t-since-c99"><span>without a designator </span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>initializes the array element at index one greater than the one initialized by the previous initializer.</p> +<div class="c source-c"><pre data-language="c">int x[] = {1,2,3}; // x has type int[3] and holds 1,2,3 +int y[5] = {1,2,3}; // y has type int[5] and holds 1,2,3,0,0 +int z[4] = {1}; // z has type int[4] and holds 1,0,0,0 +int w[3] = {0}; // w has type int[3] and holds all zeroes</pre></div> <p>It's an error to provide more initializers than elements when initializing an array of known size (except when initializing character arrays from string literals).</p> +<table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <p>A designator causes the following initializer to initialize of the array element described by the designator. Initialization then continues forward in order, beginning with the next element after the one described by the designator.</p> +<div class="c source-c"><pre data-language="c">int n[5] = {[4]=5,[0]=1,2,3,4}; // holds 1,2,3,4,5 + +int a[MAX] = { // starts initializing a[0] = 1, a[1] = 3, ... + 1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0 +}; +// for MAX=6, array holds 1,8,6,4,2,0 +// for MAX=13, array holds 1,3,5,7,9,0,0,0,8,6,4,2,0 ("sparse array")</pre></div> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <p>When initializing an array of unknown size, the largest subscript for which an initializer is specified determines the size of the array being declared.</p> +<h3 id="Nested_arrays"> Nested arrays</h3> <p>If the elements of an array are arrays, structs, or unions, the corresponding initializers in the brace-enclosed list of initializers are any initializers that are valid for those members, except that their braces may be omitted as follows:</p> +<p>If the nested initializer begins with an opening brace, the entire nested initializer up to its closing brace initializes the corresponding array element:</p> +<div class="c source-c"><pre data-language="c">int y[4][3] = { // array of 4 arrays of 3 ints each (4x3 matrix) + { 1 }, // row 0 initialized to {1, 0, 0} + { 0, 1 }, // row 1 initialized to {0, 1, 0} + { [2]=1 }, // row 2 initialized to {0, 0, 1} +}; // row 3 initialized to {0, 0, 0}</pre></div> <p>If the nested initializer does not begin with an opening brace, only enough initializers from the list are taken to account for the elements or members of the sub-array, struct or union; any remaining initializers are left to initialize the next array element:</p> +<div class="c source-c"><pre data-language="c">int y[4][3] = { // array of 4 arrays of 3 ints each (4x3 matrix) +1, 3, 5, 2, 4, 6, 3, 5, 7 // row 0 initialized to {1, 3, 5} +}; // row 1 initialized to {2, 4, 6} + // row 2 initialized to {3, 5, 7} + // row 3 initialized to {0, 0, 0} + +struct { int a[3], b; } w[] = { { 1 }, 2 }; // array of structs + // { 1 } is taken to be a fully-braced initializer for element #0 of the array + // that element is initialized to { {1, 0, 0}, 0} + // 2 is taken to be the first initialized for element #1 of the array + // that element is initialized { {2, 0, 0}, 0}</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <p>Array designators may be nested; the bracketed constant expression for nested arrays follows the bracketed constant expression for the outer array:</p> +<div class="c source-c"><pre data-language="c">int y[4][3] = {[0][0]=1, [1][1]=1, [2][0]=1}; // row 0 initialized to {1, 0, 0} + // row 1 initialized to {0, 1, 0} + // row 2 initialized to {1, 0, 0} + // row 3 initialized to {0, 0, 0}</pre></div> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <h3 id="Notes"> Notes</h3> <p>The <a href="eval_order" title="c/language/eval order">order of evaluation</a> of subexpressions in an array initializer is indeterminately sequenced in C (but not in C++ since C++11):</p> +<div class="c source-c"><pre data-language="c">int n = 1; +int a[2] = {n++, n++}; // unspecified, but well-defined behavior, + // n is incremented twice (in arbitrary order) + // a initialized to {1, 2} and to {2, 1} are both valid +puts((char[4]){'0'+n} + n++); // undefined behavior: + // increment and read from n are unsequenced</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-until-c23"> +<td> <p>In C, the braced list of an initializer cannot be empty. C++ allows empty list:</p> +</td> <td><span class="t-mark-rev t-until-c23">(until C23)</span></td> +</tr> <tr class="t-rev t-since-c23"> +<td> <p>An empty initializer can be used to initialize an array:</p> +</td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <div class="c source-c"><pre data-language="c">int a[3] = {0}; // valid C and C++ way to zero-out a block-scope array +int a[3] = {}; // valid C++ way to zero-out a block-scope array; valid in C since C23</pre></div> <p>As with all other <a href="initialization" title="c/language/initialization">initialization</a>, every expression in the initializer list must be a <a href="constant_expression" title="c/language/constant expression">constant expression</a> when initializing arrays of static or thread-local <a href="storage_duration" title="c/language/storage duration">storage duration</a>:</p> +<div class="c source-c"><pre data-language="c">static char* p[2] = {malloc(1), malloc(2)}; // error</pre></div> <h3 id="Example"> Example</h3> <div class="t-example"> <div class="c source-c"><pre data-language="c">int main(void) +{ + // The following four array declarations are the same + short q1[4][3][2] = { + { 1 }, + { 2, 3 }, + { 4, 5, 6 } + }; + + short q2[4][3][2] = {1, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 4, 5, 6}; + + short q3[4][3][2] = { + { + { 1 }, + }, + { + { 2, 3 }, + }, + { + { 4, 5 }, + { 6 }, + } + }; + + short q4[4][3][2] = {1, [1]=2, 3, [2]=4, 5, 6}; + + + // Character names can be associated with enumeration constants + // using arrays with designators: + enum { RED, GREEN, BLUE }; + const char *nm[] = { + [RED] = "red", + [GREEN] = "green", + [BLUE] = "blue", + }; +}</pre></div> </div> <h3 id="References"> References</h3> <ul> +<li> C17 standard (ISO/IEC 9899:2018): </li> +<ul><li> 6.7.9/12-39 Initialization (p: 101-105) </li></ul> +<li> C11 standard (ISO/IEC 9899:2011): </li> +<ul><li> 6.7.9/12-38 Initialization (p: 140-144) </li></ul> +<li> C99 standard (ISO/IEC 9899:1999): </li> +<ul><li> 6.7.8/12-38 Initialization (p: 126-130) </li></ul> +<li> C89/C90 standard (ISO/IEC 9899:1990): </li> +<ul><li> 6.5.7 Initialization </li></ul> +</ul> <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/array_initialization" class="_attribution-link">https://en.cppreference.com/w/c/language/array_initialization</a> + </p> +</div> |
