Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Arrays and pointers are completely different animals. In most contexts, an <em>expression</em> designating an array is treated as a pointer. </p> <p>First, a little standard language (<a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf" rel="nofollow">n1256</a>):</p> <blockquote> <b>6.3.2.1 Lvalues, arrays, and function designators</b><br> ...<br> 3 Except when it is the operand of the <code>sizeof</code> operator or the unary <code>&</code> operator, or is a string literal used to initialize an array, an expression that has type "array of <i>type</i>" is converted to an expression with type "pointer to <i>type</i>" 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.<br></blockquote> <p>The string literal "this is a test" is a 15-element array of <code>char</code>. In the declaration<br><br> <pre><code> char *string1 = "this is a test"; </code></pre><br> <code>string1</code> is being declared as a pointer to <code>char</code>. Per the language above, the type of the <em>expression</em> "this is a test" is converted from <code>char [15]</code> to <code>char *</code>, and the resulting pointer value is assigned to <code>string1</code>.<br> <br><br> In the declaration <br><br></p> <pre><code> char string2[] = "this is a test"; </code></pre> <p><br> something different happens. More standard language: <br><br></p> <blockquote> <b>6.7.8 Initialization</b><br> ...<br> 14 An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.<br> ...<br> 22 If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. At the end of its initializer list, the array no longer has incomplete type. </blockquote> <p>In this case, <code>string2</code> is being declared as an array of <code>char</code>, its size is computed from the length of the initializer, and the <em>contents</em> of the string literal are copied to the array. </p> <p>Here's a hypothetical memory map to illustrate what's happening: <br></p> <pre> Item Address 0x00 0x01 0x02 0x03 ---- ------- ---- ---- ---- ---- <i>no name</i> 0x08001230 't' 'h' 'i' 's' 0x08001234 ' ' 'i' 's' ' ' 0x08001238 'a' ' ' 't' 'e' 0x0800123C 's' 't' 0 ... string1 0x12340000 0x08 0x00 0x12 0x30 string2 0x12340004 't' 'h' 'i' 's' 0x12340008 ' ' 'i' 's' ' ' 0x1234000C 'a' ' ' 't' 'e' 0x1234000F 's' 't' 0 </pre> <p>String literals have static extent; that is, the memory for them is set aside at program startup and held until the program terminates. Attempting to modify the contents of a string literal invokes undefined behavior; the underlying platform may or may not allow it, and the standard places no restrictions on the compiler. It's best to act as though literals are always unwritable. </p> <p>In my memory map above, the address of the string literal is set off somewhat from the addresses of <code>string1</code> and <code>string2</code> to illustrate this.</p> <p>Anyway, you can see that <code>string1</code>, having a pointer type, contains the <em>address</em> of the string literal. <code>string2</code>, being an array type, contains a copy of the <em>contents</em> of the string literal. </p> <p>Since the size of <code>string2</code> is known at compile time, <code>sizeof</code> returns the size (number of bytes) in the array. </p> <p>The <code>%i</code> conversion specifier is not the right one to use for expressions of type <code>size_t</code>. If you're working in C99, use <code>%zu</code>. In C89, you would use <code>%lu</code> and cast the expression to <code>unsigned long</code>: <br></p> <pre><code> C89: printf("%lu, %lu\n", (unsigned long) sizeof string1, (unsigned long) sizeof string2); C99: printf("%zu, %zu\n", sizeof string1, sizeof string2); </code></pre> <p>Note that <code>sizeof</code> is an <em>operator</em>, not a function call; when the operand is an expression that denotes an <em>object</em>, parentheses aren't necessary (although they don't hurt). </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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