Search code examples
c++functiontypesheaderglobal-variables

My functions are not updating global variables / the variables used in main


My project is some simple matrix operations, it should work fine, but my input function doesn't seem to be updating the global variables, they might be the wrong data type for what I'm trying to do but I'm not sure. Here is a link of what should be happening http://cpp.sh/22kie . also here is a link to everything with a Makefile https://drive.google.com/open?id=1tmIbdEWXJJ54moQKy8rkZODFkXKDU2Nz

here's my header file:

#ifndef project1
#define project1

static int choice, rows1, cols1, rows2, cols2, k;
static char choice2;
static int *mat1 = new int[10 * 10];
static int *mat2 = new int[10 * 10];
static int *matf = new int[10 * 10];

void output(int *matf, int rows, int cols);

void addition(int *mat1, int *mat2, int *matf, int rows, int cols);

void subtraction(int *mat1, int *mat2, int *matf, int rows, int cols);

void multiplication(int *mat1, int *mat2, int *matf, int rows1, int cols1, int rows2, int cols2);

int input();
#endif

here's: my main:

#include <string>
#include "project1.h"
using namespace std;

int main()
{

    input();

    switch (choice)
    { //this switch block will call the correct fucntion with respect to the user's choice

    case 1:
        addition(mat1, mat2, matf, rows1, cols1);

        break;

    case 2:
        subtraction(mat1, mat2, matf, rows1, cols1);

        break;

    case 3:
        multiplication(mat1, mat2, matf, rows1, cols1, rows2, cols2);

        break;

    case 0:
        return 0;
    default:
        cout << "invalid 2input";
    }
    //the end of the main function will repeat if the user would like

    cout << "\n Would you like to do another operation y/n?" << endl;
    cin >> choice2;

    if (choice2 == 'y')
    {
        main();
    }
    else
    {
        return 0;
    }
}

and here's the input function:

int input()

{

    //input function

    cout << "Menu"
         << "\n 1. Addition"
         << "\n 2. Subtraction"
         << "\n 3. Multiplication"
         << "\n 0. Exit"
         << "\n Enter the number of your choice" << endl;
    cin >> choice;

    if (choice == 0)
    { // this will kill the main function if "Exit" is chosen, or repeat if an invalid number is chosen
        return 0;
    }
    else if (choice > 3)
    {
        cout << "invalid input" << endl;
        input();
    }
    else
    {
    }
    //this part of the code will prompt the user for the rows and columns for each matrix
    cout << "Number of rows for the first Matrix? (max 10)" << endl;
    cin >> rows1;

    cout << "Number of columns for the first Matrix? (max 10)" << endl;
    cin >> cols1;

    cout << "Number of rows for the second Matrix? (max 10)" << endl;
    cin >> rows2;

    cout << "Number of columns for the second Matrix? (max 10)" << endl;
    cin >> cols2;

    //this if/else statement checks that the matrices are the right size to be operated
    if ((choice == 1 || choice == 2) && ((cols1 != cols2) || (rows1 != rows2)))
    {
        cout << " error: for addition and subraction the two matrices must have the same amount of elements";
        choice = 0;
        return 0;
    }
    else if ((choice == 3) && (rows2 != cols1))
    {
        cout << " error: for multiplication the columns of the first must equal the rows of the second";
        choice = 0;
        return 0;
    }
    else
    {
    }

    // this for loop allows the user to input each element for the first matrix
    cout << "input the elements of the first matrix: " << endl;

    for (int i = 0; i < rows1; i++)
    {
        for (int j = 0; j < cols1; j++)
        {
            cout << "Enter element "
                 << "(" << i << "," << j << "): ";
            cin >> k;
            *(mat1 + i * cols1 + j) = k;
        }
    }

    output(mat1, rows1, cols1); //this call to output will allow the user to see what they have imputed

    // this for loop allows the user to input each element for the second matrix
    cout << "input the elements of the second matrix: " << endl;
    for (int i = 0; i < rows2; i++)
    {
        for (int j = 0; j < cols2; j++)
        {
            cout << "Enter element "
                 << "(" << i << "," << j << "): ";
            cin >> k;
            *(mat2 + i * cols2 + j) = k;
        }
    }

    output(mat2, rows2, cols2); //this call to output will allow the user to see what they have imputed
}```

Edit: New main after switching everything to local variables:

main:

#include <iostream>
#include <string>
#include "project1.h"
using namespace std;

int choice, rows1, cols1, rows2, cols2, k;
char choice2;
int *mat1 = new int[10 * 10];
int *mat2 = new int[10 * 10];
int *matf = new int[10 * 10];

int main()
{


    input( choice, rows1, cols1, rows2, cols2, k, mat1, mat2, matf);
cout<<rows1;
    switch (choice)
    { //this switch block will call the correct fucntion with respect to the user's choice

    case 1:
        addition(mat1, mat2, matf, rows1, cols1);

        break;

    case 2:
        subtraction(mat1, mat2, matf, rows1, cols1);

        break;

    case 3:
        multiplication(mat1, mat2, matf, rows1, cols1, rows2, cols2);

        break;

    case 0:
        return 0;
    default:
        cout << "invalid input";
    }
    //the end of the main fucntion will repeat if the user would like

    cout << "\n Would you like to do another operation y/n?" << endl;
    cin >> choice2;

    if (choice2 == 'y')
    {
        main();
    }
    else
    {
        return 0;
    }
}

header:

#ifndef project1
#define project1


int output(int *matf, int rows1, int cols1);

int addition(int *mat1, int *mat2, int *matf, int rows1, int cols1);

int subtraction(int *mat1, int *mat2, int *matf, int rows1, int cols1);

int multiplication(int *mat1, int *mat2, int *matf, int rows1, int cols1, int rows2, int cols2);

int input(int choice,int rows1,int cols1,int rows2,int cols2,int k, int *mat1, int*mat2, int*matf);
#endif

Solution

  • Your variables are still global variables (declared outside of a function). You should declare them inside of main (although this isn't what's causing the problem).

    The problem now is that you're passing your values to input by value. That means, input is called, the stack is increased, and the values you're sending are copied into the stack space of input. When you modify them in input, they're modified on the stack of input. input then returns, and those updated values are deleted. You need to send references to these variables instead. That means that the address of the variables will be copied to the stack of input, and input will use these addresses to go back to the variable in the main function and update those values directly.

    Change your function signature for input to be

    void input(int& choice, int& rows1, int& cols1, int& rows2, int& cols2, int& k, int *mat1, int* mat2, int* matf);
    

    Note that the return value of input is changed from int to void. This is because when you call it in main, you weren't assigning the return value of input to anything, so I assumed you didn't need it. Any return statements in input will need to be changed to just return; (instead of something like return 0;).

    Note also that there are now ampersands (&) after the first 6 parameters sent to input. This way, input will have their addresses and can change them directly. mat1, mat2, and matf are already being passed as pointers, so they don't need to be changed.

    What's the difference between passing by reference vs. passing by value?