How to print matrix in C using pointers? - c

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");
}
}

Related

Printing the value of 2d array stored in another function

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]);
}
}
}

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
*/

(SOLVED) C 2D Array: Finding Max from each row and Min from each column

I am creating a program to print out the maximum value of each row and the minimum value of each column of an NxN 2D array.
So, for example I have this 4x4 2D array:
1 14 11 16
9 10 3 12
13 6 15 8
13 2 7 4
Then, the output should be
16 12 15 13 //Max of each row
1 2 3 4 //Min of each column
EDIT: Here is the revised code that works.
#include <stdio.h>
#include <stdlib.h>
void getMax(int n, int a[][n])
{
for (int i = 0; i < n; i++)
{
int max = a[i][0];
for (int j = 1; j < n; j++)
{
if (a[i][j] > max)
max = a[i][j];
}
printf("%d ",max);
}
}
void getMin(int n, int b[][n])
{
for (int i = 0; i < n; i++) {
int min = b[0][i];
for (int j = 1; j < n; j++)
{
if (b[j][i] < min)
min = b[j][i];
}
printf("%d ",min);
}
}
int main()
{
int r;
scanf("%d", &r);
int a[r][r];
for(int i=0; i<r; i++)
{
for(int j=0; j<r; j++)
{
scanf("%d",&a[i][j]);
}
}
getMax(r,a);
printf("\n");
getMin(r,a);
printf("\n");
}
This is my OLD code that did not work. Turns out I don't have to use MAX. Replace the a[][MAX] to a[][n].
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000
void getMax(int a[][MAX], int n)
{
for (int i = 0; i < n; i++)
{
int max = a[i][0];
for (int j = 1; j < n; j++)
{
if (a[i][j] > max)
max = a[i][j];
}
printf("%d ",max);
}
}
void getMin(int b[][MAX], int n)
{
for (int i = 0; i < n; i++) {
int min = b[0][i];
for (int j = 1; j < n; j++)
{
if (b[j][i] < min)
min = b[j][i];
}
printf("%d ",min);
}
}
int main()
{
int r;
scanf("%d", &r);
int a[r][r];
for(int i=0; i<r; i++)
{
for(int j=0; j<r; j++)
{
scanf("%d",&a[i][j]);
}
}
getMax(a,r);
printf("\n");
getMin(a,r);
}
Can anybody point out what I did wrong?
Thank you!

The reverse of all numbers on the 5th column on matrix [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I have a C problem where I need to reverse all the numbers on the 5th column of a 2x5 matrix.
So if I have
1 2 3 4 89
3 8 6 8 91
This will become
1 2 3 4 98
3 8 6 8 19
The code I've written so far is:
#include <stdio.h>
void inverse() {
int reversedNumber = 0, remainder, mat[10][10], i, j;
for (i = 0; i < 2; i++)
for (j = 0; j < 5; j++) {
while (mat[i][j] != 0) {
remainder = mat[i][j] % 10;
reversedNumber = reversedNumber * 10 + remainder;
mat[i][j] /= 10;
}
}
printf("Reversed Number = %d", reversedNumber);
}
void main()
{
int mat[10][10], i, j;
printf("Enter your matrix\n");
for (i = 0; i < 2; i++)
for (j = 0; j < 5; j++) {
scanf("%d", &mat[i][j]);
}
printf("\nHere is your matrix:\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 5; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
inverse(mat[1][5]);
}
After running this I get a ridiculously large number! What should I modify?
There are number of things that can be improved in the code.
First of all you have to set reversedNumber zero inside the innermost loop, this is the reason you get large numbers.
You pass an argument to the function, but the definition is incorrect for the same.
Also, you have stated that you only need to reverse the 5th column, better make call to a function that reverses a single number.
#include<stdio.h>
int inverse(int num) {
int reversednum = 0;
while(num){
reversednum = reversednum*10 + num%10;
num /= 10;
}
return reversednum;
}
void main(){
int mat[10][10],i,j;
printf("Enter your matrix\n");
for(i=0;i<2;i++)
for(j=0;j<5;j++){
scanf("%d",&mat[i][j]);
}
printf("\nHere is your matrix:\n");
for(i=0;i<2;i++){
for(j=0;j<5;j++){
printf("%d ",mat[i][j]);
if(j == 4) mat[i][j] = inverse(mat[i][j]);
}
printf("\n");
}
}
mistakes in your program:
-your function doesnt expect anything i.e empty parameter but you are sending matrix as parameter.
do not unnecessarily use matrix of size [10][10] when your matrix of 2*5
send 'mat' as parameter(i.e address of your matrix) to function inverse
#include <stdio.h>
int main() {
//code
int mat[10][10], i, j;
printf("Enter your matrix\n");
for (i = 0; i < 2; i++)
for (j = 0; j < 5; j++) {
scanf("%d", &mat[i][j]);
}
printf("\nHere is your matrix:\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 5; j++) {
if(j==4) //only for 5th column
{
// int temp=mat[i][j]; // can use temporary variable instead of changing actual value matrix (better option)
int remainder, reverse =0;
while(mat[i][j]>0)
{
remainder=mat[i][j]%10;
reverse=reverse*10 + remainder;
mat[i][j]=mat[i][j]/10;
}
mat[i][j]=reverse;
}
printf("%d ", mat[i][j]);
}
printf("\n");
}
return 0;
}
Edited: modified code from the question
#include <stdio.h>
void inverse(int mat1[2][5]) {
int i, j;
for (i = 0; i < 2; i++){
int j=4;
int reversedNumber = 0, remainder=0;
while (mat1[i][j] > 0) {
remainder = mat1[i][j] % 10;
reversedNumber = reversedNumber * 10 + remainder;
mat1[i][j] /= 10;
}
printf("Reversed Number = %d\n",reversedNumber);
}
}
void main()
{
int mat[2][5], i, j;
printf("Enter your matrix\n");
for (i = 0; i < 2; i++)
for (j = 0; j < 5; j++) {
scanf("%d", &mat[i][j]);
}
printf("\nHere is your matrix:\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 5; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
inverse(mat);
}
hope this helps.
You have to pass the matrix to the inverse function so that the matrix (mat) can be modified. If you declare a separate mat array inside inverse then that's a different scope. You also have to figure out how many digits there are in the number. You can use <math.h> functions, or the example below uses basic calculations.
void inverse(int mat[2][5])
{
for(int i = 0; i < 2; i++)
for(int j = 0; j < 5; j++)
{
int n = mat[i][j];
int digits = 0;
while(n > 0)
{
digits++;
n /= 10;
}
n = mat[i][j];
int rev = 0;
while(digits > 0)
{
int x = n % 10;
for(int c = 0; c < digits - 1; c++)
x *= 10;
rev += x;
n /= 10;
digits--;
}
mat[i][j] = rev;
}
}
int main(void)
{
int mat[2][5] = {
1, 2, 3, 4, 89,
3, 8, 6, 8, 91 };
inverse(mat);
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 5; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
return 0;
}

Finding the smallest element in multidimensional array

Im asking for help once again. This time I found myself in the midst of a task which I found on the internet and I cant find a good solution. At first I thought of bubble sort, but I didnt seem to find a way to use it with multidimensional array.
The task asks to find 3 smallest elements which arent repeating on the second array.
So far my code looks like this, though Ive removed a lot of it... Since it was a very wrong and futile aproach.
Everything was written in C.
Thanks for the help.
3
1 2 3
3 3 3
3 3 3
5 4 6
6 4 5
4 5 6
This is the given information for the file
#include stdio.h
#include stdlib.h
int main()
{
FILE *fptr;
fptr = fopen("Duomenys.txt", "r");
int i, j;
int k, l;
int bubbleTmp;
fscanf(fptr, "%d ", &k);
l = k;
int a[k][k];
int b[k][k];
for(i = 0; i < k; i++)
{
for(j = 0; j < l; j++)
{
fscanf(fptr,"%d ",&a[i][j]);
printf("%d ", a[i][j]);
}
printf("\n");
}
printf("\n\n\n");
for(i = 0; i < k; i++)
{
for(j = 0; j < l; j++)
{
fscanf(fptr,"%d ",&b[i][j]);
printf("%d ", b[i][j]);
}
printf("\n");
}
// Bubble Sort
for(i = 0; i < k; i++)
{
for(j = 0; j < l; j++)
{
if(a[i][j] > a[i][j+1])
{
}
}
}
fclose(fptr);
return 0;
}
To find the minimum and its position in the array:
int min = a[0][0], i_min = 0, j_min = 0;
for(i = 0; i < k; i++)
{
for(j = 0; j < l; j++)
{
if(a[i][j] < min)
{
min = a[i][j];
i_min = i;
j_min = j;
}
}
}
After the first try, you repeat it two more times, avoiding the minimums alrerady found. The positions of each minimums are known.
Previously, it was a suggestion.
Now, here is the solution:
//----------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
#include <ctime>
//----------------------------------------------------------------------------
int **CreateArray (int N, int M)
{
int **arr = new int*[N];
for (int i = 0; i<N; i++)
arr[i] = new int [M];
for (int i = 0; i<N; i++)
for (int j = 0; j<M; j++)
arr[i][j] = rand()%10 - rand()%10;
return arr;
}
void DestroyArray (int **arr, int N)
{
for (int i = 0; i<N; i++)
delete [] arr[i];
delete [] arr;
}
void PrintArray (int **arr, int N, int M)
{
for (int i = 0; i<N; i++)
{
for (int j = 0; j<M; j++)
std::cout << std::setw(7) << arr[i][j];
std::cout << "\n";
}
std::cout << "\n";
}
//----------------------------------------------------------------------------
typedef struct _min
{
int value;
int i;
int j;
} TMin;
//---------------------------------------------------------------------------
void FindMin (int **arr, int N, int M, TMin **mins, int min_count)
{
mins[min_count]->value = arr[0][0];
mins[min_count]->i = 0;
mins[min_count]->j = 0;
for (int i = 0; i<N; i++)
for (int j = 0; j<M; j++)
{
if (arr[i][j] < mins[min_count]->value)
{
bool prev = false;
for (int k = 0; k<min_count; k++)
if (i == mins[k]->i && j == mins[k]->j)
{
prev = true;
break;
}
if (!prev)
{
mins[min_count]->value = arr[i][j];
mins[min_count]->i = i;
mins[min_count]->j = j;
}
}
}
}
//----------------------------------------------------------------------------
int main()
{
//array creation, filling, printing
srand ((unsigned int)time (NULL));
int N = 6, M = 7;
int **arr = CreateArray (N, M);
PrintArray (arr, N, M);
//container for 3 minimums
TMin **mins = new TMin*[3];
for (int i = 0; i<3; i++)
mins[i] = new TMin;
//let us find them
int min_count = -1;
while (++min_count < 3)
FindMin (arr, N, M, mins, min_count);
//result
for (int i = 0; i<3; i++)
std::cout << "arr[" << mins[i]->i << "][" <<mins[i]->j << "] = " << mins[i]->value << "\n";
//cleaning memory
for (int i = 0; i<3; i++)
delete [] mins[i];
delete [] mins;
DestroyArray (arr, N);
std::cin.sync();
std::cin.get();
return 0;
}
//-----------------------------------------------------------------------------

Resources