Reputation: 829
I am trying to create a variable matrix using a function that inputs an empty array pointer m
and outputs the int array pointer m
with values 1,2,3,4,...n
elements in the matrix. I use the variable k and increment the value upwards to accomplish this (not sure if this is the best way).
I am getting a subscripted value is not an array, pointer, or vector
in my for loop here matrix[i][j] = k++;
and I am not really sure why it is only appearing inside the for loop and nowhere else.
If I am inputting an int array pointer called matrix, I shouldn't be getting this error right?
int *create_matrix(int* matrix) {
int i,j;
int k = 0;
// 'total' will be 70 = 10 * 7
int total = sizeof(matrix);
// 'column' will be 7 = size of first row
int column = sizeof(matrix[0]);
// 'row' will be 10 = 70 / 7
int row = total / column;
for (i=0; i < row; i++) {
for (j=0; j < column; j++) {
matrix[i][j] = k++;
}
}
return matrix;
}
int main(void) {
// Creating a custom matrix.
int m[3][4] = {0};
create_matrix(*m);
return 0;
}
Upvotes: 1
Views: 754
Reputation: 14434
Your attempt is a reasonable attempt but it reveals some misconceptions about how objects in C work. That's all right. Yours is a good teaching example and I believe that you will be glad that you have made it. Now try this:
static const int NO_ROWS = 3;
static const int NO_COLUMNS = 4;
int *create_matrix(
int *const matrix, const int no_rows, const int no_columns
) {
int k = 0;
for (int i = 0; i < no_rows; i++) {
for (int j = 0; j < no_columns; j++) {
matrix[no_columns*i+j] = k++;
}
}
return matrix;
}
int main(void) {
// Creating a custom matrix.
int m[NO_ROWS][NO_COLUMNS];
create_matrix(m[0], NO_ROWS, NO_COLUMNS);
return 0;
}
Your matrix is constructed as an array of arrays. However, in C, an array is just a region of storage in which a sequence of objects of the same type (in your case, int
) can be kept. The symbol m
is interpreted by the C compiler as
int[NO_COLUMNS]
.The problem is that there exists no really neat, direct way to specify to a precompiled function the type int[NO_COLUMNS]
unless you are willing to hard-code the type. Therefore, one relatively straightforward way to treat the matrix within create_matrix()
would be as a single, linear array, as shown.
One point to grasp here is that C does not understand the shape of your matrix. Rather than rows and columns, C sees a linear region of storage.
Another point to grasp is that function to which an array is passed receives only the array's initial address. If it needs the size, that must be separately passed.
Upvotes: 0
Reputation: 32586
To do
int m[3][4] = {0};
create_matrix(*m);
is equivalent of
int m[3][4] = {0};
create_matrix(m[0]);
so is equivalent of having
int m[4] = {0};
create_matrix(m);
// 'total' will be 70 = 10 * 7
int total = sizeof(matrix);
matrix is a int *
, sizeof(matrix)
values 4 if an address uses 32b and 8 if an address uses 64b
The effective size of matrix in main is not relevant
// 'column' will be 7 = size of first row
int column = sizeof(matrix[0]);
matrix[0]
is an int, so you get the size of an int (4 or 8 probably)
matrix[i][j] = k++;
because matrix is an int * the form matrix[i][j]
is invalid.
To name it matrix is not helpful.
Your program can be :
#include <stdio.h>
void fill_matrix(int matrix[][4], size_t row) {
size_t i, j;
int k = 0;
for (i=0; i < row; i++) {
for (j=0; j < sizeof(matrix[0])/sizeof(int); j++) {
matrix[i][j] = k++;
}
}
}
int main(void) {
// Creating a custom matrix.
int m[3][4] = {0};
fill_matrix(m, sizeof(m)/sizeof(m[0]));
size_t i, j;
for (i=0; i < sizeof(m)/sizeof(m[0]); i++) {
for (j=0; j < sizeof(m[0])/sizeof(int); j++) {
printf("matrix[%d][%d] = %d\n", i, j, m[i][j]);
}
}
return 0;
}
Compilation and execution :
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra m.c
pi@raspberrypi:/tmp $ ./a.out
matrix[0][0] = 0
matrix[0][1] = 1
matrix[0][2] = 2
matrix[0][3] = 3
matrix[1][0] = 4
matrix[1][1] = 5
matrix[1][2] = 6
matrix[1][3] = 7
matrix[2][0] = 8
matrix[2][1] = 9
matrix[2][2] = 10
matrix[2][3] = 11
Probably it is more visible if you initialize each cell of the matrix with i*10+j
rather than with k++
, in that case that prints :
matrix[0][0] = 0
matrix[0][1] = 1
matrix[0][2] = 2
matrix[0][3] = 3
matrix[1][0] = 10
matrix[1][1] = 11
matrix[1][2] = 12
matrix[1][3] = 13
matrix[2][0] = 20
matrix[2][1] = 21
matrix[2][2] = 22
matrix[2][3] = 23
Upvotes: 1
Reputation: 31296
You need to learn the difference between arrays and pointers. You can point a pointer to a matrix, but the information about size and number of dimensions are lost as long as you're only accessing the array via the pointer.
You would need to do something like this:
int *create_matrix(int* matrix, size_t size_x, size_t size_y) {
...
}
int main()
{
int m[3][6];
size_t size_y=sizeof m[0]/sizeof m[0][0];
size_t size_x=sizeof m / sizeof m[0];
create_matrix(m);
}
Upvotes: 1