Generating matrix in C language - arrays

I can't solve simple task to generate matrix with given size. I'm getting too much errors whitch do not understand like: C2087, C2131 or C2447 (Microsoft Visual Studio)
Please help me if you can
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iomanip>
int max = 100;
void random(int & size, int M[][])
{ for (int i = 0; i < size; i++)
{ for (int j = 0; j < size; j++)
{
M[i][j] = rand() % 9;
}
}
}
void display(int size, int M[][])
{ for (int i = 0; i < size; i++)
{ for (int j = 0; j < size; j++)
{
printf("%d", &M[i][j]);
}
}
}
int main()
{
printf("give me matrix size\n");
int size;
scanf_s("%d", &size);
//int* M = new int[size][size];
int M[max][max];
random(size, M);
display(size, M);
return 0;
}

There is an issue with the way that you are handling arrays in c. Arrays are not actually passed around as arrays, but as pointers.
Consider this example
void print_arr (int array[], int length);
void print_arr (int * array, int length);
void print_arr (int array[10], int length);
void print_arr (int array[11], int length);
These four functions, as far as c is concerned, are the same. When you pass an array as a function argument, you are actually just passing a pointer. It works okay because you can access indexes of pointers. When you write
int function (int array[]) {
return array[3];
}
C will take the address of array, add (3 * sizeof(int)), and return that value. It can do this because it knows each element of the array has the size of int.
The problem with this is that you cannot pass two dimensional arrays in c. When you write
void function (int array[][]) {
array[2][3];
}
C will first calculate the first index. The issue is that it does not know the size to offset the array by. What if your array is 4 by 4? what if it's 7 by 9? Each possible size would require a different offset, and c doesn't know which.
There are a few options. Either write the size in ahead-of-time, like this:
int function (int array[10][10]) {
return array[2][3];
}
This tells c the size of the array, and lets it correctly calculate offsets.
Or, if you don't know the size ahead of time, manually pass the information in, like this:
int function (int * array, int width) {
int index = (2 * width) + 3;
return array[index];
}
In this example, you're basically doing the math that c normally does for you, manually.

Thank you Carson. So i tried to make matrix by making long array. Still I have problem with pointers I think.
My errors:
Error C2540 non-constant expression as array bound line 30
Error C2440 'initializing': cannot convert from 'int (*)[1]' to 'int *' Line 30
Error C2664 'void random(int,int *)': cannot convert argument 2 from 'int' to 'int *' Line 32
Error C2664 'void wypisz(int,int *)': cannot convert argument 2 from 'int' to 'int *' Line 33
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void random(int size, int * M)
{
for (int i = 0; i < size^2; i++)
{
int x = rand() % 9;
M[i] = x;
}
}
void display(int size, int *M)
{
for (int i = 0; i < size^2; i++)
{
printf("%d ", &M[i]);
if(size%i==0)
printf("\n");
}
}
int main()
{
printf("Gimme size: \n");
int size;
scanf_s("%d", &size);
int* M = new int[size][size];
random(size, *M);
display(size, *M);
return 0;
}

Related

main.c: warning: passing argument of ‘’ from incompatible pointer type

I'm trying to pass and return a two-dimension dynamic array by parameter, however it always shows this warning I mentioned in the question. I know there's something wrong with the array parameter, but I couldn't find in any book or a website how to properly pass an array whose dimensions change. I've read similar questions to mine about the warning and it's mostly about adding a & in your pointer, which I haven't added in mine.
#include <stdio.h>
#include <stdlib.h>
void fun(int m, int n, int (*arr)[n]);
int main(void) {
int i, j, m, n, **arr;
printf("Enter the dimensions m, n\n");
scanf("%d %d", &m, &n);
arr = (int **)malloc(m * sizeof(int *));
for (i = 0; i < m; i++) {
arr[i] = (int *)malloc(n * sizeof(int));
}
fun(m, n, *arr);
printf("\n\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%5d", arr[i][j]);
}
printf("\n");
}
if (arr == NULL) {
exit(1);
} else
if (arr != NULL) {
free(arr);
}
return 0;
}
void fun(int m, int n, int (*arr)[n]) {
int i, j, k = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
k = k + 1;
arr[i][j] = k;
}
}
}
int **arr;
In main, arr is a pointer to a pointer to integer and you populate it with a nested memory allocation, because there are two levels of pointers involved. The arr[i] can be fragmented and each could hold a different number of entries, making arr a "ragged" array.
int (*arr)[n]
The argument to your function is a pointer to an array of n integers. Here the entries of arr are contiguous in memory, so that arr[0] and arr[1] are sizeof(int[n]) bytes apart.
These are different types and the compiler tells you so. Pick one.
A You can stick with the pointer-to-pointer approach. Then your function signature must match the definition in main:
void fun(int m, int n, int **arr) ...
In that case, you must also free all arr[i] at the end, before free(arr).
B Alternatively, you can keep your curret function and create a contiguous array with a single allocation:
int (*arr)[n] = malloc(m * sizeof(*arr));
Then pass it to your function directly without dereferencing it:
fun(m, n, arr);
At the end, just free(arr).
You are passing pointer to int(that is *arr) but you have declared function that will get pointer to array of n integers.
So, just make the following changes:
void fun(int m, int n, int **arr); // also change where function definition begins
fun(m, n, arr);
By the way, freeing memory is incomplete.
for (i=0; i<m; i++)
free(arr[i]); // first free individual array elements
free(arr);
fun is defined as receiving a pointer to variable sized array or n int. This is a C99 specific syntax that some C compilers might not support. You could also have defined fun with a simpler and more readable prototype that is in fact equivalent:
void fun(int m, int n, int arr[m][n]);
Also equivalent to this one:
void fun(int m, int n, int arr[][n]);
The problem is you allocate a very different type of object: an array of m pointers to arrays of n int. You should instead allocate an array of m variable sized arrays of n int and store its address to a pointer with the appropriate type:
int (*arr)[n] = malloc(m * sizeof(*arr));
Or just define it as a 2D variable sized array with automatic storage:
int arr[m][n];
If allocated with malloc(), you would free the object with
free(arr);
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
void fun(int m, int n, int arr[m][n]);
int main(void) {
int i, j, m, n;
printf("Enter the dimensions m, n\n");
if (scanf("%d %d", &m, &n) != 2 || m <= 0 || n <= 0)
return 1;
int (*arr)[n] = malloc(m * sizeof(*arr));
if (arr == NULL)
return 1;
fun(m, n, arr);
printf("\n\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%5d", arr[i][j]);
}
printf("\n");
}
free(arr);
return 0;
}
void fun(int m, int n, int arr[m][n]) {
int i, j, k = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
k = k + 1;
arr[i][j] = k;
}
}
}

Can somone please explain this to me

For n=3 and a={1,2,3},b={4,5,6} its supposed to calculate 1*4+2*5+3*6.
I don't understand why does it work because p is a pointer and p=produs(a,b,n) means that the address of p becomes the value returned by produs.
#include <stdio.h>
#include <conio.h>
void citire(int *x,int *n)
{
for(int i=1; i<=*n; i++)
scanf("%d",&x[i]);
}
int produs(int *a,int*b,int n)
{
int produs=0;
for(int i=1;i<=n;i++)
produs=a[i]*b[i]+produs;
return produs;
}
int main()
{
int n;
int*p;
scanf("%d",&n);
int *a=(int*)malloc(n*sizeof(int));
int *b=(int*)malloc(n*sizeof(int));
citire(a,&n);
citire(b,&n);
p=produs(a,b,n);
printf("%d",p);
return 0;
}
When you do:
size_t size = 10;
int* x = calloc(size, sizeof(int));
You get an array x with 10 items in it, indexed 0..9, not 1..10. Here calloc is used to make it abundantly clear what's being requested instead of doing multiplication that can be mysterious or obtuse.
As such, to iterate:
for (int i = 0; i < size; ++i) {
x[i] ...
}
You have a number of off-by-one errors in your code due to assuming arrays are 1..N and not 0..(N-1).
Putting it all together and cleaning up your code yields:
#include <stdio.h>
#include <stdlib.h>
void citire(int *x, size_t s)
{
for(int i=0; i < s; i++)
scanf("%d", &x[i]);
}
int produs(int *a, int* b, size_t s)
{
int produs = 0;
for(int i = 0; i < s; i++)
produs = a[i] * b[i] + produs;
return produs;
}
int main()
{
int n;
scanf("%d",&n);
int* a = calloc(n, sizeof(int));
int* b = calloc(n, sizeof(int));
citire(a, n);
citire(b, n);
// produs() returns int, not int*
int p = produs(a,b,n);
printf("%d", p);
return 0;
}
You're using pointers in places where pointers don't belong. In C passing a pointer to a single value means "this is mutable", but you don't change those values, so no pointer is necessary nor advised.
Try and use size_t as the "size of thing" type. That's what's used throughout C and it's an unsigned value as negative indexes or array lengths don't make any sense.

C program to calculate determinants of matrixes with command line parameters

So I have task like this:
"Write a program that will calculate determinants of matrixes. Size of the matrix should be typed as a command line parameter of the program. The user should type the matrix elements from the keyboard once the program is executed. The determinants should be calculated for different square matrix sizes (<=3) and not for the single fixed one. Divide your program into several functions. Use pointers. The size of arrays you'll use is determined by user during the program execution, therefore there is no need to use dynamic memory allocation."
I've heard that it's not possible to do this task with command line parameters, but not dynamic memory allocation. I'm just a beginner, so I wouldn't know. I haven't gotten to the part with calculating the determinants, I only wrote the functions to input and print a matrix, but there are already problems. I'm really lost as to what should I do.
This is what I have so far (it is not compiling right):
void inputMatrix(int size);
void printMatrix(int *matrix, int size);
int main(int argc, char *argv[])
{
int size = atoi(argv[1]);
int *matrix;
inputMatrix(size);
printMatrix(*matrix, size);
return 0;
}
void inputMatrix(int size)
{
int i, j;
int *matrix;
for(i=0; i<size; i++)
{
for(j=0; j<size; j++)
{
scanf("%d", (*(matrix + i) + j));
}
}
}
void printMatrix(int *matrix, int size)
{
int i, j;
int *matrix;
for(i=0; i<size; i++)
{
for(j=0; j<size; j++)
{
printf("%d ", *(*(matrix +i) + j));
}
printf("\n");
}
}
The answer by Joni addresses the main issue, but there are other things to be fixed in OP's code.
For starters, we have to decide whether to use a an array of arrays (like int mat[3][3];) or a simple array (like int mat[9];), while in OP's code, there's some confusion about it:
int main(int argc, char *argv[])
{
// ...
int *matrix; // <-- This pointer is uninitialized, its value is indeterminated
// ...
printMatrix(*matrix, size);
// ^ dereferencing it, you are passing an 'int'
}
// ...
void printMatrix(int *matrix, int size)
{ // ^ a pointer to an int is expected
int i, j;
int *matrix; // <-- This is a local variable that will shadow the parameter
// with the same name and it is also uninitialized.
for(i=0; i<size; i++)
{
for(j=0; j<size; j++)
{
printf("%d ", *(*(matrix +i) + j));
// ^^^^ this is equivalent to 'matrix[i][j]',
// but 'matrix' is only a pointer to 'int'
}
printf("\n");
}
}
So, if any dynamic memory allocation must be avoided, we can write somthing like this:
// ...
#define MAX_SIZE 3
int main(int argc, char *argv[])
{
int matrix[MAX_SIZE][MAX_SIZE];
// read 'size' from command line arguments, then
inputMatrix(size, matrix); // <-- Note that I'm passing 'matrix' here too.
printMatrix(size, matrix);
// ...
}
// The functions must be modified accordingly, e.g.:
void printMatrix(int size, int matrix[][MAX_SIZE])
// The inner dimension must be specified ^^^^^^
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
printf("%d ", *(*(matrix + i) + j)); // <-- "Use pointers." they said
}
printf("\n");
}
}
In case you want to use a plain array instead, it can be written like this:
// ...
#define MAX_SIZE 9 // <-- the total size: 3*3
int main(int argc, char *argv[])
{
int matrix[MAX_SIZE];
// ...
printMatrix(size, matrix);
// ...
}
void printMatrix(int size, int matrix[])
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
printf("%d ", *(matrix + (i * size + j));
// Note the math ^^^^^^^^^^^^^^^^^
// In this simple case of row wise traversal, it could be as simple as
// *(matrix++)
}
printf("\n");
}
}
Since you're not allowed to use dynamic memory allocation, you'll have to create the matrix in the main function and pass it to the other functions as a parameter. This uses a feature of C called variable length arrays:
int matrix[size*size];
inputMatrix(size, matrix);
If variable length arrays are not allowed either, just make it matrix[9] - size is at most 3 in your assignment
Finding determinant of square matrix of order n (n is finite) is quite easy with dynamic memory allocation. But, what is important in this case, is to free the memory at the end of program.
You can view my code here!

Pointing to arrays using void function

Sorry for that title. I really didn't know how to define this problem.
I was needed to declare integer array of N numbers and to fill it with random nums in void function. Then that array needs to be printed in main. The thing is that i am not allowed to use printf in void function so only way to print in main is to use pointers I guess. My knowledge is limited as I am beginner at pointers. Thx in advance and sorry for bad english.
Here is my code so far. When I compile it marks segmentation error.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form();
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, &a);
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr[100])
{
srand(time(NULL));
for (int i = 0; i < N; i++) {
*ptr[i] = rand() % 46;
}
There are several issues in your code.
1) Your array decalaration form() is obsolete. Use proper prototype.
2) For declaring a VLA, declare it after reading N instead of using a fixed size array.
3) An array gets converted into a pointer to its first element when passed to a function. See: What is array decaying?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int, int*); /* see (1) */
int main(void) /* Standard complaint prototype for main.
If you need to pass arguments you can use argc, and argv */
{
int N;
printf("Input size: \n");
scanf("%d", &N);
int a[N]; /* see (2) */
form(N, a); /* see (3) */
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr) { /* Modified to match the prototype
srand(time(NULL));
for (int i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}
So a couple things:
void form();
As Olaf was alluding to, this declaration is incorrect - you are missing the applicable parameters. Instead, it should be
void form(int N, int ptr[100]);
The main reason your program is crashing is because of the following line:
*ptr[i] = rand() % 46;
You are dereferencing the pointer at i, which is actaully giving you a number - what you want is to assign the value of the pointer at i the new random value:
ptr[i] = rand() % 46;
As related reading, see this question about passing an array in as a function parameter (basically, int ptr[] is the same thing as int * ptr)
Small modifications on your code:
1) Correction and simplification of parameter handling at function call. Just hand over "a", it's an array, so it is an address, you can use int *ptr, or int ptr[], or int ptr[100] in the formal parameter list for it. So you can use simply ptr[i] in your function.
2) Make a prototype for function from old-style declaration providing parameter list.
3) int i; declaration before the for loop - not mandatory, depends on your compiler standard
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int N, int *ptr);
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, a);
printf("Array: \n");
int i;
for (i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr)
{
srand(time(NULL));
int i;
for (i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}

Troubles with arrays in c

So I am currently getting into programming and I'm trying to write this code, but I am having trouble with arrays. I have read a lot of articles online and it seems that this code should work, but for some reason there is an error when I pass my arrays between my functions. Ignore the commented out section in the middle that is where I got it to work inside my main function. For this assignment I need it to work in the functions I defined below. I am just wanting to initialize my array in one function then print it out in the other.
Thanks!
here is the error it displays
prelab7.c:32: warning: passing argument 1 of ‘print_array’ makes pointer from integer without a cast
prelab7.c:7: note: expected ‘int *’ but argument is of type ‘int’
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int errorcheck(int );
void intializearrary(int[], int);
void print_array(int [], int);
int main()
{
int maxsize,i;
int n[maxsize];
printf("\nEnter the size of the input: ");
scanf("%d", &maxsize);
while (errorcheck (maxsize))
{
printf("\nInvalid input enter the size of the input again");
scanf("%d", &maxsize);
}
/* srand(time(NULL));
for (i = 0; i < maxsize; i++)
{
n[i] = generaterandomnumber();
printf("\nn[%d]=%d", i, n[i]);
}
*/
print_array( n[i], maxsize);
return 0;
}
int errorcheck (int maxsize)
{
if (maxsize < 0 || maxsize > 100)
return 1;
else
return 0;
}
void initializearrary( int n[],int maxsize )
{
int i;
srand(time(NULL));
for (i = 0; i < maxsize; i++)
{
n[i] = rand()%10;
}
}
void print_array(int n[], int maxsize)
{
int i; //counter
printf("\nInput Array\n");
for (i = 0; i < maxsize; i++)
{
{
printf("\t%d", n[i]);
}
}
/*int generaterandomnumber()
{
return rand()%10;
}*/
Move
int n[maxsize];
Just after the while loop and change
print_array( n[i], maxsize);
To
print_array( n, maxsize);
The former is done so that maxsize gets initialized before the VLA is constructed.
The latter is done because print_array expects an int* as the first argument, but you pass an invalid argument n[i] which is of type int.

Resources