Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
C syntax
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Arrays=== ====Array definition==== Arrays are used in C to represent structures of consecutive elements of the same type. The definition of a (fixed-size) array has the following syntax: <syntaxhighlight lang=C>int array[100];</syntaxhighlight> which defines an array named ''array'' to hold 100 values of the primitive type {{code|int}}. If declared within a function, the array dimension may also be a non-constant expression, in which case memory for the specified number of elements will be allocated. In most contexts in later use, a mention of the variable ''array'' is converted to a pointer to the first item in the array. The [[sizeof|{{code|sizeof}}]] operator is an exception: {{code|sizeof array}} yields the size of the entire array (that is, 100 times the size of an {{code|int}}, and {{code|sizeof(array) / sizeof(int)}} will return 100). Another exception is the & (address-of) operator, which yields a pointer to the entire array, for example <syntaxhighlight lang=C>int (*ptr_to_array)[100] = &array;</syntaxhighlight> ====Accessing elements==== The primary facility for accessing the values of the elements of an array is the array subscript operator. To access the ''i''-indexed element of ''array'', the syntax would be {{code|array[i]}}, which refers to the value stored in that array element. Array subscript numbering begins at 0 (see [[Zero-based indexing]]). The largest allowed array subscript is therefore equal to the number of elements in the array minus 1. To illustrate this, consider an array ''a'' declared as having 10 elements; the first element would be {{code|a[0]}} and the last element would be {{code|a[9]}}. C provides no facility for automatic [[bounds checking]] for array usage. Though logically the last subscript in an array of 10 elements would be 9, subscripts 10, 11, and so forth could accidentally be specified, with undefined results. Due to arrays and pointers being interchangeable, the addresses of each of the array elements can be expressed in equivalent [[pointer arithmetic]]. The following table illustrates both methods for the existing array: {| class="wikitable" style="margin-left: auto; margin-right: auto; text-align: center" |+ Array subscripts vs. pointer arithmetic ! style="text-align: left" | Element ! First ! Second ! Third ! ''n''th |- ! style="text-align: left" | Array subscript | {{C-lang|array[0]}} | {{C-lang|array[1]}} | {{C-lang|array[2]}} | {{C-lang|array[n - 1]}} |- ! style="text-align: left" | Dereferenced pointer | {{C-lang|*array}} | {{C-lang|*(array + 1)}} | {{C-lang|*(array + 2)}} | {{C-lang|*(array + n - 1)}} |} Since the expression {{code|a[i]}} is semantically equivalent to {{code|*(a+i)}}, which in turn is equivalent to {{code|*(i+a)}}, the expression can also be written as {{code|i[a]}}, although this form is rarely used. ====Variable-length arrays==== [[C99]] standardised [[variable-length array]]s (VLAs) within block scope. Such array variables are allocated based on the value of an integer value at runtime upon entry to a block, and are deallocated at the end of the block.<ref name="bk21st" /> As of [[C11 (C standard revision)|C11]] this feature is no longer required to be implemented by the compiler. <syntaxhighlight lang=C> int n = ...; int a[n]; a[3] = 10; </syntaxhighlight> This syntax produces an array whose size is fixed until the end of the block. ====Dynamic arrays==== {{main|C dynamic memory allocation}} Arrays that can be resized dynamically can be produced with the help of the [[C standard library]]. The <code>[[malloc]]</code> function provides a simple method for allocating memory. It takes one parameter: the amount of memory to allocate in bytes. Upon successful allocation, {{code|malloc}} returns a generic ({{code|void}}) pointer value, pointing to the beginning of the allocated space. The pointer value returned is converted to an appropriate type implicitly by assignment. If the allocation could not be completed, {{code|malloc}} returns a [[null pointer]]. The following segment is therefore similar in function to the above desired declaration: <syntaxhighlight lang=C> #include <stdlib.h> /* declares malloc */ ... int *a = malloc(n * sizeof *a); a[3] = 10; </syntaxhighlight> The result is a "pointer to {{code|int}}" variable (''a'') that points to the first of ''n'' contiguous {{code|int}} objects; due to array–pointer equivalence this can be used in place of an actual array name, as shown in the last line. The advantage in using this [[dynamic allocation]] is that the amount of memory that is allocated to it can be limited to what is actually needed at run time, and this can be changed as needed (using the standard library function [[realloc|{{code|realloc}}]]). When the dynamically allocated memory is no longer needed, it should be released back to the run-time system. This is done with a call to the {{code|free}} function. It takes a single parameter: a pointer to previously allocated memory. This is the value that was returned by a previous call to {{code|malloc}}. As a security measure, some programmers {{who|date=August 2020}} then set the pointer variable to {{code|NULL}}: <syntaxhighlight lang=C> free(a); a = NULL; </syntaxhighlight> This ensures that further attempts to dereference the pointer, on most systems, will crash the program. If this is not done, the variable becomes a [[dangling pointer]] which can lead to a use-after-free bug. However, if the pointer is a local variable, setting it to {{code|NULL}} does not prevent the program from using other copies of the pointer. Local use-after-free bugs are usually easy for [[static analyzer]]s to recognize. Therefore, this approach is less useful for local pointers and it is more often used with pointers stored in long-living structs. In general though, setting pointers to {{code|NULL}} is good practice {{according to whom|date=August 2020}} as it allows a programmer to {{code|NULL}}-check pointers prior to dereferencing, thus helping prevent crashes. Recalling the array example, one could also create a fixed-size array through dynamic allocation: <syntaxhighlight lang=C> int (*a)[100] = malloc(sizeof *a); </syntaxhighlight> ...Which yields a pointer-to-array. Accessing the pointer-to-array can be done in two ways: <syntaxhighlight lang=C> (*a)[index]; index[*a]; </syntaxhighlight> Iterating can also be done in two ways: <syntaxhighlight lang=C> for (int i = 0; i < 100; i++) (*a)[i]; for (int *i = a[0]; i < a[1]; i++) *i; </syntaxhighlight> The benefit to using the second example is that the numeric limit of the first example isn't required, which means that the pointer-to-array could be of any size and the second example can execute without any modifications. ====Multidimensional arrays==== In addition, C supports arrays of multiple dimensions, which are stored in [[row-major order]]. Technically, C multidimensional arrays are just one-dimensional arrays whose elements are arrays. The syntax for declaring multidimensional arrays is as follows: <syntaxhighlight lang=C>int array2d[ROWS][COLUMNS];</syntaxhighlight> where ''ROWS'' and ''COLUMNS'' are constants. This defines a two-dimensional array. Reading the subscripts from left to right, ''array2d'' is an array of length ''ROWS'', each element of which is an array of ''COLUMNS'' integers. To access an integer element in this multidimensional array, one would use <syntaxhighlight lang=C>array2d[4][3]</syntaxhighlight> Again, reading from left to right, this accesses the 5th row, and the 4th element in that row. The expression {{code|array2d[4]}} is an array, which we are then subscripting with [3] to access the fourth integer. {| class="wikitable" style="margin-left: auto; margin-right: auto; text-align: center" |+ Array subscripts vs. pointer arithmetic<ref>{{cite book|last=Balagurusamy|first=E|title=Programming in ANSI C|publisher=Tata McGraw Hill|pages=366}}</ref> ! style="text-align: left" | Element ! First ! Second row, second column ! ''i''th row, ''j''th column |- ! style="text-align: left" | Array subscript | {{C-lang|array[0][0]}} | {{C-lang|array[1][1]}} | {{C-lang|array[i - 1][j - 1]}} |- ! style="text-align: left" | Dereferenced pointer | {{C-lang|*(*(array + 0) + 0)}} | {{C-lang|*(*(array + 1) + 1)}} | {{C-lang|*(*(array + i - 1) + j - 1)}} |} Higher-dimensional arrays can be declared in a similar manner. A multidimensional array should not be confused with an array of pointers to arrays (also known as an [[Iliffe vector]] or sometimes an ''array of arrays''). The former is always rectangular (all subarrays must be the same size), and occupies a contiguous region of memory. The latter is a one-dimensional array of pointers, each of which may point to the first element of a subarray in a different place in memory, and the sub-arrays do not have to be the same size. The latter can be created by multiple uses of {{code|malloc}}.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)