How to pass unbound multidimensional array? - c

Is there any way to pass a multidimensional array to a function without knowing the no of columns.... I mean say I want to print a multidimensional array say a[][9] and b[][3]. If I make a common function say print.
// I have to specify the no of columns right and since
// the no of columns should be same for both actual and
// formal arguments
void print(int a[][])
I have to make different functions for different multidimensional arrays. There should be some way around it.
How to pass unbound multidimensional array?

You have to include all of the array dimensions, except the innermost one (although you probably do want to give the innermost one anyway, so that your function knows when to stop printing). If the dimension is not known at compile time then you can make it a parameter to the function:
void print(size_t m, size_t n, int a[m][n])
{
for ( size_t i = 0; i < m; ++i )
for ( size_t j = 0; j < n; ++j )
printf("%d\n", a[i][j]);
}
Calling the function:
int main(void)
{
int a[][4] = { { 0, 1, 2, 3 }, {8, 7, 6, 5}, {11, 10, 12, 9} };
print(3, 4, a);
return 0;
}

Matt McNabb's answer shows how to use the C99 or C11 variable-length array facilities. There is an alternative that will work with C89 too (which might be a factor if you code on Windows with MSVC), but you still have to tell the function about both dimensions of the array, and you have to do the subscript calculations yourself:
void print(size_t m, size_t n, int *a)
{
size_t i;
size_t j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
printf(" %d", a[i * n + j]);
putchar('\n');
}
}
You might call this as:
int main(void)
{
int a[][4] = { { 0, 1, 2, 3 }, {8, 7, 6, 5}, {11, 10, 12, 9} };
print(3, 4, &a[0][0]);
return 0;
}
Sample output:
0 1 2 3
8 7 6 5
11 10 12 9
(One minor comment: I'm not certain that the automatic array could be initialized like that in C89 — there were some restrictions still on automatic variable initialization. If it doesn't work, simply move the entire array declaration outside of main() and prefix it with static so it becomes a file scope array.)

Related

How to find a missing value in an array? [duplicate]

This question already has answers here:
Why sizeof(param_array) is the size of pointer?
(8 answers)
Closed 9 months ago.
I am trying to find the smallest missing element of an array using function check, which has two arguments (n and array A). I can't understand why my function check is always returning one and the while loop is never closing.
#include <stdio.h>
bool check(int n, int A[])
{
for (int i = 0; i < sizeof(A); i++)
{
if(A[i] == n)
{
return 1;
}
}
return 0;
}
int main()
{
int A[] = {1, 3, 6, 4, 1, 2};
int n = 1;
while (check(n, A) == 1)
{
n++;
}
printf("%d is missing",n);
}
The compiler adjusts a parameter having an array type to pointer to the array element type.
So this function declaration
bool check(int n, int A[])
is equivalent to
bool check(int n, int *A );
And within the function the expression sizeof(A) is equivalent to the expression sizeof( int * ) and is equal to either 4 or 8 depending on the used system.
Thus this for loop
for (int i = 0; i < sizeof(A); i++)
invokes undefined behavior.
I know but still that's not why the while loop is never stopping.
Answering your above comment it seems that in the used system sizeof( int * ) is equal to 8 and the variable n is placed in memory after the array A as they defined in main
int A[] = {1, 3, 6, 4, 1, 2};
int n = 1;
As a result you get the infinite wile loop because in the for loop within the function the memory occupied by the variable n is checked and n is always equal to itself.
Thus the function always returns 1.
That is in the for loop the array is traversed as it has 8 elements like
int A[] = {1, 3, 6, 4, 1, 2, n, some_indeterminate_value };

I need a straightforward example of passing an 2D array to a function in C

I would like to create a C function that takes a 2D array of doubles as a parameter and operates on that array via indexing, e.g. printf("%f ", array[i][j]).
What I've been able to piece together from various examples and SO questions is something like this:
void printArray(double **array, int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%f ", array[i][j]);
}
printf("\n");
}
}
In main, I'm able to successfully print the array like so:
int i, j, k = 0, m = 5, n = 6;
double **a = malloc(m * sizeof(*a));
//Initialize the arrays
for (i = 0; i < m; i++)
{
a[i] = malloc(n * sizeof(*(a[i])));
}
for (i = 0; i < m; i++)
{
for (j = 0; j<n; j++)
{
k++;
a[i][j] = k;
}
}
printArray(a, m, n);
However, when I try to initialize an array to some given values and then call:
double a[5][6] = { { 1, 2, 3, 4, 5 ,6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6} };
printArray(a, 5, 6);
I am met with the following error:
Unhandled exception at 0x011514D3 in Example.exe: 0xC0000005:
Access violation reading location 0xA1F8E3AC.
Can someone explain what my mistake is and how to fix it? edited
Please note that, for the purposes of the function definition, I will know the size of the array at run time but not compile time. Also, I'm compiling on Windows with VisualStudio 2013.
double a[5][6] has type double[][6], which is not the same as double**. double** is a pointer to a pointer to a double. double[][6] is a compiler-managed data type that represents a two-dimensional array.
What's going on here is that the double[][6] you created is being silently cast to a double** in your invocation of printArray.
If your function is going to take a double**, you need to pass it a double**. You can initialize the array contents by filling each member array individually:
double row1[3] = {3, 4, 5};
a[1] = row1;
This works around the problem; because the double[] is stored by the compiler as a contiguous array of double values, casting it to double* implicitly as above is safe.
Another solution is to change the function to take a "real" double[][6], instead of a pointer-pointer. How you would do this with non-fixed-size arrays is up to your particular off-brand of C; it's not part of the C standard so far as I know.
A third solution is to build the array row by row with malloc and fill it cell by cell with a[0][0] = 1 and so forth. You already have this in your question, and it works correctly.
A final thing to be aware of is that you are allocating a on the stack: when your main function exits, accessing it will result in undefined behavior.

Passing a two dimensional array to a function in C

#include <iostream>
#include <math.h>
#include <stdio.h>
#define column 3
#define row 3
#define share 3
int matrix_multiplication(int left_matrix[][column], int right_matrix[][column], int result_matrix[][column], int rows, int cols, int shared);
int A[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
},
B[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}, C[3][3]; //initialize "hard coded" three matrices
int main() {
matrix_multiplication(A, B, C, row, column, share); //passes address of each matrix to function
return 0;
}
int matrix_multiplication(int left_matrix[][column], int right_matrix[][column], int result_matrix[][column], int rows, int cols, int shared) {
int i, j, k;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {//stays within first column and row through first iteration
for (k = 0; k < 3; k++)//ensures inner dimensions match with variable k i.e. ixk * kxj =ixj or A*B=C
result_matrix[i][j] += right_matrix[i][k] * left_matrix[k][j]; //C programming has ability to perform matrix multiplication
//Adds result of each operation to C matrix i.e. +=
printf("%d\t", result_matrix[i][j]); //matrix C is composed of rows(i) and columns(j)
}//new tab after each column iteration
printf("\n"); //new line for each row iteration
}
return 0;
}
This code is an good example of passing multidimensional arrays to a function using pointers and printing multidimensional arrays after mutliplication. There are multiple ways to indicate pointers to the compiler. I recommend seeing the "Correct way of passing a 2 dimensional array into a function." for example:
/*void display(int (*p)[numcols],int numRows,int numCols)//First method//
void dispaly(int *p,int numRows,int numCols) //Second Method//
void dispaly (int p[][numCols],int numRows,int numCols) //Third Method*/
Remove the column variable, and add this above the matrix_multiplication function declaration:
#define column 3
(You may also want to rename column to COLUMNS.)
In C++ you can also do this:
static const int column = 3;
or, in C++11:
constexpr int column = 3;
The idea behind all this is that all but the very first size of a multidimensional array must be known at compile time.
To fix the expected primary-expression before ']' token" error, change your inner assignment to something like this:
result_matrix[i][j] += right_matrix[i][k] * left_matrix[k][j];
Also you should initialize result_matrix with 0s first.
Also remove the * from int *result_matrix[][column].
Most modern compilers display warnings if you pass an int instead of an int*. Please enable all warnings in your compiler, recompile, fix them, and update your question stating that the example code compiles cleanly, without warnings.
To print an element of the matrix, you have to specify which element you want to print:
printf("%d\t", result_matrix[i][j]);
I can't believe that your compiler didn't display a warning when you omitted the [i][j]. Warnings are for your benefit: they indicate possible bugs in your code.

How to determine number of elements that are in a array in C

i'm new learning the C Languange.
I want to know the number of elements that are in a array for example
int MyArray[80] = {50, 845, 584};
n = sizeof(MyArray)/sizeof(MyArray[0]); // This will give me 80.
But I only want the number of elements that are inside of {}, As i initialized above it has 3 elements (50, 845, 584), so how do i count them by code?
Another question:
How do i create an empty array so i can add elements by myself and print all elements with a for loop, I've tried this:
int i;
int MyArray[80] = {};
MyArray[0] = 50;
MyArray[1] = 584;
MyArray[2] = 784;
for(i=0; i<=sizeof(MyArray); i++){
printf("Array Element[%d] is: %d", i, MyArray[i]);
}
But this doesn't seem to work, any help? Thanks
EDIT: i fixed it by doing the following code found in another post:
#include <stdio.h>
#define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a])
main() { int i; int numbers[] = {2, 3, 5, 7, 11, 13, 17, 19, 85};
int AllElements = NUM_ELEMS(numbers);
for(i=0; i<AllElements; i++){
printf("Element[%d] in array is: %d \n", i, numbers[i]);
}
}
If you initialize an array with fewer elements than the array is declared to hold, the remaining elements will be default-initialized. For integers, this means that they will be zeroed.
Assuming you have no zeroes in your initialization list, then, you can check how long the initialization list was by checking for the first zero in the array (up to the length of the array).
Alternately, if the array size should just be constant, you should specify the size as [], which makes it exactly as long as the initialization list and no longer.
I only want the number of elements that are inside of {}
Try
size_t n = sizeof (int[]){50, 845, 584} / sizeof (int);
An ugly way using the preprocessor:
#include <stdio.h>
#define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N
#define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)
#define init_array(arr, ...) NARGS(__VA_ARGS__); arr = {__VA_ARGS__}
int main(void)
{
int n = init_array(int my_array[80], 50, 845, 584);
printf("%d\n", n);
return 0;
}
Is expanded to:
int main(void)
{
int n = 3; int my_array[80] = {50, 845, 584};
printf("%d\n", n);
return 0;
}
Output:
3
Note that this version is limited to N elements in the initializer.

Sorting a C array based on contents of another array

I'm trying to sort an array A whose elements are indexes. The indexes refer to another array B whose value will determine the order of A. So, I would like to sort A such that B[ A[i] ] is increasing.
For example:
A = [0, 1, 4, 5, 7]
B = [5, 3, 8, 2, 2, 7, 1, 6, 3, 9]
Sorted A would be
A' = [ 7, 4, 1, 0, 5 ]
Is this possible with C's built-in sort, or am I going to have to write my own implementation?
EDIT: These arrays are local function variables.
If you want to use qsort, the best thing to-do would be to re-wrap the indexes in A and the values in B into a struct, and then make a comparator based on a new array that struct. For instance:
typedef struct
{
int index_from_A;
int value_from_B;
} index_value_wrapper;
index_value_wrapper index_wrapper_array[5];
for (int i=0; i < 5; i++)
{
index_wrapper_array[i].index_from_A = A[i];
index_wrapper_array[i].value_from_B = B[A[i]];
}
int comparitor (const void* lhs, const void* rhs)
{
return (lhs.value_from_B - rhs.value_from_B);
}
Now you can run qsort on the struct array and from there you can extract the proper sorted sequence you desired for the original array A without having to use a custom sorting function.
If you have it available, qsort_r provides a way to do this. You can give it context information in an additional parameter. That context is passed to the comparison function. You can access that additional information to extract the desired sorting information.
The Microsoft compiler has a similar one: qsort_s
I think you can use qsort and a custom comparator
int comparator(const void *x, const void *y)
{
return ( b[*(int*)x] - b[*(int*)y] );
}
Create another array C of type struct { int a_value; int b_value}, initialise each element to the values of each index of a and the value looked up from b. Sort that, traverse the sorted C copying the a_values back into A.
Viola. No, that's a large violin. Voila!
Use your rule as the comparison function to qsort (as long as B is longer than A):
#include <stdio.h>
#include <stdlib.h>
int A[] = {0, 1, 4, 5, 7};
int B[]= {5, 3, 8, 2, 2, 7, 1, 6, 3, 9};
int my_cmp(const void *a_, const void *b_,void *arg_)
{
const int *a = a_, *b = b_;
if(B[*a] == B[*b])
return 0;
else if (B[*a] < B[*b])
return -1;
else
return 1;
}
int main(int argc,char *arga[])
{
int i;
qsort(A,sizeof A/sizeof A[0] ,sizeof A[0],my_cmp);
puts("Sorted A");
for(i = 0 ; i < sizeof A/sizeof A[0]; i++) {
printf("A[%d] : %d B[A[%d]] : %d\n",i,A[i],i,B[A[i]]);
}
return 0;
}
This gives:
$ ./a.out
Sorted A
A[0] : 4 B[A[0]] : 2
A[1] : 1 B[A[1]] : 3
A[2] : 0 B[A[2]] : 5
A[3] : 7 B[A[3]] : 6
A[4] : 5 B[A[4]] : 7
Available on many platforms is also qsort_r(on linux you'll have to #define _GNU_SOURCE before including <stdlib.h> to use it. Using that, you'd change the comparison function to e.g.
int my_cmp(const void *a_, const void *b_,void *arg_)
{
const int *a = a_, *b = b_, *arg = arg_;
if(arg[*a] == arg[*b])
return 0;
else if (arg[*a] < arg[*b])
return -1;
else
return 1;
}
And call qsort_r like
qsort_r(A,sizeof A/sizeof A[0] ,sizeof A[0],my_cmp,B);

Resources