简体   繁体   中英

Matrix multiplication not working in C++

I made a program that calculates product of all elements in column of a 2D array and stores that value in another 1D array. This is my code:

void product_of_col(int n)
{
    int i, j, product;
    for(i = 0; i < n; i++)
    {
        product = 1;
        for(j = 0; j < n; j++)
            product *= a[j][i];
        b[i] = product;
    }
}

This function works fine, but when I change

for(j = 0; j < n; j++)
    product *= a[j][i];

to

for(j = 0; j < n; j++, product *= a[j][i]);

every product is equal to 0. I runned this code on Ideone and it didn't work. I also made a function that calculates the sum of all elements in the same column and it works fine for both codes.

Can anyone tell me why isn't the second code working?

You got the order wrong. Replace for(j = 0; j < n; j++, product *= a[j][i]); with for(j = 0; j < n; product *= a[j][i], j++);

请注意,由于逗号运算符的工作方式,在第二个代码段中,表达式j++在表达式product *= a[j][i] 之前执行。

Alright, this is something that you (probably) didn't learn in your C++ class. I know I sure as heck didn't.

the comma operator

You probably know about the term "operator" in c++. You have +-=*/, ect. What you probably DIDN'T know is there is an comma operator ( , ). What the heck does the comma operator do? Whell basically, it evaluates everything in a statement, but returns only the first value. so i can do

int a = 1,2,3,4;

and a will only equal 1. Additionally, I can do

int x = 5; int y = 10;
int z = (y*=2), (x*=2);
std::cout << x << ',' << y << ',' << z << std::endl;

which will output 10, 20, and 20. What you are ACTUALLY doing in a for loop is calling this comma operator. In your case, we are looking at the statement

j++, product *= a[j][i]

I find it helpful to think of this as the following call:

const int& comma_operator(const int& a,const int& b) {return a;} comma_operator(j++,produce*=a[j][i]);

Now that you understand what the comma is actually doing, lets look at the concept of order of evaluation.

order of evaluation

C++ makes NO promises on what order arguments to a function call or operator is called, just that they are all called before the function or operator is run. This may seem counter intuitive: you may be thinking to yourself, why doesn't it just run from left to right?

Well, this would tie the hand of the compiler in a lot of cases where it could optimize the crap out of your code. The common example would be:

int x; int y; int z = x/y+x%y.

In this case, most CPU's can calculate x/y and x%y with the same instruction. Certainly, this doesn't make sense to you, but the first argument to plus and the second argument to plus are calculated at the SAME time rather than sequentially.

C++ only guarantees that the code will behave the same as you wrote it logically, not exactly as you wrote it. And operand evaluation order is not part of that logic.

So just use for(j = 0; j < n; j++) product *= a[j][i]; and you'll be happy.

Can anyone tell me why isn't the second code working?

In your second code,

for(j = 0; j < n; j++, product *= a[j][i]);

You are incrementing j before product *= a[j][i]) executes.So,Just change the order like :

for(j = 0; j < n; product *= a[j][i], j++);   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM