For each time step, I have a 2D matrix a[ix][iz] with ix varying from 0 to nx-1 and iz varying from 0 to nz-1.
To assemble the matrix of all the time steps, I define a 3D pointer ***b of length nx*nz*nt. At time it the matrix can be represented by b[ix][iz][it] with ix varying from 0 to nx-1 and iz varying from 0 to nz-1.
In the time loop, I have to deliver the 2D array/pointer at time it to the function void func(**ptr). Because b is a 3D pointer/array, how can I call it in the main code? Like func(b[it]);?
You could restructure your matrix as b[it][ix][iz] instead of b[ix][iz][it]. This way, you'd have an array of 2D matrices, allowing you to pass in the 2D matrix at any given timestep using b[it].
Otherwise, if you keep your matrix as-is, you'd have to construct the 2D array at time it, then pass that into func() - that's extra computation that you can avoid by restructuring your 3D matrix.
The simplest way would be to use your b to just store pointers to matrices like this:
In each timestep, copy your matrix a and insert the pointer to the copy of matrix a into b.
Then, you can pass b[i] over to your function func(b[i]) .
That is basically what frsim suggests as well.
In code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_TIME 5
void func(int array[2][3]) {
for(size_t x = 0; x < 2; ++x) {
for(size_t y = 0; y < 3; ++y) {
printf("%i ", array[x][y]);
}
printf("\n");
}
printf("\n");
}
int main (int argc, char** argv) {
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int b[MAX_TIME][2][3] = {0};
for(size_t time = 0; time < MAX_TIME; ++time) {
/* Calculate your new version of `a` here */
a[1][0] = time;
memcpy(b[time], a, sizeof(a));
printf("%zu ", sizeof(a));
}
for(size_t i = 0; i < MAX_TIME; ++i) {
printf("time: %zu \n", i);
func(b[i]);
}
}
Arrays bear a lot of pitfalls, in particular, an array is not a pointer.
But: If you pass an array to a function, what happens is that not the array itself will be passed into the function, but a pointer to the array.
The same would happen with a two-dimensional array: When calling a function with a two-dimensional array, what is passed into the function is not the array, but a pointer, and this pointer is still just int * and not int **... See e.g. this question
Related
I have written code which allows me to modify the elements of a 1D array within my function by passing the element of the array:
I print the original array
I pass each element of the array to the function
Within the function I add the value 50 to each element of the array
I then call the function, and print out to screen the modified element value (i.e the value of each element +50)
I have been able to do this for a 1D array, with example values in the array being (10,20,30) and the valued printed after modification being (60,70,80).
What I am hoping to do is adapt that code to work for 2D arrays, you will see my attempt at doing this below. This code focuses on the use of int, but once I understand how to achieve this I am hoping to adapt for the use of a 2D string as well.
With the code below:
My objective is
Print to screen the original 2D array
Pass each element of the 2D array to the function
Within the function add the value 50 to each element of the array
Then call the function, and print out the modified element values to the screen(expected result displayed on screen 60,61,etc,.)
So far I have been able to print the original 2D array to the screen. It is the function I think I am messing up and would appreciate any advice. Thank you.
#include <stdio.h>
#include <string.h>
#define M 4
#define N 2
int function(int **arr);
int main() {
int i, a;
int arr[N][M] = {10, 11, 12, 13, 14, 15, 16, 17};
// the int array first
for(i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
// Accessing each variable
printf("value of arr[%d] is %d\n", i, arr[i][j]);
}
}
printf("\n ***values after modification***\n");
a = function(&arr[i][0]);
// int array print results
for(int i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr %d\n", arr[i][j]);
}
}
return 0;
}
int function(int **arr) {
int i;
int j;
for(int i = 0; i < 3; i++) {
for(size_t j = 0; j < 5; j++) {
arr[i][j] = arr[i][j] + 50;
}
}
}
My apologies in advance for silly mistakes I am very new to C.
Thank you in advance.
The function int function(int **arr) does not return an int so make it void.
When you call it, a = function(&arr[i][0]);, you do not use a after the assignment. I suggest that you remove a from the program completely since it's not used anywhere.
The call to the function, function(&arr[i][0]);, should simply be function(arr);
The function signature needs to include the extent of all but the outermost dimension:
void function(int arr[][M])
Inside the function, you use 3 and 5 instead of N and M. That accesses the array out of bounds.
In function, the i and j you declare at the start of the function are unused. Remove them.
arr[i][j] = arr[i][j] + 50; is better written as arr[i][j] += 50;
When initializing a multidimensional array, use braces to make it simpler to read the code:
int arr[N][M] = {{10, 11, 12, 13}, {14, 15, 16, 17}};
In main you mix int and size_t for the indexing variables. I suggest you settle for one type.
Remove unused header files (string.h)
Example:
#include <stdio.h>
#define N 2
#define M 4
void function(int arr[][M]) {
for(int i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
arr[i][j] += 50;
}
}
}
int main() {
int arr[N][M] = {{10, 11, 12, 13}, {14, 15, 16, 17}};
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
printf("\n ***values after modification***\n");
function(arr);
// int array print results
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
}
Since you print the array more than once, you could also add a function to do so to not have to repeat that code in main:
void print(int arr[][M]) {
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
}
Two-Dimensional arrays in C (and C++) are actually one-dimensional arrays whose elements are one-dimensional arrays. The indexing operator [] has left-to-right semantics, so for a type arr[N][M] the first index (with N elements) is evaluated first. The resulting expression, e.g. arr[0], the first element in arr, is a one-dimensional array with M elements. Of course that array can be indexed again , e.g. arr[0][1], resulting in the second int in the first sub-array.
One of the quirks in the C language is that if you use an array as a function argument, what the function sees is a pointer to the first element. An array used as an argument "decays" or, as the standard says, is "adjusted" that way. This is no different for two-dimensional arrays, except that the elements of a two-dimensional array are themselves arrays. Therefore, what the receiving function gets is a pointer to int arr[M].
Consider: If you want to pass a simple integer array, say intArr[3], to a function, what the function sees is a pointer to the first element. Such a function declaration might look like void f(int *intPtr) and for this example is simply called with f(intArr). An alternative way to write this is void f(int intPtr[]). It means exactly the same: The parameter is a pointer to an int, not an array. It is pointing to the first — maybe even only — element in a succession of ints.
The logic with 2-dimensional arrays is exactly the same — except that the elements, as discussed, have the type "array of M ints", e.g. int subArr[M]. A pointer argument to such a type can be written in two ways, like with the simple int array: As a pointer like void f(int (*subArrPtr)[M]) or in array notation with the number of top-level elements unknown, like void f(int arr[][M]). Like with the simple int array the two parameter notations are entirely equivalent and interchangeable. Both actually declare a pointer, so (*subArrPtr)[M] is, so to speak, more to the point(er) but perhaps more obscure.
The reason for the funny parentheses in (*subArrPtr)is that we must dereference the pointer first in order to obtain the actual array, and only then index that. Without the parentheses the indexing operator [] would have precedence. You can look up precedences in this table. [] is in group 1 with the highest priority while the dereferencing operator * (not the multiplication!) is in group 2. Without the parentheses we would index first and only then dereference the array element (which must therefore be a pointer), that is, we would declare an array of pointers instead of a pointer to an array.
The two possible, interchangeable signatures for your function therefore are
void function( int (*arrArg)[M] ); // pointer notation
void function( int arrArg[][M] ); // "array" notation (but actually a pointer)
The entire program, also correcting the problems Ted mentioned, and without printing the original values (we know them, after all), is below. I have also adapted the initialization of the two-dimensional array so that the sub-arrays become visible. C is very lenient with initializing structures and arrays; it simply lets you write consecutive values and fills the elements of nested subobjects as the come. But I think showing the structure helps understanding the code and also reveals mistakes, like having the wrong number of elements in the subarrays. I have declared the function one way and defined it the other way to show that the function signatures are equivalent. I also changed the names of the defines and of the function to give them more meaning.
#include<stdio.h>
#define NUM_ELEMS_SUBARRAY 4
#define NUM_ELEMS_ARRAY 2
/// #arrArg Is a pointer to the first in a row of one-dimensional
/// arrays with NUM_ELEMS_SUBARRAY ints each.
void add50ToElems(int arrArg[][NUM_ELEMS_SUBARRAY]);
int main()
{
// Show the nested structure of the 2-dimensional array.
int arr[NUM_ELEMS_ARRAY][NUM_ELEMS_SUBARRAY] =
{
{10, 11, 12, 13},
{14, 15, 16, 17}
};
// Modify the array
add50ToElems(arr);
// print results
for (int i = 0; i < NUM_ELEMS_ARRAY; i++) {
for (int j = 0; j < NUM_ELEMS_SUBARRAY; j++)
{
printf("value of arr[%d][%d]: %d\n", i, j, arr[i][j]);
}
}
return 0;
}
// Equivalent to declaration above
void add50ToElems(int (*arrArg)[NUM_ELEMS_SUBARRAY])
{
for (int i = 0; i < NUM_ELEMS_ARRAY; i++)
{
for (size_t j = 0; j < NUM_ELEMS_SUBARRAY; j++)
{
//arrArg[i][j] = arrArg[i][j] + 50;
arrArg[i][j] += 50; // more idiomatic
}
}
}
Why is it wrong to pass a two-dimensional array to a function expecting a pointer-to-pointer? Let's consider what void f(int *p) means. It receives a pointer to an int which often is the beginning of an array, that is, of a succession of ints lying one after the other in memory. For example
void f(int *p) { for(int i=0; i<3; ++i) { printf("%d ", p[i]); }
may be called with a pointer to the first element of an array:
static int arr[3];
void g() { f(arr); }
Of course this minimal example is unsafe (how does f know there are three ints?) but it serves the purpose.
So what would void f(int **p); mean? Analogously it is a pointer, pointing to the first in a succession of pointers which are lying one after the other in memory. We see already why this will spell disaster if we pass the address of a 2-dimensional array: The objects there are not pointers, but all ints! Consider:
int arr1[2] = { 1,2 };
int arr2[2] = { 2,3 };
int arr3[2] = { 3,4 };
// This array contains addresses which point
// to the first element in each of the above arrays.
int *arrOfPtrToStartOfArrays[3] // The array of pointers
= { arr1, arr2, arr3 }; // arrays decay to pointers
int **ptrToArrOfPtrs = arrOfPtrToStartOfArrays;
void f(int **pp)
{
for(int pi=0; pi<3; pi++) // iterate the pointers in the array
{
int *p = pp[pi]; // pp element is a pointer
// iterate through the ints starting at each address
// pointed to by pp[pi]
for(int i=0; i<2; i++) // two ints in each arr
{
printf("%d ", pp[pi][i]); // show double indexing of array of pointers
// Since pp[pi] is now p, we can also say:
printf("%d\n", p[i]); // index int pointer
}
}
}
int main()
{
f(ptrToArrOfPtrs);
}
f iterates through an array of pointers. It thinks that the value at that address, and at the subsequent addresses, are pointers! That is what the declaration int **pp means.
Now if we pass the address of an array full of ints instead, f will still think that the memory there is full of pointers. An expression like int *p = pp[i]; above will read an integer number (e.g., 1) and think it is an address. p[i] in the printf call will then attempt to access the memory at address 1.
Let's end with a discussion of why the idea that one should pass a 2-dimensional array as a pointer to a pointer is so common. One reason is that while declaring a 2-dimensional array argument as void f(int **arr); is dead wrong, you can access the first (but only the first) element of it with e.g. int i = **arr. The reason this works is that the first dereferencing gives you the first sub-array, to which you can in turn apply the dereferencing operator, yielding its first element. But if you pass the array as an argument to a function it does not decay to a pointer to a pointer, but instead, as discussed, to a pointer to its first element.
The second source of confusion is that accessing elements the array-of-pointers uses the same double-indexing as accessing elements in a true two-dimensional array: pp[pi][i] vs. arr[i][j]. But the code produced by these expressions is entirely different and spells disaster if the wrong type is passed. Your compiler warns about that, by the way.
Can we directly insert a 1D array to a 2D array?
For example I have this code:
void insert(int[]data , int**collection)
{
collection[1] = data
}
int main()
{
int data[2]= {1,3}
int collection[2][2];
insert(data,&collection);
}
Will this work?
You cannot insert a 1D array to 2D array the way you are doing. Use memcpy to copy the elements of 1D array to 2D array, like this:
memcpy(collection[1], data, 2 * sizeof(int));
this will copy the 2 integer elements of data array to collection[1].
Besides, a couple of problems in your code. Lets discuss them:
First:
insert(data,&collection);
^
You don't need to pass the address of collection. Note that, an array, when used in an expression, will convert to pointer to its first element (there are few exceptions to this rule). That means, when you pass collection, it will convert to type int (*)[2]. Just do:
insert(data, collection);
Second:
void insert(int[]data , int**collection)
int[]data is wrong. The first parameter of insert() should be int data[2] or int data[], both are equivalent to int * data. You can use either of them.
The second argument to insert() is collection array which is a 2D array of integers. When you pass it to insert(), it will decay to pointer whose type is int (*)[2]. The type of second parameter of insert() is int ** which is not compatible with the argument that you are passing to insert() function. The second parameter of insert() function should be int collection[2][2] or int collection[][2], both are equivalent to int (*collection)[2].
Putting these altogether, you can do:
#include <stdio.h>
#include <string.h>
#define ROW 2
#define COL 2
void insert(int data[ROW], int collection[ROW][COL]) {
//for demonstration purpose, copying elements of data array
//to all elements (1D array) of collection array.
for (int i = 0; i < ROW; ++i) {
memcpy(collection[i], data, COL * sizeof(int));
}
}
int main(void) {
int data[COL] = {1, 3};
int collection[ROW][COL];
insert(data, collection);
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
printf("collection[%d][%d] : %d ", i, j, collection[i][j]);
}
printf("\n");
}
return 0;
}
Output:
# ./a.out
collection[0][0] : 1 collection[0][1] : 3
collection[1][0] : 1 collection[1][1] : 3
I am exploring pointer "mechanics" in C/C++. I try to understand if and how is possible to implement a 2D matrix using two pointers (one for "rows" and one for "columns") instead of a single double pointer. I am aware that a matrix with rows*columns number of values could be stored in memory sequentially, but i am looking to comprehend deeper the mechanics of pointers and eventually to implement a function similar to
int value=getValue(vectorNr,vectorValue)
that is able to "simulate" the construct
value=Matrix[vectorNr][vectorValue]
vectorPointer vectorValue
| AddressV1 |------|valAddr11 valAddr12 valAddr13 |
| AddressV2 |------|valAddr21 valAddr22 valAddr23 |
| AddressV3 |------|valAddr31 valAddr32 valAddr33 |
I tried to begin writing a code like this but I quickly get stuck on pointer arithmetic and address offsetting. I also might chose a very dirty approach so any comment is welcome.
CODE TO IMPLEMENT A 2D ARRAY WITH POINTERS (BUT NOT USING DOUBLE POINTERS). To avoid confusion between rows and columns I refer to "Vectors as rows" and "Columns as vector values"
int vectorsNumber = 3; //Number of Vectors
int valuesNumber = 3; //Number of values stored in one Vector
//Addresses of Vectors. Since Vectors holds a reference to set of values, vectorPointer will hold an address for every set.
void* vectorPointer = malloc(vectorsNumber *sizeof(void*));
//Populating the vectorPointer with the address generated by allocating memory for every set of values
for (int i = 0; i < vectorsNumber; i++)
{
vectorPointer = (int*)malloc(valuesNumber * sizeof(int)); //Values shall be of int types
vectorPointer++; //ILLEGAL since cannot perform arithmetic on pointers of type void. What do do??
}
//Restore the initial address. In any case...ILLEGAL arithmetic. What do do??
for (int i = 0; i < vectorsNumber; i++)
{
vectorPointer--; //Restore the initial address. In any case...ILLEGAL arithmetic.
}
//Declaring the pointer to hold the address of one value. Memory was already allocated before
int* valueAddress;
for (int j = 0; j < vectorsNumber; j++)
{
//Getting the address of the first value of the first Vector
valueAddress = (int*)vectorPointer; //Is this casting valid in C language?
//Populating the value with whatever operation
for (int k = 0; k < valuesNumber; k++)
{
*valueAddress = (k + 1)*(j + 1); //populate the Vector with int values
}
vectorPointer++; //Switch to next Vector.ILLEGAL arithmetic
}
Actually, you only need one pointer. One way of doing it is by allocating enough memory to hold all the values, and then have functions that map the x/y values in the array to the respective memory location. Assume we want those to be the dimensions and our array variable:
int dimX = 10, dimY = 5;
int *array;
You can set a value this way:
void arraySet(int value, int x, int y) {
array[x + dimX * y] = value;
}
And get a value this way:
int arrayGet(int x, int y) {
return array[x + dimX * y];
}
Allocate the memory beforehand such as in the main function:
array = malloc(sizeof(int)*dimX*dimY);
Use it like this:
arraySet(123, 9, 3); // sets the value of [9, 3] to 123
printf("Memory at 9, 3 is %d\n", arrayGet(9, 3));
This "two pointers" idea doesn't make any sense and the code you posted cannot be salvaged. What you should do instead is to use a pointer to a 2D array:
int (*ptr)[x][y] = malloc(sizeof *ptr);
...
free(ptr);
That's it. However, a pointer to a 2D array is cumbersome, since we have to de-reference it before accessing the actual array. That is, we'd end up writing (*ptr)[i][j] = ...; which is ugly.
To dodge this, we can instead still allocate a 2D array, but instead of pointing at "the whole array", we point at the first element, which is a 1D array:
int (*ptr)[y] = malloc( sizeof(int[x][y]) );
...
ptr[i][j] = ... ; // more convenient syntax for access
...
free(ptr);
More info: Correctly allocating multi-dimensional arrays
You can simulate int a[2][3]; with
one dimensional array and index computing:
int* matrix = (int*) malloc(6 * sizeof(int));
int get_matrix_2_3(int* matrix, int i, int j) { return matrix[3 * i + j]; }
2-dimensional array:
int** matrix = (int**) malloc(2 * sizeof(int*));
for (int i = 0; i != 2; ++i) {
matrix[i] = (int*) malloc(3 * sizeof(int));
}
matrix[1][2] = 42;
I'm trying to figure out how to loop through a 2 dimensional array as a single dimensional array. Since a 2 dimensional array will occupy continuous memory, is there a way to address the two dimensional array as a single dimensional array by changing the index by 4 bytes. I'm assuming an integer array. Could some one provide an example? I tried the following but it doesn't work:
for (int i = 0; i < 2; i++){
for (int j = 0;j < 2; j++){
z[i][j] = count;
count++;
}
}
for (int i = 0; i < 4; i++)
printf("%d\n", z[i]);
2D arrays can be iterated through in a single loop like this:
#include <stdio.h>
int main()
{
int a[2][2], *p;
a[0][0] = 100;
a[0][1] = 200;
a[1][0] = 300;
a[1][1] = 400;
p = &a[0][0];
while(p!=&a[0][4])
printf("%d\n", *p++);
return 0;
}
Remember that an array index is just an offset from the first element of the array, so there is no real difference between a[0][3] and a[1][1] - they both refer to the same memory location.
Access 2D arrays like this
int *array; // note one level of pointer indirection
array = malloc(width * height * sizeof(int)); / allocate buffer somehow
for(y=0;y<height;y++)
for(x=0;x<width;x++)
array[y*width+x] = 0; // address the element by calculation
In three dimensions
int *array; // note one level of pointer indirection
array = malloc(width * height * depth * sizeof(int)); / allocate buffer somehow
for(z=0;z<depth;z++)
for(y=0;y<height;y++)
for(x=0;x<width;x++)
array[z*width*height + y*width+x] = 0; // address the element by calculation
Generally it's easier to use flat buffers than to mess around with C and C++ convoluted rules for multi-dimensional arrays. You can also of course
iterate through the entire array with a single index. If you want to set
up a 2D array, then cast the array to a single pointer, it behaves the
same way.
#define HEIGHT 50
#define WIDTH 90
int array2D[HEIGHT][WIDTH}:
int * array = reinterpret_cast<int *>(array2D):
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int arr[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
void my_fun(int(*a)[],int m,int n)
{
for(int i=0;i<m*n;i++)
{
printf("%d\n",(*a)[i]);
}
}
int main()
{
my_fun(arr,3,4);
return 0;
}
This question already has answers here:
Manipulate multidimensional array in a function
(4 answers)
Closed 8 years ago.
I'm learning pointers, and gotten stuck for an hour now, with this code,
#include <stdio.h>
int determinant(int **mat) /* int mat[3][3] works fine.. int *mat[3] doesn't.. neither does int *mat[] */
{
int det;
int a=*(*(mat+0)+0); // printf("\n%d",a);
int b=*(*(mat+0)+1); // printf("\n%d",b);
int c=*(*(mat+0)+2); // printf("\n%d",c);
int d=*(*(mat+1)+0); // printf("\n%d",d);
int e=*(*(mat+1)+1); // printf("\n%d",e);
int f=*(*(mat+1)+2); // printf("\n%d",f);
int g=*(*(mat+2)+0); // printf("\n%d",g);
int h=*(*(mat+2)+1); // printf("\n%d",h);
int i=*(*(mat+2)+2); // printf("\n%d",i);
det = a*(e*i-h*f) - b*(d*i-g*f) + c*(d*h-e*g);
return det;
}
int main()
{
int mat[3][3];
int i,j;
printf("Enter the 3 X 3 matrix:\n\n");
for (i=0;i<3;i++)
{
for (j=0;j<3;j++)
{
scanf("%d",*(mat+i)+j);
}
}
printf("\nThe determinant of the given 3 X 3 matrix is %d",determinant(mat));
return 0;
}
I don't think anything is wrong with the function call. Maybe the problem is while accepting the arguments. Idk, isn't mat a pointer to an 1-dimensional array, which would again be a pointer to the array element, making mat a pointer to a pointer?
When I print some text at places (just to check), i find that the execution goes till after int det in the function, and the program crashes in the next step.
mat [3][3] works well, but i wanna use some * there, because as i said, i'm 'learning'..
Please help!
Thanks :)
The correct prototype for your function is
int determinant(int mat[][3]);
or
int determinant(int (*mat)[3]);
(both are equivalent because of a special rule for arrays as function arguments)
Then you can simply access your matrix elements with something like mat[i][j].
This is because 2 dimensional array and pointer to pointer are not same.
No matter how much dimension does an array have, its 1 dimensional in actual memory. So we can access it serially.
#include <stdio.h>
#include <conio.h>
int determinant(int *matrix1stMember)
{
int a, b, c, d, e, f, g, h, i;
a = *(matrix1stMember + 0);
b = *(matrix1stMember + 1);
c = *(matrix1stMember + 2);
d = *(matrix1stMember + 3);
e = *(matrix1stMember + 4);
f = *(matrix1stMember + 5);
g = *(matrix1stMember + 6);
h = *(matrix1stMember + 7);
i = *(matrix1stMember + 8);
return ( a*(e*i-h*f) - b*(d*i-g*f) + c*(d*h-e*g) );
}
int main()
{
int matrix[3][3]; // int matrix[y][x]; not [x][y]
int i, j;
printf("\nEnter 3x3 Matrix : ");
for(j = 0; j < 3; j++)
{
for(i = 0; i < 3; i++)
{
scanf("%d", &matrix[j][i]);
}
}
// call function determinant(int*) using first member of array
printf("\nDeterminant = %d", determinant(&matrix[0][0]));
getch();
return 0;
}
If we have to access via row and column then we can do following
data = *(_1stMemberofArray + rowIndex*totalColumn + columnIndex);
For Example,
data = matrix[2][1];
where datatype of matrix is
int matrix[3][3];
is identical to.
data = *(matrixPointer + 2*3 + 1);
where 3 is total column 2 is row(vertical or y) and 1 is column(horizontal or x).
and datatype of matrixPointer is,
int* matrixPointer;
and it should point to first member of matrix;
2D array dont decay to pointer to pointer. You can decay them to pointers so your code should look like
int determinant(int *mat) {
int det;
int a=*((mat+0)+0); // printf("\n%d",a);
int b=*((mat+0)+1); // printf("\n%d",b);
int c=*((mat+0)+2); // printf("\n%d",c);
int d=*((mat+1*3)+0); // printf("\n%d",d);
int e=*((mat+1*3)+1); // printf("\n%d",e);
int f=*((mat+1*3)+2); // printf("\n%d",f);
int g=*((mat+2*3)+0); // printf("\n%d",g);
int h=*((mat+2*3)+1); // printf("\n%d",h);
int i=*((mat+2*3)+2); // printf("\n%d",i);
det = a*(e*i-h*f) - b*(d*i-g*f) + c*(d*h-e*g);
return det;
}
The above code is just for illustration, showing how 2-D array decays to 1-D array.
When you try to access the array using braces like a[2][1] then compiler does is unfolding for you. By unfolding I mean, the multiplication by sizeof(type) (as shown above multiply by 3). So if you decaying to 1-D you have to do it yourself.
One more thing to add, always pass the size of the dimension to the function who is has to tread the 1-D array as 2-D. like
int determinant(int *mat, int cols, rows);
Edit 1:
Just to add that #JensGustedt ans is also ok if you want to keep the arrays intact across function calls.
The correct signature for the function would be
int determinant(int mat[][3])
or
int determinant(int (*mat)[3])
In the context of a function parameter declaration, T a[] and T *a are exactly equivalent.
With either option, you can subscript mat normally in the function as you would in main:
int a = mat[0][0];
int b = mat[0][1];
...
Since a subscript operation implicitly dereferences the pointer (a[i] == *(a + i)),
you don't have to do the explicit dereference dance, making your code easier to read and understand (and potentially faster; I've seen some compilers generate more instructions for *(*(a + i) + j) than a[i][j], but don't rely on that being true everywhere).
Remember that when an expression of "N-element array of T" appears in most contexts, it is converted to an expression of type "pointer to T" and its value is the address of the first element in the array. Since the expression mat in the call to printf has type "3-element array of 3-element arrays of int", it is replaced with an expression of type "pointer to 3-element array of int".
If we pass a multidimensional array to a function:
int a2[5][7];
func(a2);
We can not declare that function as accepting a pointer-to-pointer
func(int **a) /* WRONG */
{
...
}
The function ends up receiving a pointer-to-an-array, not a pointer-to-a-pointer.