0

I want to take user input for a 2D array using pointer name

Let's say I have a 2D array named arr1[3][3] and the pointer variable name is ptr1. Is it possible use scanf with the pointer variable name? Check the code below. I am using ptr1+row+column in a nested loop

`#include <stdio.h>

int main(void)
{
    int arr1[3][3];
    int *ptr1 = &arr1[3][3];

    for (int row = 0; row < 3; row++)
    {
        for (int column = 0; column < 3; column++)
        {
            scanf("%d", (ptr1 + row) + column);
        }
    }
}`

I know I could have taken input using scanf("%d", (*(arr1 + i) + j)); Thank you!

3 Answers3

0
  1. Use meaningful variables names. Who can know if i is the row or column.
  2. You need to multiply the row by number of columns.
  3. You want reference to the first element of the array not to the one outside the array bounds.
  4. Always check the result of scanf.
#define ROWS 3
#define COLS 3

int main(void)
{
    int arr1[ROWS][COLS];
    int *ptr1 = &arr1[0][0];

    for (int row = 0; row < ROWS; row++)
    {
        for (int col = 0; col < COLS; col++)
        {
            if(scanf("%d", ptr1 + row * COLS + col) != 1)
            {
                 /* handle error */
            }
        }
    }
}
0___________
  • 60,014
  • 4
  • 34
  • 74
  • Technically, `ptr1 + row * COLS + col` is UB when `row > 0 && col > 0 || row > 1`. – Ian Abbott Nov 23 '22 at 14:14
  • @IanAbbott no, I do not index – 0___________ Nov 23 '22 at 14:17
  • @IanAbbott can you show me where it is in the Standard – 0___________ Nov 23 '22 at 14:19
  • It's in the section on Additive operators C99/C11/C17 6.5.6p8. `ptr1` is pointing to elements of `arr1[0]` and is allowed to be in the range `arr1[0] + 0` to `arr1[0] + COLS`. `arr1[0] + COLS` is one past the last element of `arr1[0]` so is OK as a pointer but dereferencing it is also UB. `arr1[0] + COLS + 1` is technically an invalid pointer so is UB. – Ian Abbott Nov 23 '22 at 14:36
  • @IanAbbott no as it does not point outside the array bounds. for `int *` pointer the referenced object is 1d int array. – 0___________ Nov 23 '22 at 14:41
  • I think it's been debated to death in https://stackoverflow.com/q/6290956/5264491 – Ian Abbott Nov 23 '22 at 14:45
  • @IanAbbott thanks God SO debates are not the part of the standard :) – 0___________ Nov 23 '22 at 14:46
  • I agree the referenced object is a 1d int array - of length `COLS`. :-) I also agree it would be nice if the standard permitted this sort of flattening. – Ian Abbott Nov 23 '22 at 14:49
0

You can use a pointer to array. Or in this specific case if you will, a pointer to a row:

#include <stdio.h>

int main(void)
{
    int arr1[3][3];
    int (*ptr1)[3] = arr1;

    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            scanf("%d", &ptr1[i][j]);
        }
    }
}

Using *(arr + i) etc notation is almost always bad practice, since arr[i] is more readable. There exists no reason why you shouldn't be using the ptr1[i][j] format in this case - unless you like to write unreadable code for the heck of it.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

There are already good answer posted. my answer would be side note . In case if we have dynamic 2-D array, below implementation is for that

#include <stdio.h>
#include <stdlib.h>

#define rows 3
#define cols 3

int main ()
{

  //allocate memory equal to [rows * cols]
  int *arr = (int *) malloc (rows * cols * sizeof (int));

  if (arr == NULL)
    {
      printf ("out of memory");
      exit (0);
    }

  // accessing each row and its respective columns.
  // index = row * NumberOfColumns + column
  for (int i = 0; i < rows; i++)
  {
        for (int j = 0; j < cols; j++)
        {
            arr[i * cols + j] = rand () % 10;
        }
  }

  for (int i = 0; i < rows; i++)
  {
        for (int j = 0; j < cols; j++)
        {
            printf ("Row[%d], Column[%d]:%d\n", i, j, arr[i * cols + j]);
        }
  }

  free (arr);

  arr = NULL;

  return 0;
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
user8811698
  • 118
  • 1
  • 7