Preliminary study on pointer and array relationship

xiaoxiao2021-04-01  204

Author: Zhu Jincan

Source: http://blog.9cbs.net/clever101

The pointer is the essence of the C language. Lin Rui, the author of "High Quality C Programming Guide", said: Will not use a pointer correctly, definitely be a qualified programmer. I thought about it last night and I realized the correct way to understand the pointer. This article tries to study the pointer by exploring the relationship between the pointers and arrays.

There will be this in general C language textbook: The pointer is the address, the number of group names is the first address of the pointer. These can't be said to be wrong, but they didn't go in-depth, and students have difficulty understanding.

I think it is essentially, the array is a separate memory block, the pointer is a single memory unit. This principle maybe no one know. Understand pointers and arrays, I think it is necessary to understand the principle of operation of the compiler. For example, as a few lines of code below, do you know what work does the compiler do?

Float x = 123.456; Double P = 3.1415926; Printf ("% 7.2F / n", x); Printf ("% 7.2LF / N", P); Printf ("% - 7.2f / n", x); Printf ("% - 7.2LF / N", P);

The above line of code, compiled in the VC often appears: Warning C4305: 'Initializing': truncation from 'const double' to 'float'. Big intending is to illegally truncate Double data to FLOAT. This warning is for the first line. Maybe you will say: 123.456 is not a floating point? Where is the reason? This is a simple line of programs, for the editor, to do two steps: First, the open variable, the second is Bin value. However, the compiler has made a step before these two steps: open constant. Note: You will say that this program doesn't have const. However, the program is processed: Before the open variable, first scan your program over again, all the values ​​you entered, the characters are all considered to be stored. So, such a simple sentence is not only a variable, not just a constant before this. Its type is Double, the value is 2.34. What you have to do is remind the translator "This is a float type", you change this line to: float x =

2.34F

. Now you can't see this program and the relationship between the topic we have to talk, but you will see it.

This article tries to explain the problem by some examples. First of all, I want to ask the reader to think about the following questions:

An example is the famous string replication program:

#include #include void struct (char * strdin, char * strsrc) {while (* strsrc! = '/ 0') {strDin = strsrc ;}} void main () {char p [15] = "Hello World"; char q [20]; strcpy (q, p); Printf ("% s", Q);}

This program will have an error. Error behavior strDin = strsrc ; the compiler will prompt: = The left should be a left value. You will ask: Why do you have this error? I will not announce the answer temporarily, we continue to look at the example.

This is an example in "High Quality C Programming Guide": char a [] = "Hello"; A [0] = 'x'; cout << a << end1; char * p = "world"; p [ 0] = 'x'; cout << p << endl;

Note that this program is compiled and there is no error, but the memory cannot be written when running. why?

Example 3:

#include int main (void) {char a [20]; a = "hello"; cout << a << endl; return 1;}

This program will have an error: '=': Cannot Convert from 'char [6]' to 'char [20]'. Big intending is = CHAR [6] cannot be converted to CHAR [20]. You may ask: why?

Now I start to publish my thinking results. I think the nature of the problem is a constant and variable problem, or is a permission issue. Why strDin = strsrc ; this does not implement character replication. In fact, we will understand this line of code.

STRSRC ;

STRDIN ;

STRDIN = strsrc;

First we clarify that strDin and strsrc are a character pointer variable, which has the right to change its own value. For example, if you can assign any value for StrDin and STRSRC.

The problem is that you have the right to change yourself, but there is no right to change others. Assuming that the value corresponding to the strDin is 1000, the value corresponding to STRDIN is 2000.

STRSRC ; // At this time, STRSRC becomes 1002

STRDIN ; // At this time, STRDIN becomes 2002

STRDIN = strsrc; // strdin == 2002.

Why do you want this way? This is ok. But you don't forget, strDin is a character pointer, that is, strDin is a memory address. When strDin == 2002, do you think you have the right to change the value of this memory cell 2002? Obviously this is unable to copy strings.

In Example 2 you will see Char A [] to "Xhello". But string P does not change. You may be ignorant for P: Why can the characters of array A can change, and pointer P can't change? At this time, because "world" is a constant string. Char * p = "world"; this compiler first is to find a memory block to save "world" constant string, and then assign the first address to P. Because this is a constant string, that is, its characters cannot be changed. You can read this string, but you can't change any content of this memory block. Then why can the array A can change? Because the array A opens up a memory block, it can be read and writable for this memory block. At this point you may say: The array can be converted to the pointer, but the pointer does not necessarily convert into an array. This kind of saying is a certain reason.

In Example 3, why can't you assign a value to the character array A? The truth is the same. A = "Hello"; just assigns the first address of the constant string to a, but the first address of the array A is a constant, and the compiler has opened up a space when defined. You may ask: why char a [] = "Hello"; this time because of the array A. The bundled block of the built-in block has absolute power, which can be read and written. This is better than someone has a land in Chengdong, he can use any crops on this land, but he can't move this land from the city to the city. Relatively speaking, the first-level pointer is also well understood. The secondary pointer is not the same. In particular, the relationship between the secondary pointer and the two-dimensional array is more exciting. I think the best way to learn the principle is experimenting. For programs, they want to have some routines to verify, thus draw some conclusions. Here is my routine:

#include void printfarray (int * parray) {for (int i = 0; i <2; i ) {for (int J = 0; j <2; j ) Printf ("% d", * (PARRAY I * 2 J));} Printf ("/ n");} int main (void) {Int a [2] [2] = {1, 2, 3, 4}; int ** pnum = New int * [2]; int = 0; int J = 0; for (i = 0; i <2; i ) {pNUM [i] = new int [2];} for (i = 0; i <2; i ) {for (j = 0; j <2; j ) {* ((* (PNUM I)) J) = a [i] [j];}} for (i = 0; i <2; i ) {for (j = 0; j <2; j ) {printf ("% D", * ((* (pnum i)) j));}} printf ("/ n") PRINTFARRAY (A [0]); PrintFarray (PNUM [0]); for (i = 0; i <2; i ) {delete pnum [i];} delete pnum; pNum = null; return 1;}

The result is:

Pointer and array relationship initial probe test results Figure 1

You may be strange: Why is the output of the third line and the second line? Now we will output its address and change the program to:

#include void printfarray (int * parray) {for (int i = 0; i <2; i ) {for (int J = 0; j <2; j ) {printf ("% D", * (PARRAY I * 2 J)); Printf ("% D / N", PARRAY I * 2 J); // Here the address}} PRINTF ("/ n");} intf Main (void) {Int a [2] [2] = {1, 2, 3, 4}; int ** pnum = new int * [2]; int = 0; int J = 0; for (i = 0; i <2; i ) {pNUM [i] = new int [2];} for (i = 0; i <2; i ) {for (j = 0; j <2; j ) {* ( * (PNUM I)) J) = a [i] [j];}} for (i = 0; i <2; i ) {for (j = 0; j <2; j ) {printf (" % D ", * (* (PNUM I)) J));}} Printf (" / n "); PrintFarray (a [0]); PrintFarray (PNUM [0]); for (i = 0 i <2; i ) {delete pnum [i];} delete pnum; pnum = null; return 1;} Run results are: pointers and array relationship initial probe test results Figure 2 Seeing their address is also continuous! But this The address is not perfect. Change the program to:

#include void printfarray (int * parray) {for (int i = 0; i <2; i ) {for (int J = 0; j <2; j ) {printf ("% D", * (PARRAY I * 2 J)); Printf ("% D / N", PARRAY i * 2 J);}}}}} int main (void) {Int a [ 2] [2] = {1, 2, 3, 4}; int ** pnum = new int * [= 0; int J = 0; for (i = 0; i <2; i ) {PNUM [I] = new int [2];} for (i = 0; i <2; i ) {for (j = 0; j <2; j ) {* ((* (PNUM I)) j) = a [i] [j];}} for (i = 0; i <2; i ) {for (j = 0; j <2; j ) {printf ("% d", a [i] [J]); Printf ("% D / N", & (a [i] [j]));}}}}}}}}}} PRINTF ("/ n"); for (i = 0; i <2; i ) {for (j = 0; j <2; j ) {printf ("% d", * ((* (PNUM I)) J))))); Printf ("% d / n", ((* (* (PNUM i )) j));}}}} printf ("/ n"); PrintFarray (a [0]); PrintFarray (PNUM [0]); for (i = 0; i <2; i ) {delete pnum [i ];} Delete pnum; pnum = null; return 1;} Run results are: pointers and array relationship initial probe test results Figure 3 This is here, the second-level pointer is not continuous, but the address of the second line head element in the two-dimensional array is only the address of the first row of end elements. This is because using New can open a continuous memory address, but the address opened between NEW is not continuous. This way you will understand why the secondary pointer PNUM passes the function, but only two elements of the head can be output. Also in the two-dimensional array of A and A [0] are the same thing, represent the first address of the array, and PNUM and PNUM [0] are not the same, PNUM is the address of PNUM [0]. Don't believe, you can take them to look at it.

转载请注明原文地址:https://www.9cbs.com/read-131075.html

New Post(0)