i have problem with acessing 2d array via function - c

i am learning pointers and i write these code to add two martix via function, it compile well and give correct answer for 2x2 matrix but for more than two row and col it fails when i try it with 3x3 matrix [0][0] element for the first matrix it automaticaly become 6 and [1][0] it became 9 every time, i can't figure out why this happen
#include <stdio.h>
//-----------------Function------------------
void add(int (*p1)[10], int (*p2)[10], int (*p3)[10], int r, int c);
void get(int (*p1)[10], int r, int c);
void print(int (*p1)[10], int r, int c);
//---------------Main Program----------------
int main()
{
//declartion
int i, j, r, c;
printf("\n\tenter the row and column of matrix\n\t");
scanf("%d %d", &r, &c);
int m1[r][c], m2[r][c], m3[r][c];
printf("\n\tenter the element of first matrix\n\t");
get(m1, r, c);
print(m1, r, c);
printf("\n\tenter the element of second matrix\n\t");
get(m2, r, c);
print(m2, r, c);
add(m1, m2, m3, r, c);
printf("\n");
print(m3, r, c);
return(0);
}
//-------------Define Function---------------
//get()
void get(int (*p1)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n\t");
for(j = 0; j < c; j++)
{
scanf("%d", (*(p1+i)+j));
}
}
}
//--------------------X----------------------
//add()
void add(int (*p1)[10], int (*p2)[10], int (*p3)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
//printf("\n%d %d = %d & %d", i, j, *(*(p1+i)+j), *(*(p2+i)+j));
*(*(p3+i)+j) = *(*(p1+i)+j) + *(*(p2+i)+j);
}
}
}
//--------------------X----------------------
//print()
void print(int (*p1)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
{
printf("\t%d", *(*(p1+i)+j));
}
}
}
//--------------------X----------------------

Drop the array pointer notation and the fixed size. Use variable-length arrays based on the parameters.
Remove useless comments like // get ... void get...
Don't use unreadable de-referncing with *(arr+i) when you could be writing readable arr[i].
Print new line after each row, not before each row.
Here's a cleaned up program which compiles. I haven't tested it.
#include <stdio.h>
void add (int r, int c, int p1[r][c], int p2[r][c], int p3[r][c]);
void get (int r, int c, int p1[r][c]);
void print (int r, int c, int p1[r][c]);
int main (void)
{
int i, j, r, c;
printf("\n\tenter the row and column of matrix\n\t");
scanf("%d %d", &r, &c);
int m1[r][c], m2[r][c], m3[r][c];
printf("\n\tenter the element of first matrix\n\t");
get(r, c, m1);
print(r, c, m1);
printf("\n\tenter the element of second matrix\n\t");
get(r, c, m2);
print(r, c, m2);
add(r, c, m1, m2, m3);
printf("\n");
print(r, c, m3);
return(0);
}
void get (int r, int c, int p1[r][c])
{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
scanf("%d", &p1[i][j]);
}
}
}
void add (int r, int c, int p1[r][c], int p2[r][c], int p3[r][c])
{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
p3[i][j] = p1[i][j] + p2[i][j];
}
}
}
void print (int r, int c, int p1[r][c])
{
for(int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
printf("\t%d", p1[i][j]);
}
printf("\n");
}
}

Related

Function inputElements() taking input only once

I am trying to create a program to find the transpose of a matrix my dynamic memory allocation. However, while entering the elements of the matrix I can't input more than one element, its only taking the a[0][0] as the input and the program is ending after that.
#include <stdio.h>
#include <stdlib.h>
void createMatrix(int **, int, int);
void inputElements(int **, int, int);
void transpose(int **, int **, int, int);
void display(int **, int, int);
void main()
{
int **matrix, **trans, rows, cols;
printf("\nEnter number of rows in the matrix: ");
scanf("%d", &rows);
printf("\nEnter number of columns in the matrix: ");
scanf("%d", &cols);
createMatrix(matrix, rows, cols);
createMatrix(trans, cols, rows);
inputElements(matrix, rows, cols);
transpose(matrix, trans, rows, cols);
printf("\nMATRIX:\n");
display(matrix, rows, cols);
printf("\nTRANSPOSE OF THE MATRIX:\n");
display(trans, rows, cols);
}
void createMatrix(int **a, int r, int c) //for allocating memory for the matrix
{
int i, j;
a = (int **)malloc(sizeof(int *) * r);
for(i = 0; i < r; i++)
a[i] = (int *)malloc(sizeof(int) * c);
}
void inputElements(int **a, int r, int c) //for entering matrix elements
{
int i, j, t;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf("\nEnter matrix element[%d][%d]: ", i + 1, j + 1);
fflush(stdin);
getchar();
scanf("%d", &(a[i][j]));
}
}
}
void transpose(int **a, int **t, int r, int c) //for finding out the transpose of the matrix
{
int i, j;
for (i = 0; i < c; i++)
{
for (j = 0; j < r; j++)
t[i][j] = a[j][i];
}
}
void display(int **a, int r, int c) //for displaying the matrix
{
int i, j;
for (i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
printf("\t%d", a[i][j]);
}
}
There are many posts about scanf in loops I've seen, but I wasn't able to connect my issue with any of them.

Error when passing 2D array to function in c

I am writing a program to calculate matrix multiplication but it does not work. When I debug and check each value of the array a and b in function printMatrixMultiplication (which are entered by user), GDB prints out "cannot perform pointer math on incomplete type try casting". (I have searched for it but I still don't get it.) The function only works when the input is predefined in main.
This is my code
#include <stdio.h>
void input(int m, int n, double a[m][n]);
void output(int m, int n, double a[m][n]);
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b]);
int main()
{
int row_a, col_a, row_b, col_b;
// get value of matrix a
printf("row_a = ");
scanf("%d", &row_a);
printf("col_a = ");
scanf("%d", &col_a);
double a[row_a][col_a];
input(row_a, col_a, a);
// output(row_a, col_a, a);
// get value of matrix b
printf("row_b = ");
scanf("%d", &row_b);
printf("col_b = ");
scanf("%d", &col_b);
double b[row_b][col_b];
input(row_b, col_b, a);
// output(row_b, col_b, a);
printMatrixMultiplication(row_a, col_a, a, row_b, col_b, b);
//test
// double a[2][2]={1,2,3,4};
// double b[2][3]={1,2,3,4,5,6};
// printMatrixMultiplication(2,2,a,2,3,b);
return 0;
}
void input(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%lf", &a[i][j]);
}
}
}
void output(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%.2f ", a[i][j]);
}
printf("\n");
}
}
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b])
{
if (col_a != row_b)
{
return;
}
double res[row_a][col_b]; //this matrix store results
for (int i = 0; i < row_a; i++) //the values be stored line by line, this
{ //operation is controled by i and j loops.
for (int j = 0; j < col_b; j++) //the k loop helps calculate dot_product.
{
double dot_product = 0;
for (int k = 0; k < col_a; k++)
{
dot_product += a[i][k] * b[k][j]; //ERROR HERE
}
res[i][j] = dot_product;
}
}
output(row_a, col_b, res);
}
So, where does the error come from and how to fix it?
Irrelevant, but the function is not well implemented so if possible, I would really appreciate if anyone gives me a hint to improve it.
I am using GCC version 6.3.0.
It's typo in your code when reading matrix b.
Just replace:
input(row_b, col_b, a);
with
input(row_b, col_b, b);

c program run on codeblocks but not on clion how is it even possible?

i successfully run it on codeblocks, but my clion doesnt display anything when i run it.
i usually use clion, so im very furious about this. (dont want to be obligated to use codeblocks)
please help a poor lost soul.
this is the code.
dont have a lot more to say, but still stackoverflow wants me to write more, so here i am.
#include <stdio.h>
#include <stdlib.h>
int **malloc2dR(int r,int c);
int **MATinit(int r, int c);
void MATstampa(int **m, int r, int c);
void change(int **M, int r, int c);
int main() {
int r=3,c=4;
int **M=MATinit(r,c);
MATstampa(M,r,c);
change(M,r,c);
MATstampa(M,r,c);
return 0;
}
int **malloc2dR(int r, int c){
int **m;
int i;
m=malloc(r*sizeof (int *));
for(i=0;i<r;i++)
m[i]=malloc(c*sizeof (int));
return m;
}
int **MATinit(int r, int c){
int **M=malloc2dR(r,c);
int i,j;
printf("scrivere in input i valori della matrice %dx%d\n",r,c);
for(i=0;i<r;i++)
for(j=0;j<c;j++)
scanf("%d",&M[i][j]);
return M;
}
void MATstampa(int **m, int r, int c){
int i,j;
for(i=0;i<r;i++) {
for (j = 0; j < c; j++)
printf("%d ", m[i][j]);
printf("\n");
}
printf("\n");
}
void change(int **M, int r, int c) {
int i, j;
int ii, jj;
int **Mfake=malloc2dR(r,c);
for(i=0;i<r;i++)
for(j=0;j<c;j++)
Mfake[i][j]=M[i][j];
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
if (M[i][j] % 2 == 1) {
for (ii = 0; ii < r; ii++)
Mfake[ii][j] = 1;
for (jj = 0; jj < c; jj++)
Mfake[i][jj] = 1;
}
for(i=0;i<r;i++)
for(j=0;j<c;j++)
M[i][j]=Mfake[i][j];
}

makes pointer(integer) from integer(pointer) without a cast

#include<stdio.h>
#include<stdlib.h>
int **transpose(int a[], int b[], int raw, int column){
int i, j;
for(i=0; i < raw ; i++)
for(j=0; j < column ; j++)
*(b+(j*raw + i)) = *(a+(i*column + j));
return *b;
}
int **mk_matrix(int raw, int col){
int i;
int **matrix = (int**)malloc(sizeof(int*)*raw);
matrix[0] = (int*)malloc(sizeof(int)*(raw*col));
for(i=1 ; i < raw ; i++)
matrix[i] = matrix[i-1] + col;
return matrix;
}
void main(void){
int r, c, i, j;
printf("Input the size of matrix : ");
scanf("%d %d", &r, &c);
int **matrix = mk_matrix(r, c);
int **trans_matrix = mk_matrix(c, r);
printf("Input elements of the %dx%d matrix : ", r, c);
for(i=0; i < r ; i++)
for(j=0; j < c ; j++)
scanf("%d", &matrix[i][j]);
**trans_matrix = transpose(matrix[0], trans_matrix[0], r, c);
for(i=0; i < c ; i++){
for(j=0; j < r ; j++)
printf("%d ", trans_matrix[i][j]);
printf("\n");
}
}
In dev c++, this code runs correctly by I wanted but it comes
return makes pointer from integer without a cast -> return *b;
assignment makes integer from pointer without a cast -> **trans_matrix = transpose(matrix[0], trans_matrix[0], r, c);
warnings.
How can i fix my code not showing warnings?
Well you don't need to
return *b
int **transpose(int a[], int b[], int raw, int column)
just modify above to
void transpose(int a[], int b[], int raw, int column){
int i, j;
for(i=0; i < raw ; i++)
for(j=0; j < column ; j++)
*(b+(j*raw + i)) = *(a+(i*column + j));
}
and in main function
**trans_matrix = transpose(matrix[0], trans_matrix[0], r, c);
to
transpose(matrix[0], trans_matrix[0], r, c);
as transpose function is already performing necessary changes to trans_matrix. You do not need to return.
this will resolve warning issue.
In the function transpose() you are returning a ptr to int when the return type of transpose() is ptr to ptr to int. Now because you are returning the value of the wrong (not expected) data type, you are getting your second warning.
Another thing is when you are working with addresses of the matrices in the transpose() function you don't need to return any kind of value because ultimately you are changing values that are stored on that address. You are not working on a copy of that value. That's why you don't need to:
**trans_matrix = transpose(matrix[0], trans_matrix[0], r, c);
I don't know why you are overcomplicating the functions. You can write them as:
int transpose(int **a, int **b, int row, int column)
{
int i, j;
for(i=0; i < column ; i++)
for(j=0; j < row ; j++)
b[i][j] = a[j][i];
return 0;
}
and
int **mk_matrix(int row, int col)
{
int i;
int **matrix = malloc(sizeof(int*)*row);
for(i=0; i<row; i++)
matrix[i] = malloc(sizeof(int)*(col));
return matrix;
}
and in main() you just need to modify how you call the transpose() method:
transpose(matrix, trans_matrix, r, c);
P.S. Also, check if the memory space you are requesting(malloc()) is allocated to the ptr or not.

Using scanf() with a pointer to a double pointer

I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}
There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}
Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &

Resources