struct array function argument - c

I have the following code of declarations:
struct coord {
int x;
int y;
}
void rotateFig(struct coord[10][10]);
I need to implement rotateFig.
I tried to start with following:
void rotateFig(struct coord[10][10] c)
{
//code
}
I can`t compile it - probaly the way I transfer c in the function definition is incorrect .How should I transfer c using given signature.
Thank you

Use this definition:
void rotateFig(struct coord c[10][10])
{
//code
}
The array is the actual parameter, so the dimensions have to come after its name, not before.

Though other answers ARE enough, I prefer passing it as a pointer and passing the dimensions with it, this is more dynamic, and is the same for the //code part:
void rotateFig(struct coord**, int, int);
void rotateFig(struct coord** c, int d1, int d2)
{
//code
}

struct coord is a type and c is a variable of type struct coord which can hold 10 X 10 struct coord elements.
So it should be as follows
void rotateFig(struct coord c[10][10])
One thing to note when working with multi-dimension array in C is that it cannot be return back from a function. For details, read this. So its not advised to use the above format as C by default passes arguments by value and not by address.
So as #Mr.TAMER mentioned in his answer, you should use the following
void rotateFig(struct coord** c, int d1, int d2)
OTOH, you can use the following rotate code for your reference! It rotates a 2d array to 90 degrees!
#include <stdio.h>
#define N 10
int matrix[N][N];
void display()
{
int i, j;
printf("\n");
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
printf("%3d", matrix[i][j]);
printf("\n");
}
printf("\n");
return;
}
int main()
{
int i, j, val = 1;
int layer, first, last, offset, top;
for (i=0; i<N; i++)
for (j=0; j<N; j++)
matrix[i][j] = val++;
display();
for (layer = 0; layer < N/2 ; layer++) {
first = layer;
last = N - layer - 1;
for (i=first; i< last ; i++) {
offset = i - first;
top = matrix[first][i];
matrix[first][i] = matrix[last-offset][first];
matrix[last-offset][first] = matrix[last][last-offset];
matrix[last][last-offset] = matrix[i][last];
matrix[i][last] = top;
}
}
display();
return 0;
}
Hope this helps!

Related

how do returns a matrix in C (include code)

i defined a matrix into a function. how do i return that matrix for print it when i call it with another function. i mean...
#include<stdio.h>
#include<conio.h>
#include<time.h>
void main() {
int m,n;
printf("type 2 numbers:");
scanf("%i %i",&m,&n);
declaration(m,n);\\HERE IS THE PROBLEM
printing(matrix,m,n);
getch();
}
void declaration(int a,int b) {
srand(time(NULL));
int i,j,matrix[a][b];
for(i=0;i<a;i++){
for(j=0;j<b;j++){
matrix[i][j]=1+rand()%7;
}
}
}
void printing(int c[100][100],int a,int b) {
int i,j;
for(i=0;i<a;i++){
for(j=0;j<b;j++){
printf("%i\t",c[i][j]);
}
printf("\n");
}
}
Define it like:
typedef struct {
int rows;
int cols;
int *data;
} int_matrix_entity, *int_matrix;
int_matrix int_matrix_create(int rows, int cols, bool rand)
{
int_matrix mt;
int i;
if ((mt = malloc(sizeof(int_matrix_entity))) == NULL)
{
return NULL;
}
if ((mt->data = malloc(sizeof(int) * cols * rows)) == NULL)
{
free(mt);
return NULL;
}
if (rand)
{
srand(time(NULL));
for (i = 0; i < cols * rows; i++)
{
mt->data[i] = 1 + rand() % 7;
}
}
else
{
memset(mt->data, 0, sizeof(int) * cols * rows);
}
return mt;
}
void int_matrix_printf(int_matrix mt)
{
int i;
int j;
for (i = 0; i < mt->rows; i++)
{
for (j = 0; j < mt->cols; j++)
{
printf("%5d ", mt[i * cols + j]);
}
printf("\n");
}
}
You have a few points that require a bit more attention;
1 ) read warning and error messages given by your compiler
2 ) again, read warning messages given by your compiler
3 ) use indentation to make your code more readable.
4 ) Always return from main(), that's a good practice
The code below does what you want to achieve; have a look at it and keep on reading...
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
// You either have to declare your functions
// or implement them before main()
void declaration(int a,int b, int m[a][b]);
void printing(int a,int b, int m[a][b]);
int main(){ // always return from main()
int m,n;
printf("type 2 numbers:");
scanf("%i %i",&m,&n);
int matrix[m][n];
declaration(m, n, matrix);
printing(m, n, matrix);
return 0;
}
void declaration(int a,int b, int m[a][b]){
srand(time(NULL));
int i,j;
for(i=0;i<a;i++){
for(j=0;j<b;j++){
m[i][j]=1+rand()%7;
}
}
}
void printing(int a,int b, int m[a][b]){
int i,j;
for(i=0;i<a;i++){
for(j=0;j<b;j++){
printf("%i\t",m[i][j]);
}
printf("\n");
}
}
You need a way to transfer data from one function to another. You cannot simply declare an auto variable in one function and pass it to another as you did in the code below
declaration(m,n);
printing(matrix,m,n); /* where does matrix[][] come from? */
remember, C is a strongly typed language which means you have to declare your variables before using them. This applies to your functions as well. You either have to give your function declarations before main() (or more specifically, before using them), or implement them.
Look into your header files (i.e. .h files) and you will see lots of function declarations.
Since you use variable length arrays, make sure your compiler is at least capable of compiling code confirming C99 standard.
Some extras;
Normally, C passes arguments by value and you have to use a pointer if you want the value of your variable get changed within the function. If you have a close look at the code snippet I gave, I simply used an int m[a][b].In C, the name of an array is a pointer to its first element, hence you can change the value of array elements when actually array's name is passed to your function as an argument.
For further reading, you may want to look at
variable scope
global variables (you can define matrix[][] as a global variable and change the value of matrix elements)
declaration vs definition in C
Another simple way to do it is use double pointer to create 2-dimensional array. Keep it simple.
#include <stdio.h>
#include <stdlib.h>
int** create_matrix(int rows, int cols) {
int **matrix = malloc(rows*(sizeof(int *)));
for(int i = 0; i < rows; i++) {
matrix[i] = malloc(cols*sizeof(int));
}
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
matrix[i][j] = 1 + rand()%7;
}
}
return matrix;
}
void printing(int** matrix, int rows, int cols) {
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int main(void) {
int rows, cols;
rows = 3, cols = 3;
int** matrix = create_matrix(rows, cols);
printing(matrix, rows, cols);
free(matrix);
return 0;
}

How to declare a variable sized 2D arrays global in C?

I'm making a randomized n*n matrix, but I do not know the value of n until the program is already running.
I'm capable of creating the n*n matrices in main() like so:
double (*m1)[n];
m1 = malloc(sizeof *m1 * n);
double (*m2)[n];
m2 = malloc(sizeof *m2 * n);
But now I must use these matrices outside of main and need them to be global, but I'm completely clueless how to make them global. I intend to read these two matrices with multiple threads and need them easily accessible. I know I can make a struct to pass multiple parameters, but I would need to define a struct with variable length arrays globally so the problem rearises. Thank you for your time.
Just declare as double pointer and allocate memory in main. For more details refer this
#include <stdio.h>
int **a;
void fun(int n)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
printf("%d ",a[i][j]);
}
}
int main(void)
{
int n;
scanf("%d",&n);
a = (int **)malloc(n * sizeof(int *));
for(int i=0;i<5;i++)
{
a[i]=(int*)malloc(n*sizeof(int));
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
}
}
fun(n);
return 0;
}
Working Code : https://ideone.com/OMQ4qA
The correct, proper solution is to not use globals. Allocate the array in the thread which will persist throughout the execution of the whole program.
If that, for reasons unknown, is not an option, then you will have to come up with some solution that stores the array size globally too. You could create a simple ADT for this, such as a struct with a "mangled" 2D array in the form of a flexible array member. Example:
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
size_t x;
size_t y;
double array [];
} double_array2d_t;
double_array2d_t* array2d = NULL;
int main()
{
/* let x and y be some manner of run-time values: */
int x = 3;
int y = 2;
array2d = malloc(sizeof(*array2d) + sizeof(double[x][y]));
array2d->x = x;
array2d->y = y;
double count = 0.0;
for(int i=0; i<x; i++)
{
for(int j=0; j<y; j++)
{
array2d->array[i*y + j] = count++;
printf("%f ", array2d->array[i*y + j]);
}
printf("\n");
}
...
free(array2d);
}
And of course if you access this from multiple threads, you have to protect the data with a mutex as always.

How to pass an array of structures to a function by reference in C?

This code is similar to what I am attempting to do, however I am getting errors saying that I am passing incompatable types
#include <stdio.h>
struct numbers{
int num;
};
void fillArray(struct numbers* a[]);
int main(void)
{
struct numbers array[4];
fillArray(&array);
for(int i = 0; i < 4; i++)
{
printf("%d", array[i].num);
}
}
void fillArray(struct numbers* a[])
{
for(int i = 0; i < 4; i++)
{
a[i]->num = i;
}
}
The function parameter
void fillArray(struct numbers* a[]);
is adjusted to
void fillArray(struct numbers ** a);
On the other hand the type of the argument in this call
fillArray(&array);
is struct numbers( * )[4]. The types struct numbers ** and struct numbers ( * )[4] are incompatible.
There is no need to pass a pointer to the array because elements of the array are already passed indirectly if you will pass just the array that is implicitly converted to pointer to its first element.
So what you need is to declare and define the function like
void fillArray( struct numbers a[] )
// or
// void fillArray( struct numbers *a )
{
for(int i = 0; i < 4; i++)
{
a[i].num = i;
}
}
and call it like
fillArray( array );
Take into account that the function depends on magic number 4. It is better to define the function such a way that it could deal with arrays of various numbers of elements.
So I would define the function like
void fillArray( struct numbers a[], size_t n )
// or
// void fillArray( struct numbers *a, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
a[i].num = i;
}
}
and call it like
fillArray( array, 4 );
Here is demonstrated how the program can look in whole
#include <stdio.h>
struct numbers
{
int num;
};
void fillArray( struct numbers a[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
a[i].num = i;
}
}
#define N 4
int main(void)
{
struct numbers array[N];
fillArray( array, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", array[i].num );
}
putchar( '\n' );
return 0;
}
Its output is
0 1 2 3
To use an array with a different number of elements it is enough to change the value of the macro name N. Thus the program and its function do not depend on the magic number 4.
You probably want this:
#include <stdio.h>
struct numbers {
int num;
};
void fillArray(struct numbers a[]);
int main(void)
{
struct numbers array[4];
fillArray(array);
for (int i = 0; i < 4; i++)
{
printf("%d\n", array[i].num);
}
}
void fillArray(struct numbers a[])
{
for (int i = 0; i < 4; i++)
{
a[i].num = i;
}
}
Your function wants an array of pointers, but you have a single array, so
void fillArray(struct numbers* a);
or
void fillArray(struct numbers a[]);
Moreover using a[i] you are already dereferencing the pointer, so you need . not -> operator.
#include <stdio.h>
struct numbers
{
int num;
};
void fillArray(struct numbers *a);
int main(void)
{
struct numbers array[4];
fillArray(array);
for (int i = 0; i < 4; i++)
{
printf("%d", array[i].num);
}
printf("\n");
}
void fillArray(struct numbers *a)
{
for (int i = 0; i < 4; i++)
{
a[i].num = i;
}
}
Finally using c array decays to pointer to first item of array, so
fillArray(&array);
must be
fillArray(array);
or
fillArray(&array[0]);
Lastly you should pass size of array to your function, instead of using fixed numbers. You can do it using pointer and size
#include <stdio.h>
struct numbers
{
int num;
};
void fillArray(size_t size, struct numbers *a);
int main(void)
{
struct numbers array[4];
fillArray(sizeof(array)/sizeof(array[0]), array);
for (int i = 0; i < 4; i++)
{
printf("%d", array[i].num);
}
printf("\n");
}
void fillArray(size_t size, struct numbers *a)
{
for (size_t i = 0; i < size; i++)
{
a[i].num = i;
}
}
Or using VLAs
#include <stdio.h>
struct numbers
{
int num;
};
void fillArray(size_t size, struct numbers a[size]);
int main(void)
{
struct numbers array[4];
fillArray(sizeof(array)/sizeof(array[0]), array);
for (int i = 0; i < 4; i++)
{
printf("%d", array[i].num);
}
printf("\n");
}
void fillArray(size_t size, struct numbers a[size])
{
for (size_t i = 0; i < size; i++)
{
a[i].num = i;
}
}
It is sufficient to only mention the array name. The compiler will transform it into a pointer to the first element.
So instead of
fillArray(&array);
you write
fillArray(array);
Though this answers your question, of course the function being called must have a compatible definition, which in your case is not so.

Setting values to a struct is not working for me. (C)

I created a typedef matrix:
typedef struct matrix {
int m;
int n;
int **vrednosti;
} matrix ;
and a function that creates a matrix:
matrix* create_matrix(int x, int y, int** val)
but when I set the dimensions (m and n)
mat.n = x;
mat.m = y;
only n gets actually set.
When i print them out after setting them I get something like that
n = 3
m = -1717986919
even though I set n = 3 and m = 3.
Full code:
typedef struct matrix {
int m;
int n;
int **vrednosti;
} matrix ;
matrix* create_matrix(int x, int y, int** val){
matrix mat;
mat.n = x;
mat.m = y;
mat.vrednosti = val;
matrix* trol = &mat;
return trol;
}
int main(int argc, char* argv[]){
int n = *argv[1]-'0';
int m = *argv[2]-'0';
int i,j;
int** tab;
tab = (int**)malloc(n*sizeof(int*));
for(i=0; i<n; i++){
tab[i] = (int*)malloc(m*sizeof(int));
}
for(i=0; i<n; i++){
for(j=0; j<m; j++){
scanf("%d",&tab[i][j]);
}
}
matrix* mat;
mat = create_matrix(n,m,tab);
printf("%d ",(*mat).n);
printf("%d ",(*mat).m);4
return 0;
}
It is most likely that you create a matrix object local to the function and return its address. The object does not exist beyond the scope of the function and gives you undefined behavior. Your implementation probably looks something like:
matrix* create_matrix(int x, int y, int** val)
{
matrix mat;
mat.n = x;
mat.m = y;
return &mat;
}
There are a number of ways to solve the problem the basic of each of those rules is:
To increase the lifetime of the object(who's address is returned) even after the function exits.
The exact way depends on the functionality you want to achieve. Simplest being returning a object itself by value, or dynamically allocating the object.

Returning dynamic array through void function in C

In my C program, I use a void function with the following arguments:
One 2D int array, one int pointer that will be used to create the new dynamic array and a last int pointer which will hold a number of counts that will occur inside the function.
So the dynamic array is created in the function using malloc and everything works okay, until I print its elements in main() after calling the function. What I get is rubbish instead of the numbers I should see. Here's the function code:
void availableMoves(int array[][3], int *av, int *counter)
{
int i, j;
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
if (array[i][j] == E)
{
printf("%d ", 3*i + j + 1);
(*counter)++;
}
}
}
av = (int *) malloc(*counter * sizeof(int));
if (av == NULL)
{
printf("ERROR!");
}
else
{
for (i=0; i<*counter; i++)
*(av + i) = 0;
int pos = 0;
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
if (array[i][j] == E)
{
*(av + pos++) = 3*i + j + 1;
}
}
}
}
}
In this function, av is a pointer passed by copy. So when you change the value of your pointer inside the function, the original pointer won't be modified.
There are two possibilities :
use a pointer to pointer (int **av);
return the allocated pointer (return av).
So either:
void availableMoves(int array[][3], int **av, int *counter);
Or:
int *availableMoves(int array[][3], int *av, int *counter)
And the call:
availableMoves(array, &av, &counter);
av = availableMoves(array, av, &counter);
use double pointer for your dynamic array int **av instead of int *av
void availableMoves(int array[][3], int **av, int *counter)
and into the function change av by *av

Resources