Two-level pointers and two-dimensional arrays

Source: Internet
Author: User

Recently read the "Linux C programming Encyclopedia" this book, although there are some mistakes in the book, but overall, the writing is still good.

When I see the network Programming "section 23.2.4 to obtain host information", encountered a piece of code, the original text is as follows:

"A host has many network-related information, such as host name, IP address, service provided by the host, and so on. This information is generally stored in a file in the system (such as/etc/hosts, etc.), and the user program can read the contents of these files through the functions provided by the system. The Linux environment uses the Gethostent function to read information about the host, and the prototype of the function is as follows:

 

1 #include <netdb.h>23struct hostent * gethostent (void);

The function reads the host-related information from the system's/etc/hosts file, stores its contents in a static buffer in the system, returns the first address of the static buffer, and returns null if it fails. The structure is defined in the Netdb.h file (Netdb.h is located in the/usr/include directory) and is prototyped as follows:

1#include <netdb.h>2 3 structhostent{4     Char* H_NAME;/*official hostname, each host has only one*/5     Char**h_aliases;/*host alias list, can have many, stored as a two-dimensional array*/6     intH_addrtype;/*IP Address Type, you can choose IPv4 or IPv6*/7     intH_length;/*IP address length, IPv4 corresponds to 4 bytes of address length*/8     Char**h_addr_list;/*IP Address list, h_addr_list[0] is the IP address of the host*/9};

In the code below to get the host information, the author first declares a pointer to the struct hostent type with the following code, and obtains the host information by getting the member variables of the struct, which I don't understand.

1#include <stdio.h>2#include <stdlib.h>3#include <netdb.h>4#include <arpa/inet.h>5 6 #defineNet_addr 16/*16 bytes to hold a string of dotted decimal IP addresses */7 8 intMainvoid)9 {Ten  One     structHosten * HOST;/*for storing host information*/ A     CharADDR_P[NET_ADDR];/*a string used to store dotted decimal IP addresses*/ -     inti; -   the     if((host = Gethosten ()) = = NULL) {/*Get host information*/ -Perror ("fail to get host ' s information\n"); -Exit1); -     }   +     -printf"%s\n", host->h_name);/*Print Host name*/ +      for(i=0; Host->h_aliases[i]! = NULL; i++) {/*Print host aliases*/ Aprintf"%s\n", host->h_aliases[i]); at     } -    -     if(Host->h_addrtype = = af_inet) {/*Print Address Type*/ -printf"af_inet\n"); -     } -     Else { inprintf"unix_inet\n"); -     } to  +printf"%d\n", host->h_length);/*Print Address length*/ -  the      for(i=0; Host->h_addr_list[i]! = NULL; i++) {/*Print host IP address*/ *            /*the address is stored as a binary number, converted to a string form*/ $printf"%s\n", Inet_ntop (host->H_addrtype,Panax NotoginsengHost->H_addr_list[i], addr_p, net_addr); -     } the  +  A     return 0; the  +}

where struct type is a member of Struct hostent, char **h_aliases; The h_aliases here represents a level two pointer to a pointer to a char type, which is a pointer to a char type pointer.

Puzzle: Why can the level two pointer be directly h_aliases[i at the 22nd line below? What exactly is the relationship between the two-level pointers and the two-dimensional arrays? This question is put here first, the paragraph is not table.

By flipping through the data, associating itself with the previous pointers and arrays this part also learned not solid enough, just to make up for the next.

Starting with the value of the address operation from the name of the array and the names of the arrays .

In the http://bbs.csdn.net/topics/310254311 forum, the 2nd floor, the ID of hit_flying answer is: There is a more difficult sentence, you take the address of the group name of course, the address of the array, Unfortunately, C also specifies that the value of the array name is the array address.

and hit_flying on the 12 floor of the supplement:

For the array int a[3][4], will be said to be 2-dimensional array A, then &a of course is to take the address of the array, this has what to suspect, and a itself is the first address of the array, so &a and a value is the same, and the difference between sizeof to see whether the compiler is to treat you as a pointer to handle or as an array to deal with, this point of view of the 4 floor, perhaps &a will be some compiler as a pointer

and verified by the following code:

"Insertion Code Office"

concluded that:

Suppose you have the following declaration

1 int a[3[4]

Then the array name a represents the first address of the array, which is the value equivalent to &a[0][0], that is, the value of a is the address of the array element a[0][0].

And, the name of the array to take the address operation, that is, &a, get the entire array of memory space occupied by the starting address, that is, the beginning of the entire array of addresses, and known quantity group is stored by row, the first element must be a[0][0], so,

So, for &a, we get the address of the array element a[0][0], and we conclude that the value of&a is the same as the value of a.

Just in the C language Chinese network see this article about pointers and arrays, also go here.

Http://c.biancheng.net/cpp/html/477.html

Multidimensional arrays and multi-level pointers are also a place for beginners to feel confused. Arrays of more than two dimensions and pointers of more than two levels are not much used. If we can understand the two-dimensional array and the two-level pointer, then the two-dimensional is not a problem. So this section focuses on two-dimensional arrays and two-level pointers.

One or two-D arrays

1. Hypothetical two-dimensional array layout
As we discussed earlier, there can be no data in the array, except for the function. The following is a detailed discussion of how arrays are stored in an array. Excel table, I believe everyone has seen it. We can usually imagine a two-dimensional array as an Excel table, such as:
Char a[3][4];


2, memory and ruler of the comparison
In fact, the memory is not a table-like, but linear. Have you seen a ruler? The ruler is very similar to our memory. The minimum scale on a general ruler is millimeters, while the smallest unit of memory is 1 byte. Usually we say 32 mm, is the zero start offset 32 mm; Usually we say the memory address is 0x0000ff00 also refers to starting from the memory 0 address offset 0x0000ff00 byte. Since the memory is linear, the two-dimensional array must also be stored linearly in memory. In fact, its memory layout is as follows:


Access one of these elements in an array-subscript way: a[i][j]. The compiler always sees a two-dimensional array as a one-dimensional array, and each element of a one-dimensional array is an array. A[3] The three elements of this one-dimensional array are:
A[0],A[1],A[2]. The size of each element is sizeof (a[0]), or Sizof (char). The first address of the a[0],a[1],a[2] three elements can be calculated as & a[0],& a[0]+ 1*sizof (char) *4,& a[0]+ 2*sizof (char). The first address of A[i] is & a[0]+ i*sizof (char). Then consider the contents of a[i]. For the purposes of this example, A[i] has 4 elements of type char, with the first address of each element being &a[i],&a[i]+1*sizof (char), &a[i]+2*sizof (char) &a[i]+3*sizof (char), the first address of A[i][j] is &a[i]+j*sizof (char). The value of &a[i] is denoted by a, and the first address of the A[I][J] element is: A + i*sizof (char) *4+ j*sizof (char). Similarly, it can be converted into a pointer representation: * (* (a+i) +j).

After the above explanation, I believe you have mastered the layout of the two-dimensional array in memory. Here's a question:
#include <stdio.h>
Intmain (int Argc,char * argv[])
{
int a [3][2]={(0,1), (2,3), (4,5)};
int *p;
p=a [0];
printf ("%d", p[0]);
}
Q What is the result of the printout?

A lot of people think it's too easy, and soon you'll be able to tell me the answer: 0. But it's a pity, wrong. The answer should be 1. If you think it is 0, you really should take a good look at this problem. Parentheses are nested inside curly braces, not curly braces! Here is the comma expression nested inside the curly braces! In fact, this assignment is equivalent to
int a [3][2]={1, 3,5};
So, when initializing a two-dimensional array, be careful not to accidentally write curly braces that should be used.
The

3, &p[4][2]-&a[4][2] What is the value?
The above question seems to be better understood, and here is another example:
int a[5][5];
int (*p) [4];
p = A;
Q &p[4][2]-what is the value of &a[4][2]?

The problem seems to be very simple, but almost no one has answered it correctly. We can write the code first to test its value, and then analyze why. In Visual c++6.0, the test code is as follows:
Intmain ()
{
int a[5][5];
int (*p) [4];
p = A;
printf ("a_ptr=% #p, p_ptr=% #p \ n", &a[4][2],&p[4][2]);
printf ("%p,%d\n", &p[4][2]-&a[4][2],&p[4][2]-&a[4][2]);
return 0;
}
After testing, it is known that the value of &p[4][2]-&a[4][2] is-4. What the hell is this? Let's look at the following: As we said earlier, when the array name A is the right value, it represents the first address of the first element of the array. Here A is a two-dimensional array, and we think of array A as a one-dimensional array containing 5 elements of type int, which stores a one-dimensional array.

In this case, a is represented here as the first address of a[0]. A+1 represents the second element of the one-dimensional array A. A[4] Represents the 5th element of a one-dimensional array, and this element has a one-dimensional array. So &a[4][2] represents &a[0][0]+4*5*sizeof (int) + 2*sizeof (int).

By definition, p is a pointer to an array that contains 4 elements. That is, p+1 means that the pointer p moves backwards a "array containing 4 elements of type int". Here 1 of the units are the space that P points to, that is, 4*sizeof (int). Therefore, p[4] moves backwards by 4 "arrays containing 4 elements of type int" relative to p[0], that is, &p[4] represents &p[0]+4*4*sizeof (int). Since P is initialized to &a[0], then &p[4][2] represents &a[0][0]+4*4*sizeof (int) +2* sizeof (int).

Again, the values of &p[4][2] and &a[4][2] differ by 4 elements of type int. Now, the results of the tests above can be understood, right? In fact, our simplest way is to draw the memory layout:


The most important thing here is to understand what the memory of the array pointer p points to. The best way to solve this kind of problem is to draw a memory layout diagram.

二、二级 pointer

Memory layout for 1, two-level pointers
Second-level pointers are often used, especially when combined with two-dimensional arrays that are confusing. For example:
Char **p;
Defines a two-level pointer variable p. P is a pointer variable, which undoubtedly accounts for 4 byte under a 32-bit system.

Unlike a first-level pointer, a one-level pointer holds the address of the data, and a level two pointer holds the address of a primary pointer. Help understand:

We try to initialize the variable p:
A
p = NULL;
B
Char *p2; p = &p2;
Any pointer variable can be initialized to null (note that it is null, not nul, and not NULL), and a level two pointer is no exception. This means pointing the pointer to the 0 address of the array. Lenovo to the front we compare the ruler to memory, if the memory is initialized to NULL, it is equivalent to pointing the pointer to the ruler 0 mm, when the pointer is not any memory available.

When we really need to use p, we have to save the address of a first-level pointer to P, so B) is also the correct way to assign the value.

After reading this article, or a little less enjoyable, and then found this post:

Http://www.360doc.com/content/11/0506/22/6903212_114913991.shtml

First look at a simple: char *p, which defines a pointer to the data type of the pointer is a character type, char * (p) defines a pointer p;

Char *p[4], as an array of pointers , because [] the precedence is higher than *, so p first and [] union, p[] is an array, temporarily put p[] as Q, that is, char * (q), defines a pointer q, but q is an array, Therefore, an array is defined, and the data inside the array is char *, so the data inside the array is the pointer type. So Char *p[4] is four pointers, and these four pointers make up an array, called an array of pointers, that consists of multiple pointers.

char (*P) [4], which is the array pointer, forces the change of precedence, * first with P, so p becomes a pointer to an array with 4 char data. Therefore, the first address of this char array is stored in P and can be applied using the array pointer dynamic memory:

char (*P) [ten];

p= (char*) malloc (sizeof (CHAR[X)) *n);

Char *f (Char,char), a pointer function, () has precedence over *, so F is first combined with (), becomes function f (), the return value of the function is char * type, so the return value is a pointer.

char (*f) (Char,char), as a function pointer,* and F are combined into a pointer to the entry address of the function. The function name is the first address of the function. A function pointer is a pointer variable that points to a function. Thus the function pointer itself should first be a pointer variable, except that the pointer variable points to the function. This is just like using pointer variables to point to integer variables, character types, and arrays, and here is a pointer to a function. C at compile time, each function has a portal address, which is the address pointed to by the function pointer. Once you have a pointer variable to a function, you can use that pointer variable to call the function, just as you can refer to other types of variables with pointer variables, which are conceptually consistent. A function pointer has two uses: calling a function and making a function argument.

int func (int x); /* Declare a function */
Int (*f) (int x); /* Declare a function pointer */
F=func; /* Assigns the first address of the Func function to the pointer f */

If you want to invoke the function func () Later, you can call it this way: (*f) ();

Finally, we're back to the point, about level two pointers and two-dimensional arrays

/**************************************************** Level two pointer ********************************************* *****/

A second-level pointer is simply a pointer to a pointer.

Char a=200;

Char *p;

Char **q;//q is a level two pointer

p=&a;

q=&p;//q pointing pointer p

Assuming that variable A has an address of 2000H in memory, their relationship is as follows:

The value of the pointer p to A,p is 2000h,*p is to take the value in address 2000H, A is 200, and the address of P itself is 4000h,q point pointer p,*q is the value of the address 4000H is the value of P is 2000H, and **q is to take the address 2000H value is 200.

So:

*p==200;

*q=2000h;

**q=200;

The above q is a two-level pointer to a pointer pointer, but there is also a level two pointer to the array.

When a pointer variable points to another pointer variable, a level two pointer is formed. The use of level two pointers provides greater flexibility in building complex data structures, enabling functionality that is difficult to implement in other languages. The form of a two-level pointer is defined as:

Type identifier * * Level two pointer variable name

When you define a pointer, you can assign a value to it, and then you can use it.

If you define an array of pointers, the pointer array name is a level two pointer. The pointer array element value points to the same length of the string, the operation can save memory space, and the operation of the address, improve the operational efficiency.

Char s[3][5]={"abc", "UiO", "Qwe"};
Can be seen as three pointer to a string (S[0],s[1],s[2]), by s[3].
and S itself is a one-dimensional array storage s[0],s[1],s[2] Three first-level pointers, then s can be considered as a level two pointer, that is, a pointer to the pointer.
At this point a level two pointer char**p is defined, and a two-dimensional array can be accessed by P.

You can also do this char *p[] = {"AB", "CD", "EF"}; An array of pointers is defined.

char **sp = p;

You can use Sp[i] to access the string.

(To be Continued ...)

Reference:

http://bbs.csdn.net/topics/310254311

Http://c.biancheng.net/cpp/html/477.html

Http://www.360doc.com/content/11/0506/22/6903212_114913991.shtml

Two-level pointers and two-dimensional arrays

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.