2
/* Demonstrates passing a pointer to a multidimensional */
/* array to a function. */

#include <stdio.h>

void printarray_1(int (*ptr)[4]);
void printarray_2(int (*ptr)[4], int n);

int main(void)
{
    int multi[3][4] = { {1, 2, 3, 4},
                        {5, 6, 7, 8},
                        {9, 10, 11, 12} };

    // ptr is a pointer to an array of 4 ints.
    int (*ptr)[4], count;

    // Set ptr to point to the first element of multi.
    ptr = multi;

    // With each loop, ptr is incremented tto point to the next
    // element (that is, the next 4-elements integer array) of multi.

    for (count = 0; count < 3; count++)
        printarray_1(ptr++);

    puts("\n\nPress Enter...");
    getchar();
    printarray_2(multi, 3);
    printf("\n");

    return 0;
}

void printarray_1(int (*ptr)[4])
{
    // Prints the elements of a single 4-element integer array.
    // p is a pointer to type int. You must use a typecast
    // to make p equal to the address in ptr.

    int *p, count;
    p = (int *)ptr;

    for (count = 0; count < 4; count++)
        printf("\n%d", *p++);
}

void printarray_2(int (*ptr)[4], int n)
{
    // Prints the elements of an n by 4-element integer arrray.

    int *p, count;
    p = (int *)ptr;

    for (count = 0; count < 4; count++)
        printf("\n%d", *p++);
}

In the definition of printarray_1 & 2 functions, the int pointer p is assigned to (int *)ptr. why?

In the pointer declaration of the main function, the parenthesis puts *ptr in a higher precedence than [4]. but (int *)ptr does not make sense to me. Would you please explain why?

9
  • printarray_1 and printarray_2 seem exactly the same except the latter has an extra argument that is never used? Commented Apr 7, 2020 at 2:07
  • @user3386109 it looks OK to me (apart from the redundant int n) Commented Apr 7, 2020 at 2:10
  • It's bad form to do p = (int *)ptr; It should just be p = *ptr; Commented Apr 7, 2020 at 2:11
  • 2
    In general you should not be casting pointers from one type to another if you can help it. To and from void * is sometimes necessary, but in a case like this you're circumventing the type system and constructing your own pointer, claiming it has the desired type by casting it. It makes no sense to do that when you can accomplish the same thing more clearly, more concisely, and without bypassing the builtin type checks of the language. You want the compiler to warn you about pointer type mismatches. Don't hide them from it. Commented Apr 7, 2020 at 2:42
  • 3
    @aom Regarding why the author did it that way, it wouldn't surprise me at all if he or she simply didn't know better and didn't understand what dereferencing a pointer to an array does in C. You'd be surprised at how many people who think they understand it really don't. But no one who does would ever write p = (int *) ptr; in this situation. They would instead write p = *ptr; or p = ptr[0]; rather than giving up and bypassing the type system of the language. Note that none of these actually perform a memory reference - they merely change the type of the pointer. Commented Apr 7, 2020 at 3:00

1 Answer 1

2

The syntactically and semantically correct way to obtain p from ptr is:

    p = *ptr;

... as you are trying to extract an array int p[4] (declared as int *p) from a pointer to an array int(*ptr)[4]. This eliminates the need for any casting.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.