How to use pointer to pointer for passing matrix? - c++

Passing matrix as a pointer to pointer to function not working.
#include <stdio.h>
void printMatrix(int **matrix, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", matrix[i][j]);
printf("\r\n");
}
}
void printM (size_t row, size_t col, int matrix[3][4])
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", matrix[i][j]);
printf("\r\n");
}
}
int main()
{
int M[3][4];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++)
M[i][j] = 4*i+j;
printM(3, 4, M);
int *row = *M;
printMatrix(&row, 3, 4); //not working
}
Function printM works, but I would like to know how to use pointer to pointer correctly, thanks for help.

First of all, thank-you for this question. It is a good review of how C does multi-dimensional arrays. Also, it is OK to do double pointers. Remember an array reference is equivalent to a pointer, such as: a[0] and *a both refer to the first element of int a[12]; where *a is the de-referencing of pointer a. And so, &M is a the address of the pointer M when M is declared as int M[3][4];
I modified your code by adding a few comments for clarity and so that it would run in Eclipse using a C compiler from Microsoft, specifically, int declarations where moved out of the for statements. Other than that it is the same as what you originally wrote with a change to the printMatrix declaration and how it is invoked.
Hope this helps, please ask if more questions...
#include <stdio.h>
void printMatrix(int (*matrix)[3][4], int row, int col)
{
int i, j;
// point t so that when de-referenced it is at
// the matrices first element
int *t = (*matrix)[0];
printf("\n");
for (i = 0; i < row; i++)
{
// in C matrices are stored in Row Major form, so
// per K&R just sequentially loop thru (*t)[12]
for (j = 0; j < col; j++) {printf("%d ", *t++);}
printf("\r\n");
}
} // end printMatrix
void printM (size_t row, size_t col, int matrix[3][4])
{
int i, j;
printf("\n");
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++) {printf("%d ", matrix[i][j]);}
// new line for next row
printf("\r\n");
}
}
int main()
{
int i,j;
// define a matrix with 3 rows and 4 columns
int M[3][4];
// fill-in the matrix with values
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
M[i][j] = 4*i + j;
// print the three rows and four columns of M
printM(3, 4, M);
printMatrix(&M, 3, 4); // Also Works
} // end main

void printMatrix(int *matrix, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", *(matrix+(i*col)+j);
printf("\r\n");
}
}
Don't do a double pointer.

Related

Find the sum of an entire matrix using functions (C++)

I am writing some code that writes a matrix with a 10x10 size and prints it using functions. What I need is a function that takes the sum of the entire matrix array. What I have done is that I tried to sum up each row and column separately and add the total together. The problem with mine is that I believe that it only prints out the sum of the row or the column.
This is the code I have:
#include <iostream>
#include <ctime>
#include <iomanip>
#include <cstdlib>
using namespace std;
const int ROW_SIZE = 10;
const int COLUMN_SIZE = 10;
void initialize(int [][10], int, int);
void display(int matrix[][10], int, int);
void sum(int matrix[][COLUMN_SIZE], int, int);
int main() {
int matrix [ROW_SIZE][COLUMN_SIZE];
initialize(matrix, ROW_SIZE, COLUMN_SIZE);
display(matrix, ROW_SIZE,COLUMN_SIZE);
sum(matrix, ROW_SIZE,COLUMN_SIZE);
return 0;
}
void initialize(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
for (int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COLUMN_SIZE; j++){
matrix[i][j] = 1 + rand() % 99;
}
}
}
void display(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
for(int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COLUMN_SIZE; j++){
cout<< setw(4)<<matrix[i][j]<< " ";
}
cout<< endl;
}
}
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum_row;
int sum_col;
for(int i = 0; i < ROW_SIZE; i++){
int sum_row = 0;
for(int j = 0; j < COLUMN_SIZE; j++){
sum_row = sum_row + matrix[i][j];
}
}
for(int i = 0; i < ROW_SIZE; i++){
int sum_col = 0;
for(int j = 0; j < COLUMN_SIZE; j++){
sum_col = sum_col + matrix[i][j];
}
}
int sum = sum_row + sum_col;
cout<<"The sum of the matrix is "<<sum<< endl;
}
What you have done is sum of last row + last column. This should be enough:
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum = 0;
for(int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COLUMN_SIZE; j++){
sum += matrix[i][j];
}
}
cout<<"The sum of the matrix is "<<sum<< endl;
}
few early problems in your code
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum_row; // uninitialized make it equal to 0
int sum_col; // uninitialized make it equal to 0
for(int i = 0; i < ROW_SIZE; i++){
int sum_row = 0; // This is local to block and masks the sum_row above
for(int j = 0; j < COLUMN_SIZE; j++){
sum_row = sum_row + matrix[i][j];
}
}
for(int i = 0; i < ROW_SIZE; i++){
int sum_col = 0;
for(int j = 0; j < COLUMN_SIZE; j++){
sum_col = sum_col + matrix[i][j]; //Iterating over rows again matrix[j][i] may be
}
}
int sum = sum_row + sum_col;
cout<<"The sum of the matrix is "<<sum<< endl;
}
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum_row = 0;
int sum_col = 0;
for(int i = 0; i < ROW_SIZE; i++)
for(int j = 0; j < COLUMN_SIZE; j++)
sum_row += matrix[i][j];
for(int i = 0; i < ROW_SIZE; i++)
for(int j = 0; j < COLUMN_SIZE; j++)
sum_col += matrix[j][i];
int sum = sum_row + sum_col;
cout<<"The sum of the matrix is "<<sum<< endl;
}
Now of course the question and logic doesn't seem to co-exist together and if sum of entire matrix means sum of all elements which is what it sounds like it can be achieved with the one here
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum = 0;
for(int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COLUMN_SIZE; j++){
sum += matrix[i][j];
}
}
cout<<"The sum of the matrix is "<<sum<< endl;
}
You're doing something wrong in terms of naming. You have constants called ROW_SIZE and COLUMN_SIZE and then you have parameters with the same names to functions like sum(). This is confusing for something reading your code. Call your parameters something else, like rows and columns.
Here is an alternative to the proposed solutions using std::accumulate().
const int ROW_SIZE = 3;
const int COLUMN_SIZE = 3;
void sum(int matrix[][COLUMN_SIZE], int const rows, int const cols)
{
int sum = std::accumulate(&matrix[0][0], &matrix[rows-1][cols], 0);
std::cout<<"The sum of the matrix is "<<sum<< std::endl;
}
int main()
{
int m[ROW_SIZE][COLUMN_SIZE] {{1,2,3}, {4,5,6}, {7,8,9}};
sum(m, ROW_SIZE, COLUMN_SIZE);
}
std::accumulate() takes the iterators that delimit a range. Those are the iterators to the first element and the one past the last element of the range. In this case, these are &matrix[0][0] and &matrix[row-1][col] (since &matrix[row-1][col-1] is the last element of the matrix). There are other ways to put that, such as the following:
auto begin = std::begin(matrix[0]);
int sum = std::accumulate(begin, begin + rows * cols, 0);

How to pass 2-D char array to a function?

I just create a simple function which takes the 2-D char array as an argument and then just print the values of that 2-D char array.
The function is given below
void final_output(char arr[][200]){
int i, j;
for(i = 0; i < r; i++){
for(j = 0; j < c; j++){
cout << arr[i][j];
}
}
}
And i call this function as
final_output(grid_2);
But i face an error
error: cannot convert 'char (*)[c]' to 'char (*)[200]' for argument '1' to 'void final_output(char (*)[200])'
final_output(grid_2);
I search for different methods to pass the 2-D array as an argument to a function but i try all of them and they give the same type of error. Please anyone help me out to remove this error. Actually i use this function in this problem of hackerrank.
It is a strange function but it works for me assuming you define r and c, and the grid2 is an char[][200].
void final_output(char arr[][200]) {
int i, j;
int r = 10;
int c = 200;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
cout << arr[i][j];
}
}
}
int main(int argc, char* argv[])
{
char arr[10][200];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 200; j++) {
arr[i][j] = 'a';
}
}
final_output(arr);
//it prints aaaaaaaa
}
I you want a method to be valid for any matrix since you need to use char**. I is more cumbersome because if you are using pointers, but it is more flexible.
void final_output(char** arr, int nrow, int ncol) {
for (int i = 0; i < nrow; i++) {
for (int j = 0; j < ncol; j++) {
cout << arr[i][j];
}
}
}
int main(int argc, char* argv[])
{
//construct the matrix (any size would work)
int nrow = 10;
int ncol = 20;
char** arr = new char* [nrow];
for (int i = 0; i < nrow; i++){arr[i] = new char[ncol];}
//assign values
for (int i = 0; i < nrow; i++) {
for (int j = 0; j < ncol; j++) {
arr[i][j] = 'a';
}
}
final_output(arr,nrow,ncol);
}

Why debugger shows problem before sorting? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have problem with my program written in C. I want to draw int numbers to 2-size array, show it and then sort numbers in lines, and then make transposition with array, but it doesn't work. debugger show error in line with printf in function main() but i totally don't know what's wrong.
Thank for all support.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <algorithm>//dla swapa
void draw(int **tab, int m, int n)
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
tab[m][n] = rand() % (100 + 1); //0-100
}
}
}
void sort(int **tab, int m, int n)
{
m = 0;
while (m)
{
for (int j = n - 1; j > 0; j--)
{
for (int i = 0; i < n; i++)
{
if (tab[i] > tab[i + 1])
{
std:: swap(tab[i], tab[i + 1]);
}
}
}
m++;
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("|%d||[%d|\n", tab[i][j]);
}
}
}
int main()
{
int w, k;
int **tab;
printf("Lines: ");
scanf(" %d", &w);
printf("columns: ");
scanf(" %d", &k);
tab = (int**)malloc(w*sizeof(int*));
for (int i = 0; i < k; i++) {
tab[i] = (int*)malloc(k * sizeof(int));
}
printf("\nBefore sorting: \n");
for (int i = 0; i < w; i++)
{
for (int j = 0; j < k; i++)
{
printf("|%d||%d|", tab[i][j]);
}
}
// lub tab=(int*)malloc(w*k*sizeof(int));
srand(time(NULL));
draw(tab, w, k);
printf("\nSorted array:\n");
sort(tab,w,k);
}
The line for (int i = 0; i < k; i++) { should be for (int i = 0; i < w; ++i)
The line printf("|%d||%d|", tab[i][j]); should be printf("tab[%d][%d] = %d\n", i, j, tab[i][j]);
Your function sort() is wrong.
You should use like row, col not w, k
The following code could work:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <algorithm>
void draw(int **tab, int row, int col) {
for (int i = 0; i < row; ++i)
for (int j = 0; j < col; ++j)
tab[i][j] = rand() % (100 + 1);
}
void sort(int **tab, int row, int col) {
int x = 0;
int y = 0;
while (x != row) {
int temp = tab[x][y];
for (int j = y + 1; j != col; ++j)
if (tab[x][j] < tab[x][y])
std::swap(tab[x][j], tab[x][y]);
for (int i = x + 1; i != row; ++i)
for (int j = 0; j != col; ++j)
if (tab[i][j] < tab[x][y])
std::swap(tab[i][j], tab[x][y]);
++y;
if (y == col) {
y = 0;
++x;
}
}
}
void output(int** tab, int row, int col) {
for (int i = 0; i < row; ++i)
for (int j = 0; j < col; ++j)
printf("tab[%d][%d] = %d\n", i, j, tab[i][j]);
}
int main() {
int row, col;
int **tab;
printf("Lines: ");
scanf(" %d", &row);
printf("columns: ");
scanf(" %d", &col);
tab = (int **)malloc(row * sizeof(int *));
for (int i = 0; i < row; ++i)
tab[i] = (int *)malloc(col * sizeof(int));
printf("\nBefore sorting: \n");
srand(time(NULL));
draw(tab, row, col);
output(tab, row, col);
printf("\nSorted array:\n");
sort(tab, row, col);
output(tab, row, col);
return 0;
}
The following lines (it appears twice):
printf("|%d||[%d|\n", tab[i][j]);
Wants to print two numbers but you are only giving it a single value tab[i][j] to print.
You also need to look at this code:
tab = (int**)malloc(w*sizeof(int*));
for (int i = 0; i < k; i++) {
tab[i] = (int*)malloc(k * sizeof(int));
}
Here you allocate w array elements but then use kwhen in the for loop.

Two dimensional array - functions

I have to solve a problem with two 2D arrays and calculated things like odds number, sum of even number and addition of the two array. I get multiple errors. Can someone help me?
It is how I define my arrays, and it also says display_odd is not a valid void function. Why?
#define DIM 50
#include <stdio.h>
#include <conio.h>
void display_odd(int[][DIM]);
int display_even_sum(int[][DIM], int[][DIM]);
int display_matrix_sum(int[DIM][DIM], int[DIM][DIM]);
void main(){
int x1, x2, y1, y2, x, y, arr1[DIM][DIM], arr2[DIM][DIM], arr[DIM][DIM];
printf("How large do you want the first matrix to be? ('x y') \n");
scanf("%d %d", &x1, &y1);
for (int i = 0; i < x1; i++){
for (int j = 0; j < y1; j++){
printf("A[%d][%d]= ", i + 1, j + 1);
scanf("%d", &arr1[i][j]);
}
}
printf("How large do you want the second matrix to be? ('x y') \n");
scanf("%d %d", &x2, &y2);
for (int i = 0; i < x2; i++){
for (int j = 0; j < y2; j++){
printf("B[%d][%d]= ", i + 1, j + 1);
scanf("%d", &arr2[i][j]);
}
}
if (x1 > x2)
x = x1;
else
x = x2;
if (y1 > y2)
y = y1;
else
y = y2;
//printf("\nThe odd numbers in matrix A are : \n");
//void display_odd(arr1[DIM][DIM]);
//printf("\nThe odd numbers in matrix B are : \n");
//void display_odd(arr2[DIM][DIM]);
printf("\nThe sum of all even elements is : ");
printf("\nThe sum of the initial matrixes is : \n");
arr = display_matrix_sum(arr1[DIM][DIM] ,arr2[DIM][DIM]);
for (int i = 0; i < DIM; i++){
printf("\n");
for (int j = 0; j < DIM; j++)
printf(" %d", arr[i][j]);
}
_getch(); //Wait for it
}
void display_odd(int arr[][DIM]){
for (int i = 0; i < DIM; i++)
for (int j = 0; j < DIM; j++)
if (arr[i][j] % 2 == 1)
printf("[%d][%d]", i, j);
}
int display_even_sum(int arr1[DIM][DIM],int arr2[DIM][DIM]){
int s = 0;
for (int i = 0; i < DIM; i++)
for (int j = 0; j < DIM; j++)
if (arr1[i][j] % 2 == 0)
s += arr1[i][j];
for (int i = 0; i < DIM; i++)
for (int j = 0; j < DIM; j++)
if (arr2[i][j] % 2 == 0)
s += arr2[i][j];
return(s);
}
int display_matrix_sum(int arr1[][DIM],int arr2[][DIM]){
int arr[DIM][DIM];
for (int i = 0; i < DIM; i++)
for (int j = 0; j < DIM; j++)
arr[i][j] = arr1[i][j] + arr2[i][j];
return(arr[DIM][DIM]);
}
arr = display_matrix_sum(arr1[DIM][DIM] ,arr2[DIM][DIM]);
A C function cannot return an array. You can pass the destination array as an additional argument.
void display_matrix_sum();
…
display_matrix_sum(arr1, arr2, arr);
…
void display_matrix_sum(int arr1[][DIM], int arr2[][DIM], int arr[][DIM])
{
…
// remove this: return(arr[DIM][DIM]);
}
When you declare an array, or when you reference a specific member in an array, you use the square brackets:
int array[2][3];
array[1][0] = 6;
int x = array[1][0]; // x is now 6
when you pass an array as an argument, you simply use the name of the array;
someFunction(array); // passes the array
anotherFunction(array[1][0]); // passes 6;
return array; // returns the array;
return array[1][0]; // returns 6;
It may also help to give the parameters and local variables in your functions different names than the global arrays you define, and to define those global arrays as local arrays in your main function.
The biggest problem is that you don't seem to understand that arrays are just pointers. you can't just pass them around unless they are heap allocated. Each function should be rewritten to show this. For example display_matrix_sum's signature should look like
int** display_matrix_sum(int** A1, int** A2, int rows, int cols);
and should be called by:
int cols = 4; // or whatever
int rows = 4; // or whatever
int** arr1 = new int*[rows]; // arr1 is now any an array of int arrays
int** arr2 = new int*[rows]; // arrays work by pointing to the first element
for(int i = 0; i < rows; i++)
{
arr1[i] = new int[cols]; // each element in arr1 becomes an int array
arr2[i] = new int[cols];
}
/* fill in the values of the arrays */
int** out = display_matrix_sum( arr1, arr2, rows, cols, out);
// output now contains the result of the function
/* when you are done with arr1 and arr2 and out*/
for(int i = 0; i < rows; i++)
{
delete[] arr1[i];
delete[] arr2[i];
delete[] out[i];
}
delete[] arr1;
delete[] arr2;
delete[] out;

Changing raw pointers to smart in C++

There is a simple function creating an zero-filled matrix stored in array.
void zeroMatrix(const int rows, const int columns, void* M)
{
for(int i = 0; i < rows; i++)
for(int j = 0; j < columns; j++)
*(((double *)M) + (rows * i) + j) = 0;
}
How do I change the code to use std::unique_ptr<double> as M?
Since there is no ownership transfer to the zeroMatrix function, what you need is a reference:
(Assuming M is a vector)
void zeroMatrix(const int rows, const int columns, std::vector<double> &M)
{
for(int i = 0; i < rows; i++)
for(int j = 0; j < columns; j++)
M[(rows * i) + j] = 0;
}