Home > Blockchain >  Is it possible to take user input for a 2D array using pointer names in C?
Is it possible to take user input for a 2D array using pointer names in C?

Time:11-24

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!

CodePudding user response:

  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 */
            }
        }
    }
}

CodePudding user response:

This declaration

int *ptr1 = &arr1[3][3];

declares a pointer to the memory after the last element of the array arr1.

As a result the pointer ptr1 does not point to any element of the array arr1.

If instead you will write for example

int *ptr1 = &arr1;

then the compiler will issue a message that there are used pointer of incompatible pointer types because the expression &arr1 has the type int ( * )[3] instead of the type int *.

So you could write

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

In this case the for loop will look the following way

for (int i = 0; i < 3; i  )
{
    for (int j = 0; j < 3; j  )
    {
        scanf("%d", *( ptr1   i )   j);
    }
}

That is the expression *( ptr1 i ) yields the i-th "row" of the two-dimensional array of the type int[3].

In turn used in this expression

*( ptr1   i )   j)

the array designator *( ptr1 i ) is implicitly converted to pointer to the first element of the i-th row of the type int *. So the full expression yields a pointer to the j-th element of the i-th row.

To make it more clear you could rewrite the for loop using an intermediate pointer the following way

for (int i = 0; i < 3; i  )
{
    for (int j = 0; j < 3; j  )
    {
        int *p = *( ptr1   i );
        scanf("%d", p   j);
    }
}

If to declare the pointer ptr1 like

int *ptr1 = &arr1[0][0];

then this for loop

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

in any case will be invalid. For example the expressions ( ptr1 0 ) 1 is the same as the expression ( ptr1 1 ) 0. That is at least some elements of the array will get their values twice.

In this case you need to write at least like

for (int i = 0; i < 3; i  )
{
    for (int j = 0; j < 3; j  )
    {
        scanf("%d", ptr1   3 * i    j);
    }
}

CodePudding user response:

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.

CodePudding user response:

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;
}
  • Related