6. Arrays and Pointers

comp.lang.c FAQ list · Question 6.1

Q: I had the definition char a[6] in one source file, and in another I declared extern char *a. Why didn't it work?

A: In one source file you defined an array of characters and in the other you declared a pointer to characters. The declaration extern char *a does not declare an array and therefore does not match the actual definition. The type pointer-to-type-T is not the same as array-of-type-T. Use extern char a[].

References: ISO Sec.
CT&P Sec. 3.3 pp. 33-4, Sec. 4.5 pp. 64-5

comp.lang.c FAQ list · Question 6.2

Q: But I heard that char a[] was identical to char *a.

A: Not at all. (What you heard has to do with formal parameters to functions; see question 6.4.) Arrays are not pointers, though they are closely related (see question 6.3) and can be used similarly (see questions 4.1, 6.8, 6.10, and 6.14).

The array declaration char a[6] requests that space for six characters be set aside, to be known by the name ``a''. That is, there is a location named ``a'' at which six characters can sit. The pointer declaration char *p, on the other hand, requests a place which holds a pointer, to be known by the name ``p''. This pointer can point almost anywhere: to any char, or to any contiguous array of chars, or nowhere [footnote] (see also questions 5.1 and 1.30).

As usual, a picture is worth a thousand words. The declarations

	char a[] = "hello";
	char *p = "world";
would initialize data structures which could be represented like this:

It is useful to realize that a reference like x[3] generates different code depending on whether x is an array or a pointer. Given the declarations above, when the compiler sees the expression a[3], it emits code to start at the location ``a'', move three past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the location ``p'', fetch the pointer value there, add three to the pointer, and finally fetch the character pointed to. In other words, a[3] is three places past (the start of) the object named a, while p[3] is three places past the object pointed to by p. In the example above, both a[3] and p[3] happen to be the character 'l', but the compiler gets there differently. (The essential difference is that the values of an array like a and a pointer like p are computed differently whenever they appear in expressions, whether or not they are being subscripted, as explained further in question 6.3.) See also question 1.32.

References: K&R2 Sec. 5.5 p. 104
CT&P Sec. 4.5 pp. 64-5

comp.lang.c FAQ list · Question 6.3

Q: So what is meant by the ``equivalence of pointers and arrays'' in C?

A: Much of the confusion surrounding arrays and pointers in C can be traced to a misunderstanding of this statement. Saying that arrays and pointers are ``equivalent'' means neither that they are identical nor even interchangeable. What it means is that array and pointer arithmetic is defined such that a pointer can be conveniently used to access an array or to simulate an array. In other words, as Wayne Throop has put it, it's ``pointer arithmetic and array indexing [that] are equivalent in C, pointers and arrays are different.'')

Specifically, the cornerstone of the equivalence is this key definition:

A reference to an object of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T.

That is, whenever an array appears in an expression, the compiler implicitly generates a pointer to the array's first element, just as if the programmer had written &a[0]. (The exceptions are when the array is the operand of a sizeof or & operator, or is a string literal initializer for a character array. [footnote] See questions 6.23, 6.12, and 1.32, respectively.)

As a consequence of this definition, and in spite of the fact that the underlying arrays and pointers are quite different, the compiler doesn't apply the array subscripting operator [] that differently to arrays and pointers, after all.[footnote] Given an array a and pointer p, an expression of the form a[i] causes the array to decay into a pointer, following the rule above, and then to be subscripted just as would be a pointer variable in the expression p[i] (although the eventual memory accesses will be different, as explained in question 6.2). If you were to assign the array's address to the pointer:

	p = a;
then p[3] and a[3] would access the same element.

This harmony of access explains how pointers can access arrays, serve in their stead as function parameters (see question 6.4), and simulate dynamic arrays (see question 6.14).

See also questions 6.8, 6.10, and 6.14.

References: K&R1 Sec. 5.3 pp. 93-6
K&R2 Sec. 5.3 p. 99
ISO Sec., Sec., Sec. 6.3.6
H&S Sec. 5.4.1 p. 124

comp.lang.c FAQ list · Question 6.4

Q: If they're so different, then why are array and pointer declarations interchangeable as function formal parameters?

A: It's supposed to be a convenience.

Since arrays decay immediately into pointers, an array is never actually passed to a function. You can pretend that a function receives an array as a parameter, and illustrate it by declaring the corresponding parameter as an array:

	void f(char a[])
	{ ... }
Interpreted literally, this declaration would have no use, so the compiler turns around and pretends that you'd written a pointer declaration, since that's what the function will in fact receive:
	void f(char *a)
	{ ... }
There's nothing particularly wrong with talking about a function as if it ``receives'' an array, if the function is traditionally used to operate on arrays, or if the parameter is naturally treated within the function as an array.

This conversion of array-like declarators into pointers holds only within function formal parameter declarations, nowhere else. If the conversion bothers you, you're under no compulsion to make use of it; many programmers have concluded that the confusion it causes outweighs the small advantage of having the declaration ``look like'' the call or the uses within the function. (Note that the conversion happens only once; something like char a2[][] won't work. See questions 6.18 and 6.19.)

See also question 6.21.

References: K&R1 Sec. 5.3 p. 95, Sec. A10.1 p. 205
K&R2 Sec. 5.3 p. 100, Sec. A8.6.3 p. 218, Sec. A10.1 p. 226
ISO Sec., Sec. 6.7.1, Sec. 6.9.6
H&S Sec. 9.3 p. 271
CT&P Sec. 3.3 pp. 33-4
Dennis Ritchie, ``The Development of the C Language''

comp.lang.c FAQ list · Question 6.4b

Q: So arrays are passed by reference, even though the rest of C uses pass by value?

A: That's one way of thinking about it. See question 4.11.

comp.lang.c FAQ list · Question 6.5

Q: Why can't I do something like this?

	extern char *getpass();
	char str[10];
	str = getpass("Enter password: ");

A: Arrays are ``second-class citizens'' in C; one upshot of this prejudice is that you cannot assign to them (see also question 6.7). When you need to copy the contents of one array to another, you must do so explicitly. In the case of char arrays, the strcpy routine is usually appropriate:

	strcpy(str, getpass("Enter password: "));

(When you want to pass arrays around without copying them, you can use pointers and simple assignment. See also question 4.1.)

See also question 8.2.

References: ISO Sec.
H&S Sec. 7.9.1 pp. 221-2

comp.lang.c FAQ list · Question 6.6

Q: If you can't assign to arrays, then how can

	int f(char str[])
		if(str[0] == '\0')
			str = "none";

A: In this code, str is a function parameter, so its declaration is rewritten by the compiler as described in question 6.4. In other words, str is a pointer (of type char *), and it is legal to assign to it.

comp.lang.c FAQ list · Question 6.6b

Q: And what about this? Isn't this an array assignment?

	char a[] = "Hello, world!\n";

A: No, that's an initialization. You are allowed to initialize arrays when you define them.

comp.lang.c FAQ list · Question 6.7

Q: How can an array be an lvalue, if you can't assign to it?

A: The term ``lvalue'' doesn't quite mean ``something you can assign to''; a better definition is ``something that has a location (in memory).'' [footnote] The ANSI/ISO C Standard goes on to define a ``modifiable lvalue''; an array is not a modifiable lvalue. See also question 6.5.

References: ISO Sec.
Rationale Sec.
H&S Sec. 7.1 p. 179

comp.lang.c FAQ list · Question 6.8

Q: Practically speaking, what is the difference between arrays and pointers?

A: An array is a single, preallocated chunk of contiguous elements (all of the same type), fixed in size and location. A pointer is a reference to any data element (of a particular type) anywhere. A pointer must be assigned to point to space allocated elsewhere, but it can be reassigned (and the space, if derived from malloc, can be resized) at any time. A pointer can point to an array, and can simulate (along with malloc) a dynamically allocated array, but a pointer is a much more general data structure (see also question 4.1).

Due to the so-called equivalence of arrays and pointers (see question 6.3), arrays and pointers often seem interchangeable, and in particular a pointer to a block of memory assigned by malloc is frequently treated (and can be referenced using []) exactly as if it were a true array. See questions 6.14 and 6.16. (Be careful with sizeof; see question 7.28.)

See also questions 1.32, 6.10, and 20.14.

comp.lang.c FAQ list · Question 6.9

Q: Someone explained to me that arrays were really just constant pointers.

A: This is a bit of an oversimplification. An array name is ``constant'' in that it cannot be assigned to, but an array is not a pointer, as the discussion and pictures in question 6.2 should make clear. See also questions 6.3, 6.8, and 6.10.

comp.lang.c FAQ list · Question 6.10

Q: I'm still mystified. Is a pointer a kind of array, or is an array a kind of pointer?

A: An array is not a pointer, nor vice versa. An array reference (that is, any mention of an array in a value context), turns into a pointer (see questions 6.2 and 6.3).

There are perhaps three ways to think about the situation:

  1. Pointers can simulate arrays (though that's not all; see question 4.1).
  2. There's hardly such a thing as an array (it is, after all, a ``second-class citizen''); the subscripting operator [] is in fact a pointer operator.
  3. At a higher level of abstraction, a pointer to a block of memory is effectively the same as an array (though this says nothing about other uses of pointers).

But, to reiterate, here are two ways not to think about it:

  1. 4. ``They're completely the same.'' (False; see question 6.2.)
  2. 5. ``Arrays are constant pointers.'' (False; see question 6.9.)

See also question 6.8.

comp.lang.c FAQ list · Question 6.11

Q: I came across some ``joke'' code containing the ``expression'' 5["abcdef"] . How can this be legal C?

A: Yes, Virginia, array subscripting is commutative in C. [footnote] This curious fact follows from the pointer definition of array subscripting, namely that a[e] is identical to *((a)+(e)), for any two expressions a and e, as long as one of them is a pointer expression and one is integral. The ``proof'' looks like

	*((a) + (e))	(by definition)
	*((e) + (a))	(by commutativity of addition)
	e[a]		(by definition)

This unsuspected commutativity is often mentioned in C texts as if it were something to be proud of, but it finds no useful application outside of the Obfuscated C Contest (see question 20.36).

Since strings in C are arrays of char, the expression "abcdef"[5] is perfectly legal, and evaluates to the character 'f'. You can think of it as a shorthand for

	char *tmpptr = "abcdef";

	... tmpptr[5] ...
See question 20.10 for a realistic example.

References: Rationale Sec.
H&S Sec. 5.4.1 p. 124, Sec. 7.4.1 pp. 186-7

comp.lang.c FAQ list · Question 6.12

Q: Since array references decay into pointers, if arr is an array, what's the difference between arr and &arr?

A: The type.

In Standard C, &arr yields a pointer, of type pointer-to-array-of-T, to the entire array. (In pre-ANSI C, the & in &arr generally elicited a warning, and was generally ignored.) Under all C compilers, a simple reference (without an explicit &) to an array yields a pointer, of type pointer-to-T, to the array's first element.

For a simple array

	int a[10];
a reference to a has type ``pointer to int,'' and &a is ``pointer to array of 10 ints.'' For a two-dimensional array like
	int array[NROWS][NCOLUMNS];
a reference to array has type ``pointer to array of NCOLUMNS ints,'' while &array has type ``pointer to array of NROWS arrays of NCOLUMNS ints.''

See also questions 6.3, 6.13, and 6.18.

References: ISO Sec., Sec.
Rationale Sec.
H&S Sec. 7.5.6 p. 198

comp.lang.c FAQ list · Question 6.13

Q: How do I declare a pointer to an array?

A: Usually, you don't want to. When people speak casually of a pointer to an array, they usually mean a pointer to its first element.

Instead of a pointer to an array, consider using a pointer to one of the array's elements. Arrays of type T decay into pointers to type T (see question 6.3), which is convenient; subscripting or incrementing the resultant pointer will access the individual members of the array. True pointers to arrays, when subscripted or incremented, step over entire arrays (see below), and are generally useful only when operating on arrays of arrays, [footnote] if at all. (See also question 6.18.)

If you really need to declare a pointer to an entire array, use something like ``int (*ap)[N];'' where N is the size of the array. (See also question 1.21.) If the size of the array is unknown, N can in principle be omitted, but the resulting type, ``pointer to array of unknown size,'' is useless.

Here is an example showing the difference between simple pointers and pointers to arrays. Given the declarations

int a1[3] = {0, 1, 2};
int a2[2][3] = {{3, 4, 5}, {6, 7, 8}};
int *ip;		/* pointer to int */
int (*ap)[3];		/* pointer to array [3] of int */
you could use the simple pointer-to-int, ip, to access the one-dimensional array a1:
	ip = a1;
	printf("%d ", *ip);
	printf("%d\n", *ip);
This fragment would print
	0 1
An attempt to use a pointer-to-array, ap, on a1:
	ap = &a1;
	printf("%d\n", **ap);
	ap++;				/* WRONG */
	printf("%d\n", **ap);		/* undefined */
would print 0 on the first line and something undefined on the second (and might crash). The pointer-to-array would only be at all useful in accessing an array of arrays, such as a2:
	ap = a2;
	printf("%d %d\n", (*ap)[0], (*ap)[1]);
	ap++;		/* steps over entire (sub)array */
	printf("%d %d\n", (*ap)[0], (*ap)[1]);
This last fragment would print
	3 4
	6 7

See also question 6.12.

Additional links: further reading

References: ISO Sec.

comp.lang.c FAQ list · Question 6.14

Q: How can I set an array's size at run time?
How can I avoid fixed-sized arrays?

A: The equivalence between arrays and pointers (see question 6.3) allows a pointer to malloc'ed memory to simulate an array quite effectively. After executing

	#include <stdlib.h>
	int *dynarray;
	dynarray = malloc(10 * sizeof(int));
(and if the call to malloc succeeds), you can reference dynarray[i] (for i from 0 to 9) almost as if dynarray were a conventional, statically-allocated array (int a[10]). The only difference is that sizeof will not give the size of the ``array'' (see question 7.28. See also questions 1.31b, 6.16, 7.7, and 7.29.

comp.lang.c FAQ list · Question 6.15

Q: How can I declare local arrays of a size matching a passed-in array?

A: Until recently, you couldn't; array dimensions in C traditionally had to be compile-time constants. However, C99 introduces variable-length arrays (VLA's) which solve this problem; local arrays may have sizes set by variables or other expressions, perhaps involving function parameters. (gcc has provided parameterized arrays as an extension for some time.) If you can't use C99 or gcc, you'll have to use malloc, and remember to call free before the function returns. See also questions 6.14, 6.16, 6.19, 7.22, and maybe 7.32.

References: ISO Sec. 6.4, Sec.
C9X Sec.

comp.lang.c FAQ list · Question 6.16

Q: How can I dynamically allocate a multidimensional array?

A: The traditional solution is to allocate an array [footnote] of pointers to pointers, and then initialize each pointer to a dynamically-allocated ``row.'' Here is a two-dimensional example:

	#include <stdlib.h>

	int **array1 = malloc(nrows * sizeof(int *));
	for(i = 0; i < nrows; i++)
		array1[i] = malloc(ncolumns * sizeof(int));
(In real code, of course, all of malloc's return values would be checked. You can also use sizeof(*array1) and sizeof(**array1) instead of sizeof(int *) and sizeof(int); see [footnote] .)

You can keep the array's contents contiguous, at the cost of making later reallocation of individual rows more difficult, with a bit of explicit pointer arithmetic:

	int **array2 = malloc(nrows * sizeof(int *));
	array2[0] = malloc(nrows * ncolumns * sizeof(int));
	for(i = 1; i < nrows; i++)
		array2[i] = array2[0] + i * ncolumns;
In either case (i.e for array1 or array2), the elements of the dynamic array can be accessed with normal-looking array subscripts: arrayx[i][j] (for 0 <= i < nrows and 0 <= j < ncolumns). Here is a schematic illustration of the layout of array1 and array2:

If the double indirection implied by the above schemes is for some reason unacceptable,[footnote] you can simulate a two-dimensional array with a single, dynamically-allocated one-dimensional array:

	int *array3 = malloc(nrows * ncolumns * sizeof(int));
However, you must now perform subscript calculations manually, accessing the i,jth element with the expression
array3[i * ncolumns + j]
and this array cannot necessarily be passed to functions which expect multidimensional arrays. (A macro such as
	#define Arrayaccess(a, i, j) ((a)[(i) * ncolumns + (j)])
could hide the explicit calculation, but invoking it would require parentheses and commas which wouldn't look exactly like conventional C multidimensional array syntax, and the macro would need access to at least one of the dimensions, as well. See also question 6.19.)

Yet another option is to use pointers to arrays:

	int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));
or even
	int (*array5)[NROWS][NCOLUMNS] = malloc(sizeof(*array5));
but the syntax starts getting horrific (accesses to array5 look like (*array5)[i][j]), and at most one dimension may be specified at run time.

With all of these techniques, you may of course need to remember to free the arrays when they are no longer needed; in the case of array1 and array2 this takes several steps (see also question 7.23):

	for(i = 0; i < nrows; i++)
		free((void *)array1[i]);
	free((void *)array1);

	free((void *)array2[0]);
	free((void *)array2);
Also, you cannot necessarily intermix dynamically-allocated arrays with conventional, statically-allocated ones (see question 6.20, and also question 6.18).

Finally, in C99 you can use a variable-length array.

All of these techniques can also be extended to three or more dimensions. Here is a three-dimensional version of the first technique (which, like the rest of the fragments presented here, requires error-checking before being used in a real program):

	int ***a3d = (int ***)malloc(xdim * sizeof(int **));
	for(i = 0; i < xdim; i++) {
		a3d[i] = (int **)malloc(ydim * sizeof(int *));
		for(j = 0; j < ydim; j++)
			a3d[i][j] = (int *)malloc(zdim * sizeof(int));

See also question 20.2.

References: C9X Sec.

comp.lang.c FAQ list · Question 6.17

Q: Here's a neat trick: if I write

	int realarray[10];
	int *array = &realarray[-1];
I can treat array as if it were a 1-based array.

A: Although this technique is attractive (and was used in old editions of the book Numerical Recipes in C), it is not strictly conforming to the C Standard. Pointer arithmetic is defined only as long as the pointer points within the same allocated block of memory, or to the imaginary ``terminating'' element one past it; otherwise, the behavior is undefined, even if the pointer is not dereferenced. The code above computes a pointer to memory before the beginning of realarray and could fail if, while subtracting the offset, an illegal address were generated (perhaps because the address tried to ``wrap around'' past the beginning of some memory segment).

Additional links: “Yes, Virginia”

References: K&R2 Sec. 5.3 p. 100, Sec. 5.4 pp. 102-3, Sec. A7.7 pp. 205-6
ISO Sec. 6.3.6
Rationale Sec.

comp.lang.c FAQ list · Question 6.18

Q: My compiler complained when I passed a two-dimensional array to a function expecting a pointer to a pointer.

A: The rule (see question 6.3) by which arrays decay into pointers is not applied recursively. (Once the rule has been applied once, the result is a pointer to which the rule no longer applies.) An array of arrays (i.e. a two-dimensional array in C) decays into a pointer to an array, not a pointer to a pointer. Pointers to arrays can be confusing, and must be treated carefully; see also question 6.13.

If you are passing a two-dimensional array to a function:

	int array[NROWS][NCOLUMNS];
the function's declaration must match:
	void f(int a[][NCOLUMNS])
	{ ... }
	void f(int (*ap)[NCOLUMNS])	/* ap is a pointer to an array */
	{ ... }
In the first declaration, the compiler performs the usual implicit parameter rewriting of ``array of array'' to ``pointer to array'' (see questions 6.3 and 6.4); in the second form the pointer declaration is explicit. Since the called function does not allocate space for the array, it does not need to know the overall size, so the number of rows, NROWS, can be omitted. The width of the array is still important, so the column dimension NCOLUMNS (and, for three- or more dimensional arrays, the intervening ones) must be retained.

If a function is already declared as accepting a pointer to a pointer, it is almost certainly meaningless to pass a two-dimensional array directly to it. An intermediate pointer would have to be used when attempting to call it with a two-dimensional array:

	extern g(int **ipp);

	int *ip = &array[0][0];
	g(&ip);		/* PROBABLY WRONG */
but this usage is misleading and almost certainly incorrect, since the array has been ``flattened'' (its shape has been lost).

See also questions 6.12 and 6.15.

References: K&R1 Sec. 5.10 p. 110
K&R2 Sec. 5.9 p. 113
H&S Sec. 5.4.3 p. 126

comp.lang.c FAQ list · Question 6.19

Q: How do I write functions which accept two-dimensional arrays when the width is not known at compile time?

A: It's not always easy. One way is to pass in a pointer to the [0][0] element, along with the two dimensions, and simulate array subscripting ``by hand'':

	void f2(int *aryp, int nrows, int ncolumns)
	{ ... array[i][j] is accessed as aryp[i * ncolumns + j] ... }
Note that the correct expression for manual subscripting involves ncolumns (the ``width'' of each row), not nrows (the number of rows); it's easy to get this backwards.

This function could be called with the array from question 6.18 as

	f2(&array[0][0], NROWS, NCOLUMNS);

It must be noted, however, that a program which performs multidimensional array subscripting ``by hand'' in this way is not in strict conformance with the ANSI C Standard; according to an official interpretation, the behavior of accessing (&array[0][0])[x] is not defined for x >= NCOLUMNS.

C99 allows variable-length arrays, and once compilers which accept C99's extensions become widespread, VLA's will probably become the preferred solution. (gcc has supported variable-sized arrays for some time.)

When you want to be able to use a function on multidimensional arrays of various sizes, one solution is to simulate all the arrays dynamically, as in question 6.16.

See also questions 6.18, 6.20, and 6.15.

References: ISO Sec. 6.3.6
C9X Sec.

comp.lang.c FAQ list · Question 6.20

Q: How can I use statically- and dynamically-allocated multidimensional arrays interchangeably when passing them to functions?

A: There is no single perfect method. Given the declarations

	int array[NROWS][NCOLUMNS];
	int **array1;			/* ragged */
	int **array2;			/* contiguous */
	int *array3;			/* "flattened" */
	int (*array4)[NCOLUMNS];

int (*array5)[NROWS][NCOLUMNS];
with the pointers initialized as in the code fragments in question 6.16, and functions declared as
	void f1a(int a[][NCOLUMNS], int nrows, int ncolumns);
	void f1b(int (*a)[NCOLUMNS], int nrows, int ncolumns);
	void f2(int *aryp, int nrows, int ncolumns);
	void f3(int **pp, int nrows, int ncolumns);
where f1a and f1b accept conventional two-dimensional arrays, f2 accepts a ``flattened'' two-dimensional array, and f3 accepts a pointer-to-pointer, simulated array (see also questions 6.18 and 6.19), the following calls should work as expected:
	f1a(array, NROWS, NCOLUMNS);
	f1b(array, NROWS, NCOLUMNS);
	f1a(array4, nrows, NCOLUMNS);
	f1b(array4, nrows, NCOLUMNS);

f1(*array5, NROWS, NCOLUMNS);
f2(&array[0][0], NROWS, NCOLUMNS); f2(*array, NROWS, NCOLUMNS); f2(*array2, nrows, ncolumns); f2(array3, nrows, ncolumns); f2(*array4, nrows, NCOLUMNS);
f2(**array5, NROWS, NCOLUMNS);
f3(array1, nrows, ncolumns); f3(array2, nrows, ncolumns);
The following calls would probably work on most systems, but involve questionable casts, and work only if the dynamic ncolumns matches the static NCOLUMNS:
	f1a((int (*)[NCOLUMNS])(*array2), nrows, ncolumns);
	f1a((int (*)[NCOLUMNS])(*array2), nrows, ncolumns);
	f1b((int (*)[NCOLUMNS])array3, nrows, ncolumns);
	f1b((int (*)[NCOLUMNS])array3, nrows, ncolumns);

It will be noticed that only f2 can conveniently be made to work with both statically- and dynamically-allocated arrays, though it will not work with the traditional ``ragged'' array implementation, array1. However, it must also be noted that passing &array[0][0] (or, equivalently, *array) to f2 is not strictly conforming; see question 6.19.

If you can understand why all of the above calls work and are written as they are, and if you understand why the combinations that are not listed would not work, then you have a very good understanding of arrays and pointers in C.

Rather than worrying about all of this, one approach to using multidimensional arrays of various sizes is to make them all dynamic, as in question 6.16. If there are no static multidimensional arrays--if all arrays are allocated like array1 or array2 in question 6.16--then all functions can be written like f3.

Additional links: Sample source code (``torture test'') illustrating all these techniques

comp.lang.c FAQ list · Question 6.21

Q: Why doesn't sizeof properly report the size of an array when the array is a parameter to a function? I have a test routine

	f(char a[10])
		int i = sizeof(a);
		printf("%d\n", i);
and it prints 4, not 10.

A: The compiler pretends that the array parameter was declared as a pointer (that is, in the example, as char *a; see question 6.4), and sizeof reports the size of the pointer. See also questions 1.24 and 7.28.

References: H&S Sec. 7.5.2 p. 195

comp.lang.c FAQ list · Question 6.22

Q: How can code in a file where an array is declared as extern (i.e. it is defined, and its size determined, in some other file) determine the size of the array? sizeof doesn't seem to work.

A: See question 1.24.

comp.lang.c FAQ list · Question 6.23

Q: I want to know how many elements are in an array, but sizeof yields the size in bytes.

A: Simply divide the size of the entire array by the size of one element:

	int array[] = {1, 2, 3};
	int narray = sizeof(array) / sizeof(array[0]);

References: ISO Sec.

comp.lang.c FAQ list · Question 6.24

Q: Is there a way to have an array of bits?

A: No. But see question 20.8.

Read sequentially: prev next up

about this FAQ list   about eskimo   search   feedback   copyright

Hosted by Eskimo North