Printing the value of 2d array stored in another function - c

i currently have a array function that reads in values of user input and I want to print out the array using another function.
this is my code
Function to read in user input and store in 2d array
void readMatrix(){
int arr[3][4];
int *ptr;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("row %d, col %d: ", i + 1, j + 1);
scanf("%d", &arr[i][j]);
}
ptr = &arr;
}
}
function to print array stored in readMatrix() function
void printMatrix(){
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 4; ++j)
{
printf("row %d, col %d = %d\n", i + 1, j + 1, arr[i][j]);
}
}
}
int main(){
//function to read matrix
readMatrix();
//function to print matrix
printMatrix();
return 0;
}

int arr[3][4]; is a local variable only valid inside that function, so you can't pass it to anyone else. The easiest and best solution is to use caller allocation instead. You can also rewrite the functions to work with variable amounts of rows/cols.
With just a few tweaks to your code:
#include <stdio.h>
void readMatrix (int rows, int cols, int arr[rows][cols]){
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
printf("row %d, col %d: ", i + 1, j + 1);
scanf("%d", &arr[i][j]);
}
}
}
void printMatrix (int rows, int cols, int arr[rows][cols]){
for (int i = 0; i < rows; ++i)
{
printf("{ ");
for (int j = 0; j < cols; ++j)
{
printf("%2.d ", arr[i][j]);
}
printf("}\n");
}
}
int main (void)
{
int arr[3][4];
readMatrix(3,4,arr);
printMatrix(3,4,arr);
return 0;
}
Input:
1 2 3 4 5 6 7 8 9 10 11 12
Output:
{ 1 2 3 4 }
{ 5 6 7 8 }
{ 9 10 11 12 }
If you don't understand why this works, then "array decay" is the next best thing to study. What is array to pointer decay?

The problem is that you are trying to access the array from outside the scope of the function that created it. You need to pass it as a parameter to your print function. You can also return a pointer to the array from your read function and then pass the pointer to your print function. Here is an example of the second option:
#include <stdio.h>
int *readMatrix(int *arr);
void printMatrix(int *arr);
int main()
{
int arr[3][4];
readMatrix(&arr[0][0]);
printMatrix(&arr[0][0]);
return 0;
}
int *readMatrix(int *arr)
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 4; ++j)
{
printf("row %d, col %d: ", i + 1, j + 1);
scanf("%d", &arr[i * 4 + j]);
}
}
return arr;
}
void printMatrix(int *arr)
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 4; ++j)
{
printf("row %d, col %d = %d\n", i + 1, j + 1, arr[i * 4 + j]);
}
}
}

Related

Expression must have arithmetic type issue

I need to multiply two square matrixes A and B 15x15.
Unfortunately, I'm getting this kind of error.
I know the problem is in pointers while calculating matrix C.
C[i][j] += *(A + k) * *(B + k)
I hope you can explain me what's wrong. I'm a beginner xD.
Thank you in advance.
#include <stdio.h>
#define N 15
#define _CRT_SECURE_NO_WARNINGS
int main() {
int A[N][N];
int B[N][N];
int C[N][N];
printf("Input matrix A.\n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("Enter your element:\n");
scanf_s("%d", &A[i][j]);
}
printf("\n");
}
printf("Input matrix B.\n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("Enter your element:\n");
scanf_s("%d", &B[i][j]);
}
printf("\n");
}
printf("Matrix A.\n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%d\t", A[i][j]);
}
printf("\n");
}
printf("Matrix B.\n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%d\t", B[i][j]);
}
printf("\n");
}
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
C[i][j] = 0;
for (int k = 0; k < 14; k++) {
C[i][j] += *(A + k) * *(B + k);
k++;
}
}
}
printf("Your result:\n");
printf("Matrix C.\n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%d\t", C[i][j]);
}
printf("\n");
}
return 0;
}
The problem in the multiplication is that A+k and B+k have type int (*)[15] which means dereferencing it once only makes a pointer out of them; furthermore, you need to take row and column items individually, which means A[i][k] and B[k][j], right? (also, there's no point on using confusing syntax, as the underlying operation is exactly the same).
Here's a fixed and improved version:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define N 15
/* Improvement 1 (type abstraction) */
typedef int NxN_int_matrix[N][N];
/* Improvement 2 (input function & wrapper) */
#define input_matrix(var) input_matrix_ex((var), #var)
static void input_matrix_ex(NxN_int_matrix dst, char *name)
{
printf("Input matrix %s.\n", name);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
/* Improvement 3 (nicer prompt) */
printf("%s[%2d][%2d]: ", name, i, j);
fflush(stdout);
scanf_s("%d", &dst[i][j]);
}
}
printf("\n");
}
/* Improvement 4 (print function) */
#define print_matrix(var) print_matrix_ex(#var, (var))
static void print_matrix_ex(char *name, NxN_int_matrix M)
{
printf("Matrix %s.\n", name);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%d\t", M[i][j]);
}
printf("\n");
}
}
/* Improvement 5 (move multiplication to a function too, and fix it) */
static void mult_matrix(NxN_int_matrix dst, NxN_int_matrix a, NxN_int_matrix b)
{
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
/* Improvement 6 (don't write out intermediate values) */
int tmp = 0;
for (int k = 0; k < N; k++)
tmp += a[i][k] * b[k][j];
dst[i][j] = tmp;
}
}
}
int main()
{
NxN_int_matrix A, B, C;
input_matrix(A);
input_matrix(B);
print_matrix(A);
print_matrix(B);
mult_matrix(C, A, B);
printf("Your result:\n");
print_matrix(C);
return 0;
}
/* Possible further improvements:
* - using a transposed B might make multiplication faster
*/

How to use a pointer (to a Matrix) as an argument in a Function in C?

I'm trying to write a code in C that sum two 4x4 matrix.
But I want my function to have a pointer as my arguments. The only error I'm getting is the time I'm trying to sum up in the function. Could someone help me?
#include <stdio.h>
#include <locale.h>
int i = 0, j = 0;
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
mat_C[i][j] = mat_A[i][j] + mat_B[i][j];
printf("%d", mat_C[i][j]);
}
}
}
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[4][4], mB[4][4], mC[4][4];
int *mat_A, *mat_B, *mat_C;
for(i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("Type in the value for Matrix A [%d][%d]: ", i, j);
scanf_s("%d", &mA[i][j]);
}
}
i, j = 0;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("Type in the value for Matrix B [%d][%d]: ", i, j);
scanf_s("%d", &mB[i][j]);
}
}
*mat_A = &mA;
*mat_B = &mB;
return 0;
}
The types of pointers for the arguments are wrong. You want to pass (the pointer to the first elements of) arrays like int mA[4][4];, so they should be pointers to int[4].
void calc_soma(int (*mat_A)[4], int (*mat_B)[4], int (*mat_C)[4])
{
/* same as original */
}
They can simply be written like this:
void calc_soma(int mat_A[][4], int mat_B[][4], int mat_C[][4])
{
/* same as original */
}
Then the function can be called like:
calc_soma(mA, mB, mC);
The purpose of mat_A and mat_B are unclear, but if you want to get pointers to the matrice like &mA, it should be int(*)[4][4]. Note that dereferencing (like *mat_A) uninitialized pointers will invoke undefined behavior.
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[4][4], mB[4][4], mC[4][4];
int (*mat_A)[4][4], (*mat_B)[4][4], (*mat_C)[4][4];
/* omit */
mat_A = &mA;
mat_B = &mB;
return 0;
}
To use functions like
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
you should express the matrice by 1D array to match with the format. It will be like this:
#include <stdio.h>
#include <locale.h>
#define ROWS 4
#define COLS 4
int i = 0, j = 0;
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
{
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
mat_C[i * COLS + j] = mat_A[i * COLS + j] + mat_B[i * COLS + j];
printf("%d", mat_C[i * COLS + j]);
}
}
}
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[ROWS * COLS], mB[ROWS * COLS], mC[ROWS * COLS];
for(i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("Type in the value for Matrix A [%d][%d]: ", i, j);
scanf_s("%d", &mA[i * COLS + j]);
}
}
i, j = 0;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("Type in the value for Matrix B [%d][%d]: ", i, j);
scanf_s("%d", &mB[i * COLS + j]);
}
}
calc_soma(mA, mB, mC);
return 0;
}

C program printing wrong output

I am trying to create a program which prints a matrix of integers, but the output returns weird numbers before the actual matrix. There are no compiling errors.
This is what my code looks like: //ignore void function for now, focus on main function::
#include <stdio.h>
#include <stdlib.h>
//array[30][30] = 2D array of max 30 rows and 30 columns
//n = number of rows and columns
void printmatrix(int array[30][30], int n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d", array[i][j]);
}
printf("\n");
}
return;
}
int main(){
int n;
scanf("%d", &n);
int ints2D[n][n];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d", &ints2D[i][j]);
}
}
printmatrix(ints2D, n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ", ints2D[i][j]);
}
printf("\n");
}
return 0;
}
And this is my output (I only want the last three lines)
123
-514159984327663
-51415932632766-514159305
1 2 3
4 5 6
7 8 9
You are missing a space in "%d" in printmatrix, and, more importantly, it is not proper to pass an int [n][n] array for an int [30][30] parameter unless n is 30.
Change void printmatrix(int array[30][30], int n) to void printmatrix(int n, int array[n][n]), and change printmatrix(ints2D, n); to printmatrix(n, ints2D);. That makes the type of the argument you are passing match the type of the parameter.
In your function args you defined the array as fixed size ([30][30]) but you are passing a VLA ([3][3] in your example) which makes it find uninitialized memory and why you are seeing the strange numbers.
#Eric Postpischil answer is spot on. Another way to solve it: 2d arrays could be flatten into 1d. Here is a working code for you:
#include <stdio.h>
#include <stdlib.h>
//array[30][30] = 2D array of max 30 rows and 30 columns
//n = number of rows and columns
void printmatrix(int *array, int n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ", array[i * n + j]);
}
printf("\n");
}
return;
}
int main(){
int n;
scanf("%d", &n);
int ints2D[n * n];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d", &ints2D[i * n + j]);
}
}
printmatrix(ints2D, n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ", ints2D[i * n + j]);
}
printf("\n");
}
return 0;
}

How to print matrix in C using pointers?

I cannot figure out why the output of my program is so strange. I just wanted to print matrix with pointers, but what I get is:
1 7 3 8 9
10 8 9 3 4
1 7 3 8 9
7 3 8 9 10
What am I doing wrong here?
#include<stdio.h>
#define NK 5
#define NW 2
int sum(int *w);
int main(void) {
srand(time(NULL));
int T[NW][NK];
int i, j;
for (i = 0; i<NW; i++) {
for (j = 0; j<NK; j++) {
T[i][j] = rand() % 10 + 1;
printf("%d ", T[i][j]);
}
printf("\n");
}
int *wsk = T;
printf("\n");
sum(wsk);
return 0;
}
int sum(int *w) {
int i, j;
int suma = 0;
printf("\n");
for (i = 0; i<NW; i++) {
for (j = 0; j<NK; j++) {
printf("%d ", *((w + i)+j));
}
printf("\n");
}
}
If the geometry is fixed, you can just declare the argument with the proper type:
int sum(int w[NW][NK]) {
printf("\n");
for (int i = 0; i < NW; i++) {
for (int j = 0; j < NK; j++) {
printf("%d ", w[i][j]);
}
printf("\n");
}
}
If you insist on passing a pointer to a linearized version:
int sum(int *w) {
printf("\n");
for (int i = 0; i < NW; i++) {
for (int j = 0; j < NK; j++) {
printf("%d ", w[i * NK + j]);
}
printf("\n");
}
}

While Performing 2D array representation in memory leads to Segmentation fault: 11

I've presented the codes below only while executing the first loop it works fine but as soon as i uncomment the second loop it starts to throw segmentation fault. My code is as below.
// Write a program to add two m*n matrices using pointer.
#include <stdio.h>
#define m 2
#define n 2
int main() {
int (*a)[n];
int (*b)[n], i, j; //, *(sum)[n], i, j;
printf("Enter first matrix:\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
scanf("%d", *(a + i) + j);
}
}
printf("Enter second matrix:\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
scanf("%d", *(b + i) + j);
}
}
// printf("The Sum of matrix is:\n");
// for (i = 0; i < m; i++) {
// for (j = 0; j < n; j++) {
// // *(*(sum + i) + j) = *(*(a + i) + j) + *(*(b + i) + j);
// // printf("\t%d", *(*(sum + i) + j));
// }
// printf("\n");
// }
}
You are not defining a and b as 2D arrays, but as uninitialized pointers to 2D arrays. passing addresses into these invokes undefined behavior. You must make these pointers point to an actual array, either static, automatic or allocated from the heap.
You can define 2D arrays this way:
int a[m][n], b[m][n];
If you are required to use pointers, you can allocate the 2D arrays with malloc:
int (*a)[n] = malloc(sizeof(*a) * m);
int (*b)[n] = malloc(sizeof(*b) * m);
In your program, it is more readable to use the [] syntax, even for pointers:
#include <stdio.h>
#include <stdlib.h>
#define m 2
#define n 2
int main(void) {
int (*a)[n] = malloc(sizeof(*a) * m);
int (*b)[n] = malloc(sizeof(*b) * m);
int (*sum)[n] = malloc(sizeof(*sum) * m);
printf("Enter first matrix:\n");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &a[i][j]);
}
}
printf("Enter second matrix:\n");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &b[i][j]);
}
}
printf("The Sum of matrices is:\n");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
sum[i][j] = a[i][j] + b[i][j];
printf("\t%d", sum[i][j]);
}
printf("\n");
}
return 0;
}

Resources