简体   繁体   中英

av[1] and av[1][0] Not the same address?

What's up? I can't understand this issue... I know that the first element of an array stock the address of the entire array. But in this situation i can't figure it out.

#include <stdio.h>

int main(int ac, char **av)
{
    printf("&av[1]= %p\n", &av[1]);
    printf("&av[1][0]= %p\n", &av[1][0]);

    return(0);
}

Input

./a.out "Hello"

Output

&av[1]= 0x7ffee0ffe4f0
&av[1][0]= 0x7ffee0ffe778

If somebody told you that char **av declares a two-dimensional array, they did you a disservice. In char **av , av is a pointer to a char * , possibly the first char * of several. So av[1] is a char * —it is a pointer to a char , and &av[1] is the address of that pointer .

av[1][0] is the char that av[1] points to, and &av[1][0] is the address of that char .

The pointer to the char and the char are of course not in the same place, so &av[1] and &av[1][0] are different.

In contrast, if you had an array, such as char av[3][4] , then av is an array of 3 arrays of 4 char . In that case, av[1] is an array of 4 char , and &av[1] would be the address of (the start of) that array. &av[1][0] would be the address of the first char in that array. Since the char is at the beginning of the array, the address of the array and the address of the char are the same.

(However, they are not necessarily represented the same way in a C implementation, and printing them with %p can show different results even though they refer to the same place in memory.)

av isn't a two-dimensional array here. It's an array of pointers.

Whereas with a two dimensional array, &av[1][0] would have the same address as &av[1] ; in an array of pointers, &av[1][0] means take the second (index=1) pointer, dereference it, and give me the address of the first element of what the dereferenced pointer target points at (the target of av[1] is also a pointer).

&av[1] is the address of the second char* , &av[1][0] is the address of the first character that the second char* points at. Different things.

av is an array of pointers where each element of this array points to a char array (of type char * ) in which each character you are passing as input to the program is stored.

As you can see by the following variation of your program, av[0] stores the address of av[0][0] (ie points to the first position of the string stored in av[0][0] ) which contains the character . and av[1] stores the address of av[1][0] (ie points to the first position of the string stored in av[1][0] ) which contains the character H .

#include <stdio.h>

int main(int ac, char **av)
{

    printf("&av[0]= %p\n", &av[0]);
    printf("&av[1]= %p\n", &av[1]);

    printf("av[0]= %p\n", av[0]);
    printf("av[1]= %p\n", av[1]);

    printf("av[0][0]= %c\n", av[0][0]);
    printf("av[0][1]= %c\n", av[0][1]);


    printf("av[0][0]= %p\n", &av[0][0]);
    printf("av[0][1]= %p\n", &av[0][1]);

    printf("av[1][0]= %c\n", av[1][0]);
    printf("av[1][1]= %c\n", av[1][1]);

    printf("av[1][0]= %p\n", &av[1][0]);
    printf("av[1][1]= %p\n", &av[1][1]);

    return(0);
}

which provides the following output:

$ ./a.out "Hello"
&av[0]= 0x7fff53625cf8
&av[1]= 0x7fff53625d00

av[0]= 0x7fff53626ee9
av[1]= 0x7fff53626ef1

av[0][0]= .
av[0][1]= /
&av[0][0]= 0x7fff53626ee9
&av[0][1]= 0x7fff53626eea

av[1][0]= H
av[1][1]= e
&av[1][0]= 0x7fff53626ef1
&av[1][1]= 0x7fff53626ef2

Graphically it is something like (significant part of addresses were removed for simplification purposes):

      av: | 26ee9 | 26ef1 |
              |       |
            av[0]   av[1] 
 address:   25cf8   25d00

   av[0]: |   .  |    /   | ...
              |       |
          av[0][0] av[0][1] 
 address:   26ee9   26eea

   av[1]: |   H  |    e   | ...
              |       |
          av[1][0] av[1][1] 
 address:   26ef1   26ef2

I hope this clarifies your doubt.

av is a pointer to an array of pointers to char s. So its second element (the second element of the array) is, indeed a pointer. &av[1] is it's address (the address of a pointer, not the address of a character).

On the other side, av[1][0] is the first character of that second string. Its address is a char address, where the first character is stored.

Both addresses are addresses of different things, so it's normal they point to different places.

av[1] and &av[1][0] are, respectively, the pointer value (that points to the first char) and the address of the first char of the second string, so they must be pointers showing the same value . The same happens to *av[1] and av[1][0] , they represent the same pointed to character.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM