简体   繁体   中英

How do pointers work when declaring a pointer to an array and passing to function

Okay, for some reason I can't wrap my head around this but this is what I know or think I know so far.

If I was to declare an array of type char, char a[8][8] and then declare a pointer of type char:

char *p = a;

I know that if I deference a in a print statement, I am getting the address of the first row - if I simply print array a, I'm still getting the same address because the array, a, points to the first row. Now if I print p, I know I will get the address of a as that is what a pointer variable does.

Regardless of whether or not I did:

char *p = &a or char *p = a or char *p = *a , it's the same thing - points to the same address.

The problem comes in when I decide to print the variable p with a deference. When I print *p , I get the value of a[0][0] . The problem is, when I try to print a deference of a , I get the address of the first row once again, instead of the value a[0][0] .

Does this mean that when I create a pointer variable to an array, it skips pointing to the array, and directly points to the row of a? Meaning:

[*p] = [**a] instead of [*p] = [*a] because [char *p = *a] = [char *p = a]

So by creating the pointer, it skips down? I'm probably overthinking this or have found a rule or property that my brain doesn't want to accept.

EDIT: I seem to understand now from Vlad's answer. It's just strange because, as I was doing the study questions for my class, I was told to make a function like this without using [] as an exercise which is the reason I tried to avoid this avenue.

char a[3][8] means you have

an array ( of 3 members ) of array of 8 characters.

You need to have

char (*ptr)[8]=a; // Pointer to an array(of 3 members) of 8 characters

Note that you, as a programmer need to take care that you're not accessing beyond the legal array bound ie the maximum you can go for is (*(ptr+2)) as the count starts at zero. ie zero to two makes three !!

It could be represented as

(*ptr)[8]  // the pointer ptr points to
   V       // the first element of
arr[0][8]  // arr, ie arr[0]

As C pointers support array like dereferencing, you could do

ptr[0][1] which is the same as (*(ptr+0))[1]

Similarly

ptr[2][7] which is the same as (*(ptr+2))[7] 
//note [2][7] is the maximum bound  for legal access

Finally, what is problem with

char *ptr=a;

With char *ptr you have a pointer. Yeah! that is correct. The problem comes when you think about compatibility of *ptr with a . a has type char[8] . But with just char *ptr=a , you are not accounting for the [8] part in a . the difference becomes clear when you take the size

char a[3][8];
char (*ptr)[8]=a;
char *ptr1=a; // A good compiler will warn you about this line.
printf("ptr : %zd\n",sizeof *ptr);
printf("ptr1 : %zd\n",sizeof *ptr1);

Gives me

ptr : 8 // accounts for eight characters. Here ptr covers the entire
block of eight charactes, so that if you need to go to the next block
of eight characters you could just do "ptr+1" or "ptr[1]
ptr1 : 1 // accounts for just one character.

If you have a declaration of an array like this

char a[8][8];

then this declaration

char *p = a;

is invalid.

As you correctly pointed out in expressions a two-dimensional array designator with rare exceptions is converted to pointer to its first row. Thus the variable a used as initializer is converted to rvalue of type char ( * )[8] . Pointers of types char * and char ( * )[8] are incompatible. They point to objects of different types. The first one points to objects of type char while the second one points to objects of type char[8] .

As for addresses then an array is an extent of memory. Thus the address of the array itself or its first row or of its first element in the first row are equal each other because all of them are the address of the extent of memory occupied by the array.

You can interpret a two dimensional array as a one dimensional array. For example

char *p = ( char * )a;

Of course in this case you can apply only one time the subscript operator to the pointer. The array extent will be considered as a memory occupied by a one dimensional array of type char[ 8 * 8 ] that is char[64] . However there can be a problem if each row of the original array contains a string.

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