Difference between int* a and int (*a)[N] in functions? - arrays

I can pass int arrays to both of these functions (1d and 2d arrays). What is the difference between them? With the second function you need to specify the size of the array. Why?
void foo(int *a, int cols)
void bar(int (*a)[N])
I have a program where I want to pass 2d int arrays to functions. Which is the better one to use and does it matter?

There are significant differences difference between these methods for 2D matrices
in the first method you pass a pointer to int, which is not the proper type for the matrix, even after implicit decaying.
cols is an int argument in the first prototype, whereas it is a constant N in the second one. In both cases, the number of rows is not specified, so it must be implicit, either because it is constant or because the matrix is square.
You will need to write the index computations explicitly in the first case and you can use a[row][col] in the second, which will be simpler, more readable and compile to more efficient code.
Note that since C99, there is a 3rd possibility allowing you to use the array syntax even for a variable number of columns. Here is an example:
#include <stdio.h>
#include <stdlib.h>
void init_matrix(int rows, int cols, int (*a)[cols]) {
int x = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
a[r][c] = x++;
}
}
}
void print_matrix(int rows, int cols, const int (*a)[cols]) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
printf("%3d%c", a[r][c], " \n"[c == cols - 1]);
}
}
}
int main() {
int cols = 4, rows = 3;
int (*a)[cols] = malloc(sizeof(*a) * rows);
init_matrix(rows, cols, a);
print_matrix(rows, cols, a);
return 0;
}

Difference between int* a and int (*a)[N] in functions?
While int* a is a pointer to int, int (*b)[N] is a pointer to an array of N ints. These are different types, and are not compatible.
b can only point to an array of N ints while a can point to an int wether it's in an array or not. When you pass an array as argument you are really passing a pointer to its first element, it's commonly said that it decays to a pointer. Another difference is that if you increment b it will point to the next block of N ints whereas if you increment a it will just point to the next int.
I have a program where I want to pass 2d int arrays to functions. Which is the better one to use and does it matter?
It matters, for foo, it hints to a flat array with cols width, of course with some arithmetic you can treat it as a 2D array, bar is a more natural use for a 2D array.
The memory layout will probably be the similar, and using a flat array to store elements in such a way that you can use it as a 2D array is perfectly fine. I personally find it less messy and more clear to use a pointer to array, instead of pointer to int, when I need a 2D array.
Example:
#include <stdio.h>
#include <stdlib.h>
#define N 5
#define M 5
void bar(int (*a)[N]) {
// prints 20, 4 bytes * 5 (can be different deppending on the size of int)
printf("Size of 'a' is %zu\n\n", sizeof *a);
// populate the array
int c = 1;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
a[i][j] = c++;
for(int i = 0; i < N; i++){
printf("a[%d][0] = %2d\n", i, **a);
// incrementing 'a' will make it point to the next array line
a++;
}
putchar('\n');
}
Output:
Size of a is 20
a[0][0] = 1
a[1][0] = 6
a[2][0] = 11
a[3][0] = 16
a[4][0] = 21
int main() {
int(*a)[N] = malloc(sizeof *a * M);
bar(a);
// prints the complete array
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
printf("%2d ", a[i][j]);
}
putchar('\n');
}
free(a);
}
In this code a is a 2D array N x M which is passed to bar to be populated. I added some handy prints and comments for clarification. See it live: https://godbolt.org/z/1EfEE5ed7
Output:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

With the second function you need to specify the size of the array. Why?
You don't have to specify the entire size of the entire 2D array, but you do have to specify the number of columns, i.e. the size of the sub-array.
The reason why the compiler must know the size of the sub-array is that this information is required for offset calculations.
For example, if you define a 2D array like this
int arr[2][4];
then the array elements will be stored in memory in the following order:
arr[0][0]
arr[0][1]
arr[0][2]
arr[0][3]
arr[1][0]
arr[1][1]
arr[1][2]
arr[1][3]
If the compiler wants to for example access arr[1][2], it will need to know how many columns there are per row, i.e. how big each sub-array is. If the compiler does not know that there are 4 columns per row, then the compiler has no way of knowing where to find arr[1][2]. However, if the compiler knows that there are 4 columns per row, it will know that the 5th element of the 2D array is the start of the second row, so it will know that arr[1][2] is the 7th element of the 2D array.
I can pass int arrays to both of these functions (1d and 2d arrays).
Although accessing a 2D array as a 1D array may work on most compilers, it is undefined behavior according to the ISO C standard. See this question for further information:
One-dimensional access to a multidimensional array: is it well-defined behaviour?
Which is the better one to use and does it matter?
The first one is better in the sense that it allows you to specify the number of columns at run-time, whereas with the second one, the number of columns must be set at compile-time, so you are less flexible.
However, as stated above, depending on your compiler, it may not be safe to access a 2D array as a 1D array. Therefore, it would probably be best to pass 1D arrays to the first function and 2D arrays to the second function.
However, it is not clear how the second function is supposed to know how many rows the 2D array contains, since this information is not passed to the function as an argument. Maybe the function is assuming a fixed number of rows, or maybe it is not intended to be used for 2D arrays at all. The information that you have provided in the question is insufficient to answer this.

Related

Globally defining an array with unknown dimensions

I am trying to globally define a multidimensional array. The dimensions will ultimately depend on some other computations. Here I'll just consider n and B to be 5 but I place them inside function2 to stress that the dimensions are not known initially. At some point I'll also need to duplicate this array. The code below gives the error Subscripted value is not an array, pointer, or vector on the line where I'm printing the array2 entries. How can I fix this error and is there anything else I need to change to accomplish this?
int n,B;
double ** array;
double ** array2;
void function(){
double array[n][B][n];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= B; j++){
for(int k = 1; k <= n; k++){
array[i-1][j-1][k-1] = i*j*k;
}
}
}
}
void function2(){
n=5;
B = 5;
function();
array2 = array;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= B; j++){
for(int k = 1; k <= n; k++){
printf("%lf",array2[i-1][j-1][k-1]);
}
}
}
}
int main(){
function2();
return 0;
}
Oops... I am trying to globally define a multidimensional array. The dimensions will ultimately depend on some other computations... Don't. At least do not try that in C language. Arrays are not first class citizens in C, not speaking of multi-dimensional ones. Said differently AFAIK, there is no way in C to declare a multi-dimensional array where all dimensions but the last one are not compile time constants.
But there are another problems in your code: double ** array; at global level declares a pointer to pointer (or a pointer to array) which is a totally different animal than a multi-dimensional array. And double array[n][B][n]; (wrongly) declares a totaly independant multi-dim. array, hiding the global symbol.
So my advice is:
avoid if possible globaly defined variables. There are indeed correct use cases but most of the time, it is cleaner to pass them as parameter of functions, possibly inside structs
make your choice between a multi-dimensional array and an array of pointers. The former is a consecutive containers where all dimensions but the last have to be constant, the latter if much more versatile, because each row could have a different size. But it is slightly more complex to declare and slightly less efficient.
int a1[5], a2[6], a3[7];
int **parray = {a1, a2, a3};
elt_i_j = parray[i][j];
do not forget about the good old idiom allowing to see a 1-D array as a multi-dim one:
size_t size1, size2, size3;
// compute the sizes...
int *array = malloc(size1, size2, size3);
elt_i_j_k = array[k + size2 * (j + size1 * i)]
Good luck in learning C arrays...
First note that in function2 :
function();
array2 = array;
array refers to the global variable, while function initialized its local variable array and not the global one. So array and array value NULL
Subscripted value is not an array, pointer, or vector
array2 is only known as double ** array2; so array2[i-1][j-1][k-1] cannot be resolved because it needs at least the last two dimensions. Note also it is strange to use a double pointer for a 3D array.
If you want to use array2 supposing it is in fact double array2[n][B][n] you can cast it as double (*)[B][n], but in your code array2 is NULL. Or of course you have array2 as a double * and you compute yourself the right offset to access the double you want
First thing, arrays in C are stored in contiguous memory locations. So if you do not provide the number of rows or the number of columns, how will the compiler know how many rows and columns there are?
So, you have to specify the rows and columns at the start.
However, you can have some workaround. Refer to this Initializing Arrays in C/C++ With Unknown Size
There are few issues in the code which you should have a look at:
functions() has a local declaration of array2. So,
double ** array2;
and
array2 = array;
are different.
You can't assign arrays in C. You can copy them with the memcpy() function, declared in string.h as follows:
memcpy(&array2, &array, sizeof array2);
array2 is declared as double ** array2; so array2[i-1][j-1][k-1] cannot be resolved.
Happy coding!

Array without the use of [] index operator [duplicate]

I am trying to print a 2D matrix with using [], instead I want to use * like a pointer.
So with a 1 D array I'd do: *(arr+i) for example.
What's the syntax used to replace in matrix[][] ?
Here's the code:
for (i = 0; i < size; i++)
{
for (j = 0; j < (size * 2); j++)
{
printf(" %5d", matrix[i][j]);
}
printf("\n");
}
P.S,
I did try several things like:
*(matrix+i+j);
*(matrix+i)+*(matrix+j);
Of course none of that worked.
Thank you for your help and time!
Use the * two times. Each of * will basically replace one []:
*(*(matrix+i)+j)
You can try this-
*(*(matrix+i)+j) //reduce level of indirection by using *
This may depend on how matrix was allocated or passed to a function.
int A[10][15];
This uses a contiguous block of memory. To address the elements without using array notation use:
A +(i*15)+j // user694733 showed this is wrong
((int *)A)+(i*15)+j // this is horribly ugly but is correct
Note the 15, as each row consists of 15 elements. Better solutions are presented in other answers here.
In the following:
int *A[10];
A is an array of 10 pointers to ints. Assuming each array element has been allocated using malloc, you address the elements without using array notation as:
*(A+i) + j;
that is, you take A, then take the ith element, dereference that and add j as the second index.
--EDIT--
And to be complete:
int foo(int *p)
here a function just receives a pointer to zero or more ints. The pointer points to a contiguous, linear block of memory into which you can place an n-dimensional array. How many dimensions there are and the upper bound of each dimension the function can only know through parameters or global variables.
To address the cells of the n-dimensional array, the programmer must calculate the addresses him/herself, using the above notation.
int foo3(int *m, int dim2, int dim3, int i, int j, int k)
{
int *cell = m + i*dim3*dim2 + j*dim2 + k;
return *cell;
}

how to Pass 2D array without size into function in C

The Question given to me specifically says that a functions takes an integer 2d array and size as parameters. That means,
1) im not allowed to define the size of the array at the declaration.
2) I have to pass the number of rows and cols into the function.
I did it for 1D array previously and it worked, however in the 2D array case it gives a syntax error. I made test codes to check the logic of the syntax. This is the 1D array logic that works.
Also this module requires me only to use stido.h library in C. The reason for passing the size of array size is to fill the array in a different function where the loop conditions will take the array size to go through indexes
#include<stdio.h>
void print(int table[],int r);
int main()
{ int r=7,table[r];
print(table,r);
}
void print(int table[],int r)
{ printf("table rows is%d\n",r);
}
However this same logic doesnt work for when I try with a 2D array.(gives a syntax error)
#include<stdio.h>
void print(int table[][],int c,int r);
int main()
{int c=7,r=7,table[c][r];
print(table,c,r);
}
void print(int table[][],int c,int r)
{printf("table rows is\ntable cols is\n",r,c)
}
Can someone kindly explain why this is happening, and suggest a solution for this problem. ?
Thanks in advance
You can't have a 2D array with unspecified dimensions. However, it seems that you have a C99+ compiler and therefore can use a variable-length array. However, you need to reorder the arguments too.
Notice that I use size_t here instead of int for the indices/dimensions - as one might have a table (though unlikely) that has more elements than is possible to represent with an int.
#include <stdio.h>
#include <stdlib.h>
void print(size_t, size_t, int [*][*]);
int main(void) {
size_t c = 7, r = 9;
int table[c][r];
print(c, r, table);
}
void print(size_t c, size_t r, int table[c][r]) {
printf("table rows is %zu\ntable cols is %zu\n", r, c);
}
It compiles in C99, (and those C11 compilers that support the optional VLA extension); and when run, it prints
table rows is 9
table cols is 7
First, you want to know why this isn't possible. It's not allowed by the language standard and the technical reason for this is the compiler cannot calculate offsets into the array when a second dimension isn't known.
A 2D array is just like a 1D array a set of values in memory one after the other. It is not, like in some other languages, an array of arrays. With a 2D array like int a[5][3], you have 5 times 3 ints in a row, all in all 15 ints. For accessing an element, the compiler will compute the offset for you, so if you write e.g. a[2][2], this is the 2*3 + 2th element (there are two rows of 3 columns to skip for the beginning of the third row).
If the compiler doesn't know the second dimension, this calculation of offets is impossible.
Antti Haapala's answer already shows how you can get around this using the C99 feature variable length arrays. That's a good approach, but unfortunately, with C11, this feature is optional, so there may be compilers not supporting it. If you're sure to only use compilers supporting VLAs (which is the great majority of all modern C compilers), go with the code from this answer.
When passing an array to a function, instead of the array, a pointer to its first element is passed (the array decays as a pointer). So the following declarations are the same:
void print(size_t n, int arr[]);
void print(size_t n, int *arr);
With that knowledge, you could be tempted to write it differently and do the offset calculations yourself:
void print(size_t r, size_t c, void *data)
{
int *arr = data;
// access arr[2][2]:
int v = arr[2*c + 2];
}
And indeed, this is very likely to work, but be aware this is undefined: int[] and int[][] are not compatible types. For details on this idea, see this question with two quite interesting answers. Bottom line: This kind of code will work with a very high probability. Still, to be sure, don't do it....
So, if you don't have variable length arrays, and if you don't want to rely on something not perfectly well-defined, the only other way would be to actually build an array of arrays by having an array of pointers:
int row1[3] = {0, 1, 2};
int row2[3] = {3, 4, 5};
int *rows[2] = { row1, row2 };
Then you can pass it like this:
void print(size_t r, size_t c, int **arr)
{
int a = arr[0][2]; // 2
}
Of course, this isn't a 2D array any more, it's a replacement construct that can be used in some similar fashion.
You can't pass a 2D array without a defined constant for the final dimension. (absent the C99 VLA additions). You can however change the order of your parameters in print so that r is defined before you declare table as a pointer to array of int [r], and pass table as follows, e.g.
#include<stdio.h>
void print (int c, int r, int (*table)[r]);
int main (void) {
int c = 7, r = 7, table[c][r];
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
table[i][j] = i * j + i + j;
print (c, r, table);
return 0;
}
void print (int c, int r, int (*table)[r])
{
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++)
printf (" %3d", table[i][j]);
putchar ('\n');
}
}
This method is proper for utilizing the VLA with the C99 VLA extensions.
Example Use/Output
$ ./bin/fpass2d
0 1 2 3 4 5 6
1 3 5 7 9 11 13
2 5 8 11 14 17 20
3 7 11 15 19 23 27
4 9 14 19 24 29 34
5 11 17 23 29 35 41
6 13 20 27 34 41 48
If VLA extensions are not available, you can work around that by allocating and then manually indexing 2D array as a 1D array. This works because a 2D array is an array-of-arrays sequentially stored in memory (e.g. a[2][3] is a00,a01,a02,a10,a11,a12 in memory.) To prevent any undefined behavior, you can allocate storage for table (e.g. int *p = malloc (sizeof table); copy table and then index each element calling print (p, c, r) as follows, e.g.
void print (int *table, int c, int r)
{
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++)
printf (" %3d", table[i * r + j]);
putchar ('\n');
}
}
Where table is indexed with table[i * r + j] to access each of the original elements of the 2D array. While this method is a workaround, without the VLA extensions, you would presumably have a defined constant to pass for the final array dimension making the workaround or a change in the order of parameters unnecessary.
Look things over and let me know if you have questions.
First of all, the type of your function argument decays to a pointer to the first element of the array. That is, the following declaration pairs are perfectly equivalent:
void f(int a[]);
void f(int *a);
void g(int a[][7]);
void g(int (*a)[7]);
void h(int a[][7][6]);
void h(int (*a)[7][6]);
Now, when you index into an array, that operation is in fact defined in terms of pointer arithmetic. So, the expression a[3] is in fact equivalent to *(a + 3).
In this expression, a yields a pointer to the first element of the array, and the addition adds the offset to skip three elements of the array. That is, the machine will perform this calculation: *(elementType*)((char*)a + 3*sizeof(elementType))
The crucial part in this is the sizeof(elementType): If the type of a is int[][], then the type of its elements is int[], and you cannot take the size of an array of unknown length for obvious reasons. Consequently, the types of all array dimensions except the outermost one must be known in order to be able to index into the multidimensional array.
So much for the explanation of what's going on. The consequence for you is, that you have to supply the size of the inner dimension. As the other answers have shown, this can be done by simply ordering the size arguments first, so they are available to the declaration of the array argument:
void print(int c, int r, int table[c][r]);
Or, equivalently, as the value of c is actually ignored in the declaration above:
void print(int rowCount, int columnCount, int (*table)[columnCount]) {
printf("table has %d columns and %d rows\n", columnCount, rowCount);
for(int curRow = 0; curRow < rowCount; curRow++) {
for(int curColumn = 0; curColumn < columnCount; curColumn++) {
printf("%d ", table[curRow][curColumn]);
}
printf("\n");
}
}
(I have taken the liberty to use proper formatting and variable names in this last example. Please, never use just a single character for variables names as vital as array dimension sizes.)

How do I write functions which accept two-dimensional arrays when the width is not known at compile time?

Is it possible to write a function which accept 2-d array when the width is not known at compile time?
A detailed description will be greatly appreciated.
You can't pass a raw two-dimensional array because the routine won't know how to index a particular element. The 2D array is really one contiguous memory segment.
When you write x[a][b] (when x is a 2d array), the compiler knows to look at the address (x + a * width + b). It can't know how to address the particular element if you don't tell it the width.
As an example, check http://www.dfstermole.net/OAC/harray2.html#offset (which has a table showing how to find the linear index for each element in an int[5][4])
There are two ways to work around the limitation:
1) Make your program work with pointer-to-pointers (char *). This is not the same as char[][]. A char * is really one memory segment, with each value being a memory address to another memory segment.
2) Pass a 1d pointer, and do the referencing yourself. Your function would then have to take a "width" parameter, and you could use the aforementioned formula to reference a particular point
To give a code example:
#include <stdio.h>
int get2(int *x) { return x[2]; }
int main() {
int y[2][2] = {{11,12},{21,22}};
printf("%d\n", get2((int *)y));
}
This should print out 21, since y is laid out as { 11, 12, 21, 22 } in memory.
C supports variable-length arrays. You must specify the width from a value known at run-time, which may be an earlier parameter in the function declaration:
void foo(size_t width, int array[][width]);
One way is use the good old "pointer to array of pointers to arrays" trick coupled with a single continuous allocation:
/* Another allocation function
--------------------------- */
double ** AnotherAlloc2DTable(
size_t size1, /*[in] Nb of lines */
size_t size2 /*[in] Nb of values per line */
)
{
double ** ppValues;
size_t const size1x2 = size1*size2;
if(size1x2 / size2 != size1)
return NULL; /*size overflow*/
ppValues = malloc(sizeof(*ppValues)*size1);
if(ppValues != NULL)
{
double * pValues = malloc(sizeof(*pValues)*size1x2);
if(pValues != NULL)
{
size_t i;
/* Assign all pointers */
for(i=0 ; i<size1 ; ++i)
ppValues[i] = pValues + (i*size2);
}
else
{
/* Second allocation failed, free the first one */
free(ppValues), ppValues=NULL;
}
}/*if*/
return ppValues;
}
/* Another destruction function
---------------------------- */
void AnotherFree2DTable(double **ppValues)
{
if(ppValues != NULL)
{
free(ppValues[0]);
free(ppValues);
}
}
Then all you have to do is pass a char ** to your function. The matrix is continuous, and usable as mat[x][y].
Possible accessor functions:
int get_multi(int rows, int cols, int matrix[][cols], int i, int j)
{
return matrix[i][j];
}
int get_flat(int rows, int cols, int matrix[], int i, int j)
{
return matrix[i * cols + j];
}
int get_ptr(int rows, int cols, int *matrix[], int i, int j)
{
return matrix[i][j];
}
An actual multi-dimensional array and a fake one:
int m_multi[5][7];
int m_flat[5 * 7];
Well-defined ways to use the accessor functions:
get_multi(5, 7, m_multi, 4, 2);
get_flat(5, 7, m_flat, 4, 2);
{
int *m_ptr[5];
for(int i = 0; i < 5; ++i)
m_ptr[i] = m_multi[i];
get_ptr(5, 7, m_ptr, 4, 2);
}
{
int *m_ptr[5];
for(int i = 0; i < 5; ++i)
m_ptr[i] = &m_flat[i * 7];
get_ptr(5, 7, m_ptr, 4, 2);
}
Technically undefined usage that works in practice:
get(5, 7, (int *)m_multi, 4, 2);
[Warning - this answer addresses the case where the number of columns - the WIDTH - is known]
When working with 2D arrays, the compiler needs to know the number of columns in your array in order to compute indexing. For instance, if you want a pointer p that points to a range of memory to be treated as a two-dimensional set of values, the compiler cannot do the necessary indexing arithmetic unless it knows how much space is occupied by each row of the array.
Things become clearer with a concrete example, such as the one below. Here, the pointer p is passed in as a pointer to a one-dimensional range of memory. You - the programmer - know that it makes sense to treat this as a 2D array and you also know (must know) how many columns are there in this array. Armed with this knowledge, you can write code to create q, that is treated by the compiler as a 2D array with an unknown number of rows, where each row has exactly NB columns.
I usually employ this when I want the compiler to do all the indexing arithmetic (why do it by hand when the compiler can do it?). In the past, I've found this construct to be useful to carry out 2D transposes from one shape to another - note though that generalized 2D transposes that transpose an MxN array into an NxM array are rather beastly.
void
WorkAs2D (double *p)
{
double (*q)[NB] = (double (*)[NB]) p;
for (uint32_t i = 0; i < NB; i++)
{
for (uint32_t j = 0; j < ZZZ; j++) /* For as many rows as you have in your 2D array */
q[j][i] = ...
}
}
I believe a nice solution would be the use of structures.
So I have an example for 1d-Arrays:
Definition of the struct:
struct ArrayNumber {
unsigned char *array;
int size;
};
Definition of a function:
struct ArrayNumber calcMultiply(struct ArrayNumber nra, struct ArrayNumber nrb);
Init the struct:
struct ArrayNumber rs;
rs.array = malloc(1);
rs.array[0] = 0;
rs.size = 1;
//and adding some size:
rs.size++;
rs.array = realloc(rs.array, rs.size);
hope this could be a solution for you. Just got to change to a 2d Array.

how to pass 1D and 2D array arguments to a function in c

Suppose I have a function, int function(int N, int c[N]){...}, taking as parameters an integer and an array. Suppose now I have a double array **c of size 'N times 2' and suppose, I want to apply the function function to one column of the double arrow, c[i][0], i varying from to N-1. How am I supposed to use this function. Does it looks like something like function(N,*c[0]) ?
Does anyone can help ?
An array in C always decays to a pointer to its first element when passed into a function. This is good to know in some situations.
As an example, you could write
int list[10];
func (int *x) {
int i;
for (i = 0; i < 10; i++) {
printf("%d", x[i]);
}
}
x[i] is really just syntactic sugar. In C, when you use bracket notation to access an element of an array, it gets converted to *(x + i), where x is the name of the array.
This works because of pointer arithmetic. If x is the name for an array of 10 integers, then the value of x in an expression is the address of the first integer of the array.
x + i will always point to the i-th element after x (C takes into account the size of the element type stored in the array, and increments the pointer accordingly).
Thus, when passing 2d arrays, the array decays to a pointer to its first element - which is an array.
A function signature taking a 2d array can be written as
func(int x[][columns] {
...
}
// but could also be written as
func(int (*x)[columns]) {
...
}
which indicates that x is a pointer to an array of integers.
Sometimes you need to write a function to accept a 2 dimensional array where the width is not known until run time. In this case, you can pass a pointer to the [0][0] element and also pass the two dimensions, and then use pointer arithmetic to get the right element. For example,
print_2d_array (int *x, height, width) {
int i, j;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
printf("%d", x[i * width + j]);
}
}
}
int list[10][10];
print_2d_array (&list[0][0], 10, 10);
would work for a dynamically allocated 2d array.
In c langauge, for single dimentional array you no need to mention the size of the array in the function arguments while passing an array to that function.
If it is a single dimentional array
...
int a[10];
func(10, a);
...
void func(int size, int x[]) //no need to mention like int x[10]
{
//here x is not an array. Its equivalent to int *
printf("%d", sizeof(x)); // this will print 4 or 8 not 40
}
If it is 2D array
...
int a[10][5];
func (10, a);
...
void (int rows, int x[][5]) //here int x[][] is invalid
{
}

Resources