Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The rule for <a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf" rel="noreferrer">C</a> is as follows:</p> <blockquote> <b>6.3.2.1 Lvalues, arrays, and function designators</b><br> ...<br> 3 Except when it is the operand of the <b>sizeof</b> operator or the unary <b>&</b> operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined. </blockquote> <p>The language for <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf" rel="noreferrer">C++</a> is a little different:</p> <blockquote> <b>4.2 Array-to-pointer conversion [conv.array]</b><br> <br> 1 An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to an rvalue of type “pointer to T”. The result is a pointer to the first element of the array.<br> ...<br> <b>8.3.4 Arrays [dcl.array]</b><br> ...<br> 7 A consistent rule is followed for multidimensional arrays. If E is an n-dimensional array of rank <i>i</i> × <i>j</i> × ... × <i>k</i>, then E appearing in an expression is converted to a pointer to an (<i>n</i>−1)-dimensional array with rank <i>j</i> × ... × <i>k</i>. If the <b>*</b> operator, either explicitly or implicitly as a result of subscripting, is applied to this pointer, the result is the pointed-to (<i>n</i>−1)-dimensional array, which itself is immediately converted into a pointer. </blockquote> <p>So the following all hold true:</p> <pre><code>Declaration Expression Type Decays to ----------- ---------- ---- --------- T a[N] a T [N] T * &amp;a T (*)[N] *a T a[i] T T a[M][N] a T [M][N] T (*)[N] &amp;a T (*)[M][N] *a T [N] T * a[i] T [N] T * &amp;a[i] T (*)[N] *a[i] T a[i][j] T T a[M][N][O] a T [M][N][O] T (*)[M][N] &amp;a T (*)[M][N][O] *a T [M][N] T (*)[N] a[i] T [M][N] T (*)[N] &amp;a[i] T (*)[M][N] *a[i] T [N] T * a[i][j] T [N] T * &amp;a[i][j] T (*)[N] *a[i][j] T a[i][j][k] T </code></pre> <p>The pattern should be clear for higher-dimensional arrays. </p> <p>So let's analyze your dictionary:</p> <pre><code>/* list of words and meanings */ char *dic[][40] = { "atlas", "A volume of maps.", "car", "A motorized vehicle.", "telephone", "A communication device.", "airplane", "A flying machine.", "", "" /* null terminate the list */ }; </code></pre> <p>This isn't going to set up your dictionary the way you want; you've basically set this up as a 1-element array of 40 pointers to char. If you want an array of pairs of strings, then the declaration should look like this:</p> <pre><code>char *dic[][2] = { {"atlas", "A volume of maps"}, {"car", "A motorized vehicle"}, {"telephone", "A communication device"}, {"airplane" , "A flying machine"}, {NULL, NULL} // empty strings and NULLs are different things. }; </code></pre> <p>The type of <code>dic</code> is "5-element array of 2-element arrays of pointer to char", or <code>char *[5][2]</code>. Going by the rules above, the expression <code>dic</code> should decay to <code>char *(*)[2]</code> -- a pointer to a 2-element array of pointer to char. </p> <p>A function to search this dictionary would then look like this:</p> <pre><code>char *definition(char *term, char *(*dictionary)[2]) // *NOT* char ***dictionary { while ((*dictionary)[0] != NULL &amp;&amp; strcmp((*dictionary)[0], term) != 0) dictionary++; return (*dictionary)[1]; } </code></pre> <p>and you would call it from your main function like</p> <pre><code>char *def = definition(term, dic); </code></pre> <p>Note that we have to use parentheses around the <code>*dictionary</code> expression in the function. The array subscript operator <code>[]</code> has higher precedence than the dereference operator <code>*</code>, and we don't want to subscript into <code>dictionary</code> directly, we want to subscript into the array that <code>dictionary</code> <em>points to</em>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload