0

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
Gomi
  • 3
  • 3
  • 1. How do you know your global variables are not being updated? To verify this, use your debugger!!! 2. Global variables are evil, avoid them when you can (which is most times). – JohnFilleau Feb 28 '20 at 22:30
  • I tested by putting ```cout< – Gomi Feb 28 '20 at 22:37
  • Are your main and input functions in different compilation units (.cpp files)? – JohnFilleau Feb 28 '20 at 22:41
  • yeah, i have a definition file for my header file – Gomi Feb 28 '20 at 22:44
  • 5
    If you have a `main.cpp` and an `input.cpp`, and they both `#include "project1.h"`, then there will be two instances of each of the static variables you declared in your `.h` file. To avoid this, use `extern` instead of `static` in the `.h` file, and initialize the variables in only one of the `.cpp` files (probably in `main.cpp`). Better yet - don't use global variables!!! – JohnFilleau Feb 28 '20 at 22:46
  • Ok i just finished switching everything to local variables and i have the exact same issue. – Gomi Feb 28 '20 at 23:44
  • update your question with your new code. Be sure to include the part where you output `cols1` after inputting it, so we can be sure you're doing it correctly. – JohnFilleau Feb 28 '20 at 23:45
  • When you update your code, you have an opportunity to simplify your example (c.f. [mre]). Don't prompt the user, and don't get the data from the user. Instead, simply assign a sample set of values, as in `rows1 = 8;`. – JaMiT Feb 28 '20 at 23:47
  • just edited it, its right after calling input in main() – Gomi Feb 28 '20 at 23:49

1 Answers1

0

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?

JohnFilleau
  • 4,045
  • 1
  • 15
  • 22