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:
- Use meaningful variables names. Who can know if
i
is the row or column. - You need to multiply the row by number of columns.
- You want reference to the first element of the array not to the one outside the array bounds.
- 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;
}