Array declaration and simulation of two dimensional arrays in C

  • 2020-05-07 20:05:53
  • OfStack

The connection between Pointers and arrays in a language is so inextricable that if you can't understand one concept, you can't fully understand the other.

Two things to note about arrays in C are:

There are only 1-dimensional arrays in C, and the size of the array must be determined as a constant at compile time. However, the elements of an array in the C language can be any type of object, or of course, another array. In this way, it is not difficult to "simulate" a multidimensional array.
For an array, we can only do two things: determine the size of the array and get a pointer to the element subscript 0 of the array. Other operations on arrays, even if they appear to be subscripts of arrays, are actually performed by Pointers. In other words, any 1 array index operation is the same as the corresponding 1 pointer operation, so we can completely define the behavior of array index based on the pointer behavior.
Once we understand both of these points and what they imply, understanding array operations in C is a piece of paper. If you don't know these two things, C array operations can cause a lot of confusion for programmers. In particular, the programmer should be able to combine the array operations with their corresponding pointer operations, and the brain can switch between the two operations when thinking about the problem. There is no delay.

Index operations are built into any programming language, and in C they are defined in the form of pointer arithmetic.

How do declare an array

To understand how arrays work in C, we must first understand how to declare an array, for example:


int a[3];

This statement states that a is an array with three integer elements, and similarly,


struct{
 int p[4];
 double x;
}b[17];

It is declared that b is an array of 17 elements, each of which is a structure that contains an array of 4 orthopedic elements (named p) and a variable of double precision type (named x).

Now consider the following example:


int calendar[12][31];

This statement declares the calendar is an array, the array has 12 types of an array element, each of these elements are 31 integer array of elements (rather than one owns 31 array type of element array, each element is one with 12 integer array element array) so sizeof (calendar) value is 372 (31 * 12) with sizeof (int) product.

If calendar is not used for the operand of sizeof, but for other situations, calendar is always replaced with a pointer to the starting element of the calendar array. To understand what this means, we must first understand some details about Pointers.

2-dimensional array simulation
*a is a reference to an element in the array a with a subscript of 0. For example, we could write:


*a=84;

This statement sets the value of an element in the array a with an index of 0 to 84. Similarly, *(a+1) is a reference to an element in the array a with an index of 1, and so on. In summary, *(a+i) is a reference to an element in the array with an index of i.

It is this concept that makes C difficult for the novice to understand. In fact, since a+i + i+a has the same meaning as i+a, a[i] and i[a] have the same meaning. The latter may be familiar to some assembly language programmers, but we definitely don't recommend it.

Now we can consider the 2 d array, as discussed earlier, it is actually an array of elements of the array, although we can completely according to the pointer to write programs to manipulate 1 d array, it is not difficult to do so in 1 d case, but for a 2 d array from the notation for the convenience of using the following form is almost can not be replaced. Also, if we only used Pointers to manipulate 2-dimensional arrays, we would have to deal with the most "opaque" parts of the C language, and we would often encounter the latent compiler bug.

Let's go back to a few more statements:


int calendar[12][31];
int *p
int i;

Then test yourself. What does calendar[4] mean?

Because of the 12 calendar is one type of the array of arrays, which type of each array element is one with 31 integer array, so calendar [4] is the fifth element calendar array, is calendar 12 has 31 integer element in an array of arrays of 1, thus calendar [4] behavior also show one with 31 plastic elements of an array of behavior, such as sizeof (calendar [4]) is the result of the 31 and sizeof (int) product.


p=calendar[4];

This statement causes the pointer p to point to an element in the array calendar[4] whose subscript is 0. If calendar[4] is an array, we can of course specify the elements in the array by subscript, as follows:


i = calendar[4][7];

And we can do that. Again, as before, this statement can be written as follows while the meaning of the expression remains the same:


i = *(calendar[4]+7);

This statement can also be further written as:


i = *(*(calendar+4)+7);

It is easy to see from here that the subscript form of square brackets is obviously much easier to express than the pointer form. Here we go:


p = calendar;

This statement is illegal, because calendar is a 2 d array, the array of arrays, where the context of use calendar name will be transformed into a pointer to an array, and p is a pointer to the variable, this statement attempts to one type of pointer assignment 1 type of a pointer to another, so it is illegal.

Obviously, we need a way to declare a pointer to an array. After much discussion of similar issues, it should not take much effort to construct the following statement:


struct{
 int p[4];
 double x;
}b[17];
0

The effect of this statement is that *ap is an array of 3101 integer elements and ap is a pointer to such an array.


struct{
 int p[4];
 double x;
}b[17];
1

Thus, monthp points to the first element of the array calendar, which is 1 of the 12 elements of the array type calendar with 31 elements.

Suppose that at the beginning of the New Year, we need to empty the calendar array, which can be easily done in subscript form:


struct{
 int p[4];
 double x;
}b[17];
2

How should the above code segment be represented as a pointer? We can easily put calendar[month][day]=0; Said to * (* (calendar + month) + day) = 0.

But what are the really relevant parts?

If the pointer monthp points to an array with 31 integer elements, and the element calendar is also an array with 31 integer elements, so just as in other cases we can use 1 pointer to iterate over 1 array 1, here we can also use the pointer monthp to step through the array calendar:


int (*monthp)[31];
for(monthp=calendar;monthp < &calendar[12];monthp++){
 int *dayp;
 for(dayp=*monthp;dayp < &(*monthp)[31];dayp++)
 *dayp=0;
}

 


Related articles: