Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As you are just learning C, I recommend you to really try to understand the <em>differences</em> between arrays and pointers first instead of the <em>common</em> things. </p> <p>In the area of parameters and arrays, there are a few confusing rules that should be clear before going on. First, <strong>what you declare in a parameter list is treated special.</strong> There are such situations where things don't make sense as a function parameter in C. These are</p> <ul> <li>Functions as parameters</li> <li>Arrays as parameters</li> </ul> <h2>Arrays as parameters </h2> <p>The second maybe is not immediately clear. But it becomes clear when you consider that the size of an array dimension is part of the type in C (and an array whose dimension size isn't given has an incomplete type). So, if you would create a function that takes an array by-value (receives a copy), then it could do so only for one size! In addition, arrays can become large, and C tries to be as fast as possible. </p> <p>In C, for these reasons, <strong>array-values</strong> are not existent. If you want to get the value of an array, what you get instead is a pointer to the first element of that array. And herein actually already lies the solution. Instead of drawing an array parameter invalid up-front, a C compiler will <strong>transform</strong> the type of the respective parameter to be a pointer. Remember this, it's very important. The parameter won't be an array, but instead it will be a pointer to the respective element type. </p> <p>Now, if you try to pass an array, what is passed instead is a pointer to the arrays' first element. </p> <h3>Excursion: Functions as parameters</h3> <p>For completion, and because I think this will help you better understand the matter, let's look what the state of affairs is when you try to have a function as a parameter. Indeed, first it won't make any sense. How can a parameter be a function? Huh, we want a variable at that place, of course! So what the compiler does when that happens is, again, to <strong>transform</strong> the function into a <strong>function pointer</strong>. Trying to pass a function will pass a pointer to that respective function instead. So, the following are the same (analogous to the array example):</p> <pre><code>void f(void g(void)); void f(void (*g)(void)); </code></pre> <p>Note that parentheses around <code>*g</code> is needed. Otherwise, it would specify a function returning <code>void*</code>, instead of a pointer to a function returning <code>void</code>.</p> <h2>Back to arrays</h2> <p>Now, I said at the beginning that arrays can have an incomplete type - which happens if you don't give a size yet. Since we already figured that an array parameter is not existent but instead any array parameter is a pointer, the array's size doesn't matter. That means, the compiler will translate all of the following, and all are the same thing:</p> <pre><code>int main(int c, char **argv); int main(int c, char *argv[]); int main(int c, char *argv[1]); int main(int c, char *argv[42]); </code></pre> <p>Of course, it doesn't make much sense to be able to put any size in it, and it's just thrown away. For that reason, C99 came up with a new meaning for those numbers, and allows other things to appear between the brackets:</p> <pre><code>// says: argv is a non-null pointer pointing to at least 5 char*'s // allows CPU to pre-load some memory. int main(int c, char *argv[static 5]); // says: argv is a constant pointer pointing to a char* int main(int c, char *argv[const]); // says the same as the previous one int main(int c, char ** const argv); </code></pre> <p>The last two lines say that you won't be able to change "argv" within the function - it has become a const pointer. Only few C compilers support those C99 features though. But these features make it clear that the "array" isn't actually one. It's a pointer. </p> <h2>A word of warning</h2> <p>Note that all i said above is true only when you have got an array as a <strong>parameter</strong> of a function. If you work with local arrays, an array won't be a pointer. It will <em>behave</em> as a pointer, because as explained earlier an array will be converted to a pointer when its value is read. But it should not be confused with pointers. </p> <p>One classic example is the following:</p> <pre><code>char c[10]; char **c = &amp;c; // does not work. typedef char array[10]; array *pc = &amp;c; // *does* work. // same without typedef. Parens needed, because [...] has // higher precedence than '*'. Analogous to the function example above. char (*array)[10] = &amp;c; </code></pre>
 

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