C array of articles (one-dimensional arrays - on)

Array, I believe we have used. This article will discuss an array of progressive approach to explore some more advanced array of topics, such as multidimensional arrays, and initialize an array of pointers and arrays and so on.

A one-dimensional array

Before discussing the multi-dimensional array, the first to learn the next dimensional array. First, we learn a concept, it is considered by many to be a flaw in the design of the C language. But in fact, this concept is a very elegant way to put some completely different concepts linked together.

1. array name

Consider the following statement:

int a;

int b[10];

We called a scalar variable, because it is a single value, type of the variable is an integer. We called an array variable b, because it is a collection of values. And using the array name with the index, for identifying a specific value in the set. For example, b [0] value identifies a first array b. Each particular value is a scalar, it can be used in any context scalar data.

b [4] is of type int, but what is the type b? What it represents is? A logical answer is that it identifies the entire array, but it is not. In C, in almost all expressions using the array name, the value of the array name is a pointer constant , which is the address of the first element of the array. Its type depends on the type of array elements; if array element is int, then type the name of the array is "const pointer to int"; if other type, the type of array name is "constant pointer pointing to other types."

Please do not come to this fact arrays and pointers are the same conclusion. And a pointer array having a number of different features. For example, an array having a determined number of elements, but only a pointer scalar value. The compiler uses the array name to remember these properties. Only when the array name used in an expression, the compiler will produce a constant pointer to it.

Note that this value is a pointer constant, not a pointer variable. You can not modify the values ​​of the constants. You just study a moment, you will think this restriction is justified; constant pointer points to a starting position in the memory array, if you modify this pointer constant, the only viable operation is to move the entire array to another location memory. However, after the completion of the program link, location of the memory array is fixed, so when the program is running, think about moving the array will be too late. Thus the value is a pointer to the array name constant.

In both cases only the array name pointer not constant for the array when --- is the name used as an operand or operator sizeof unary & operator time. sizeof Returns the length of the entire array, rather than to the length of the pointer array. Taking the address of an array of names generated is a pointer to an array rather than a pointer to a pointer constant.

for example:

int a[10];

int b[10];

int *c;

...

c = &a[0];

Expression & a [0] is a pointer to the first element of the array. But that is the value of the array name itself, so the task following this assignment and one above assignment is performed exactly the same.

c = a;

This assignment statement explains why understanding the array name expression really means is very important. If the array name represents the entire array, this statement says the entire array is copied to a new array. But in fact absolutely not the case, the assignment is actually a copy of the pointer, points C is the first element of the array. Thus expressions like the following:

b = a;

Is illegal, you can not use the assignment operator to copy all of the elements of an array to another array. You have to use a loop, each copy an element.

Consider the following statement:

a = c;

c is assigned to declare a pointer variable, this statement looks like the implementation of some form of pointer, copy value of c to a, but this assignment is illegal, and the example above: Remember! In this expression, the value of a is a constant and can not be modified.

2. The reference index

In the context of the previous statement, the following expressions What does it mean?

*(b + 3)

First, the value of b is a pointer to an integer, the value of 3 is adjusted according to the length of an integer value. b + 3 is another result of a pointer pointing to an integer, it points to the first element of the array is shifted rearward position three integer length. Then, * indirect access operators access to the new position when the entire expression is the right value, it will get there the value of the entire expression is left when the value of the case, it will be a new value is stored on the premises.

This process sounds are not very familiar with? This is because it is exactly the same as the implementation process and index references. In fact, in addition to the priority, and indirect access subscripts identical references. For example, the following two expressions are exactly the same:

array[subscript]

*(array + (subscript))

3. The pointer subscript

If you can swap pointer expressions and subscript expressions, then you should use which one do? Here there is no clear answer, for most people, the subscript easier to understand, especially in a multi-dimensional array. So in terms of readability, the subscript has certain advantages. On the other hand, this choice may affect the run-time efficiency.

Assuming that these two methods are correct, the subscript will not be more efficient than the pointer, but the pointer is sometimes more efficient than the index.

To understand this efficiency problem, let's examine two cycles. They perform the same task. First, we use the subscript program all elements in the array are set to 0.

int array[10], i;

for (i = 0; i < 10; i++)

    array[i] = 0;

In order to evaluate the expression of the subscript, compiler inserts the instruction in the program, to obtain the value of i, and with it the length of an integer (i.e., 4) is multiplied. The entire multiplication takes some time and space.

Now let's look at this cycle, it performs the task in front of the cycle and the same.

int array[10], *p;

for (p = array; p < array + 10; p++)

    *p = 0;

Although the index does not exist here, but still there is multiplication.

Now this multiplication appears in the adjustment portion of the for statement. Length + 1 must be multiplied by the integer, and then added to the pointer. But there exists a significant difference: each execution of the loop, performed is the same multiplication of the two numbers (from 1 plus operation and the integer length 4). As a result, the multiplication is performed only once ---- now includes an instruction program at compile time, the pointer 4 are added. It does not perform a multiplication operation at run time.

This example illustrates the pointer ----, multiplied by the fixed digital operation done at compile time scale than more efficient in the case when you step 1 (or a fixed number) once moved in the array, so instructions required at run time less. On most machines, the program will be smaller, faster.

Now consider the following code fragment:

a = get_value();                                  a = get_value();

array[a] = 0;                                       *(array + a)  = 0;

On both sides of the code statements generated no difference. a may be any value, we know at runtime. Both require so multiply instructions, for adjusting the value of a. This example illustrates the efficiency of the pointer and subscripts same occasion.

4. Efficiency pointer

As mentioned above, the pointer is sometimes more efficient than the index, provided that they are properly use , its results may vary, depending on the compiler and machine. However, the effectiveness of the procedure depends on the code you write, and use the index as a pointer is also very easy to write poor code quality, and usually the more likely.

As it relates to the compilation, length, and other practical reasons. Do not start speaking here specifically optimized pointer wording, it only make an assessment.

In general, the evaluation is concerned, by the wording of extremely limited pointer optimization to enhance efficiency, but also makes the code becomes very easy to understand "inexplicable" code. For rare cases, such an approach worth using, but in most cases, for a little bit of operating efficiency, making the program difficult to maintain, it is very worthwhile.

You can easily argue that the experienced C programmer when using the pointer will not encounter too much trouble. But the existence of this absurd argument at the two, the first "will not encounter too much trouble" means "still be in trouble." In essence, the big risk too much complex than the simple use of the usage involved. Second, maintain your code may not be as experienced programmers, program maintenance is the major cost of a software product is located . So that makes the program more difficult to maintain job programming techniques should be used cautiously.

At the same time, some machines are designed with special instructions for performing array subscripting purpose is to make this a very common operation more quickly, in such a machine the compiler will use special instructions to implement the subscript expression, but the compiler will not necessarily achieve pointer expression with these instructions. Thus, on such a machine, the subscript may be higher than the efficiency of the pointer.

The arrays and pointers

Pointers and arrays are not equal. To illustrate this concept, consider the following two statements:

int a[5];

int *b;

a and b have the pointer value, and can be accessed indirectly references the subscript operation. However, they are still considerable differences.

When you declare an array, the compiler will be based on the number of elements in the specified array reserved memory space, and then create an array name, its value is a constant, pointing to the starting position this space. Declare a pointer variable, the compiler itself is reserved only for the pointer memory space, it does not allocate any integer value memory space. And pointer variable has not been initialized to point to any existing memory space, if it is an automatic variable, it will not even be initialized. Use this method to represent two declarations, you may find there is a significant difference between them.

Therefore, after the above statement, the expression * a perfectly legal, but the expression * b is illegal. * B to access memory in a position of uncertainty, or cause the program to terminate. On the other hand, the expression b ++ can be compiled, but a ++ is not, because the value of a is a constant.

You must clearly understand the difference between them, which is very important, because the next topic we discussed possible to muddy the waters.

Published 60 original articles · won praise 18 · views 20000 +

Guess you like

Origin blog.csdn.net/BadAyase/article/details/101353610