"C Expert Programming": re-discussion of pointers (eight)

Source: Internet
Author: User
Tags array definition

Don't forget that when you point a finger at someone else, you have another three fingers pointing at yourself ...---the motto of a paranoid spy

In the note (7) We also explained some of the knowledge and transformations of multidimensional arrays and pointers. In this section we will continue to introduce the knowledge of arrays with pointers.
Arrays of arrays and arrays of pointers

We know that multidimensional arrays, although it seems that the storage structure is a table, but in fact, the system will never allow the program to store data in this way. The storage and reference of its individual elements are arranged in memory in a linear manner. As shown:


Figure A

The array subscript rules tell us how to calculate the Lvalue Array[i][j], first find the position of array[i], and then get the character based on the offset [j]. Therefore, array[i][j] is always interpreted by the compiler as: * (* (array+i) +j).
But what we need to pay special attention to is:the step size of array[i] will change with the array definition.
We can do this by declaring a one-dimensional array of pointers, where each pointer points to a string to get a similar array of two-dimensional array characters:
Char *p[4]; Indicates that P is an array in which each element is a pointer to a char *.
Here we mainly simplify the pointer, which is actually declared to point to a single character. However, if you define a pointer to a character, there is a possibility that other characters may be stored next to it, implicitly forming a string. But a statement like this:
Char  (*p[4]) [5];//This is the real declaration of a pointer to a string array, and it restricts the length of each string to only 5;

Its structure is shown in Figure two.


Figure II

This array must be initialized with a pointer to the memory allocated for the string and can be initialized with a constant initial value at compile time, or at run time with code such as the following.
for (i=0;i<4;i++) P[i]=malloc (5);
or all-in-one allocation:
P=malloc (sizeof (char) *size_row*size_column);
This reduces the maintenance overhead of calling malloc, but the disadvantage is that it cannot be freed separately when a string is processed.
As described above: although Char *p[4] and Char p[4][5] are eventually translated by the compiler to: * (* (p+i) +j). But they are not the same actual type that they refer to in their case.

Specific differences such as the three and figure IV:


Might


Figure Four


The definition of char *p[4] above indicates that p is an array containing 4 elements, each of which is a pointer to char. The process of querying finds the first element of the array (each element is a pointer), takes out the value of the pointer, adds the offset J, and then addresses it, removing the contents of the address. The following table, similar to the pointer in note (4), refers to the might process.
second, jagged array
In such a case, if we were to store 50 strings, and each string could have a length of 256 characters, we could apply the following array:
Char p[50][256];
Unfortunately, only one string in this string has a length of 256, and the other is only about 10 bytes in length. If we do this often, the waste of memory will be very large. An alternative is to use a string pointer array, noting that all of its two-level arrays do not require the same length.
Char *p[4];

Allocating memory for these strings as needed will greatly save system resources, some people call it a "jagged" array because of the length of its right side.

Its structure is shown in Figure five:


Figure Five

The specific implementation code is as follows:

#include <iostream>using namespace Std;int main () {char *p[3];char *p1= "hello!"; Char *p2= "ABC"; char *p3= "This is my life!"; p[0]=p1;p[1]=p2;p[2]=p3;for (int i=0;i<3;i++) Cout<<p[i]<<endl;system ("pause"); return 0;}

The results of the operation are as follows:


Note: Sometimes data sharing and movement, as far as possible, try not to copy the entire string, copy a pointer than copy the entire array is much faster, but also greatly save memory space.
how are arrays and pointers modified by the compiler?

"The array name is rewritten as a pointer to the parameter" rule is not recursively defined. Arrays of arrays are rewritten as "pointers to arrays", rather than "pointers";

The specific rules are shown in six:


Figure Six

The reason why you can see char **argv in the main () function is because argv is an array of pointers (that is, Char *argv[]). This expression is rewritten by the compiler to a pointer to the first element of the array, which is a pointer to the pointer. If the argv parameter is actually declared as an array of arrays (that is, Char argv[4][5]), it will be translated by the compiler to char (*) [5] (an array pointer) instead of a pointer to char **ARGV.

The code for the specific array and pointer rewrite section is as follows:

#include <iostream>using namespace std;void my_function1 (int array[2][3][5]) {cout<< "1, It's OK" << Endl;} void My_function2 (int (*array) [3][5]) {cout<< "2, It's OK" <<ENDL;} void My_function3 (int array[][3][5]) {cout<< "3, It's OK" <<ENDL;} int main () {int arr[2][3][5];my_function1 (arr); My_function2 (arr); My_function3 (arr); int (*ARR1) [3][5]=arr;my_ Function1 (ARR1); My_function2 (arr1); My_function3 (arr1); int (*ARR2) [2][3][5]=&arr;my_function1 (*ARR2); my_ Function2 (*ARR2); My_function3 (*ARR2); System ("pause"); return 0;}
The results of the operation are as follows:


in the C language, how do you ensure that a multidimensional array is passed to the function?
1, for a one-dimensional array, the formal parameter is rewritten exponentially pointer to the first element, so a convention is required to prompt the length of the array. There are generally two methods:
(1) Adding an additional parameter, representing the number of elements, is one of our most common practices. For example, ARGC is the role.
(2) assigns a special value to the last element of the array. Tip It is the tail of the array (the end of the string ' + ' is the function). This special value must not appear in the array as a normal element value.
One-dimensional arrays are relatively simple, but complex are two-dimensional arrays. For a two-dimensional array we need at least one row in the array to end properly, so that the pointer can perform the self-increment when it reverses to the writing line, when the entire array ends. But this is more difficult, half of us give up passing the two-dimensional array a[i][j], but can also be rewritten as: a[i+x]d form, this translates into the above two kinds of solutions.
We know that a normal multidimensional array cannot be passed in the C language.
This is because we need to know the length of each dimension. Provide the correct unit of length when the address is running. In C, we have no way to communicate this data between arguments and formal parameters. So we have to provide all the length information except the leftmost meaning, otherwise it will go wrong.
For example, call the function as follows:
void My_function2 (int array[][3][5]) {}
We can call it in the following ways:
int arr[100][3][5];   My_function (arr); Okint arr[10][3][5];    My_function (arr);  Ok
But not like the following:
int arr[100][33][24]; My_function (arr); Errorint arr[10][4][6];    My_function (arr);    ERROR
This will not pass through the compiler.
So how to pass a multidimensional array?
method One: define void My_function3 (int array[3][5])
This is the simplest, but the least useful, because it can handle only 3 rows and 4 columns of array data. In fact, the leftmost one-dimensional length of a multidimensional array can be omitted, since the function knows the information of the other dimension, it can skip a complete line at a time and reach the next line.

Method two: void My_function3 (int array[][5]).

This is the data omitted from the leftmost first dimension mentioned in method one. This means that each line must be exactly the length of 5 integers. Functions can also be similar to declarations:

void My_function3 (int array (*P) [5])
the parentheses are necessary to ensure that it is a pointer to an array of 5 int types instead of a 5 int * Type element.
According to the original design, Pascal also has the same functional flaws as the C language-there is no way to pass an array of different lengths like the same function. In fact, Pascal's situation is even worse because he can't even support the case of a one-dimensional array. And the C language is possible. Because the array bounds are part of the function prototype. But Pascal if the parameters are not the same length as the arguments, a mismatch error occurs. For example, the following code:
var arr:array[1..10] of integer;precedure function (a:array[1..15] of integer;function (arr);//cannot be compiled, but can be in C language.

Method Three: Discard passing the two-dimensional array. This means creating a one-dimensional array in which the elements in the array are pointers to other things.

Recall that in the main function described earlier, we are accustomed to the form of Char *argv[] parameters, and sometimes we can see the form of Char **argv. So we can simply pass a pointer to the first element of the array parameter, as follows:

void My_function3 (int **array);
Note: You can do this only if you change the two-dimensional array to a pointer array that points to a vector.
method Four: Adopt the Circuitous method: Char array[i*columns+j];

Because the storage of the array is continuous linear, we can dimension the multidimensional array. Because C is an array of arrays, we can reduce a multidimensional array to a one-dimensional array, which makes it more convenient for us to deal with them! In line with our habits!

After all, the passing of an array in a function is always translated into pointers by the compiler, so that we can take advantage of this feature and sometimes simplify the operation of multidimensional arrays (not all of them).

"C Expert Programming": re-discussion of pointers (eight)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.