0

I'm working on a program to solve an Economics model. First, I declare a namespace as follows:

namespace myNameSpace
{
    const int d1{10};
    const int d2{5};
    const int d3{7};
    double array[d1][d2][d3]={};
}

Then, I have a function that modifies array:

void doSomething(double (&array)[myNameSpace::d1][myNameSpace::d2][myNameSpace::d3])
{
    int i,j,k;
    for (i=0, j=0, k=0; i<myNameSpace::d1,j<myNameSpace::d2,k<myNameSpace::d3; i++,j++,k++)
        array[i][j][k]=i+j+k+1.0;
}

In the main function I call doSomething as:

int main()
{
    doSomething(myNameSpace::array);
    for (int i=0;j<myNameSpace::d1;j++)
        std::cout << myNameSpace::array[i][1][1] << std::endl;
}

The output I get in the console is:

0
0
0

Can you provide any guidance on this? I've tried passing array without the address-of operator &, but then inside doSomething, array losses the first dimension. Any help will be highly appreciated!!

Boiethios
  • 38,438
  • 19
  • 134
  • 183

4 Answers4

2

First of all, your for loop

for (i=0, j=0, k=0; i<myNameSpace::d1,j<myNameSpace::d2,k<myNameSpace::d3; i++,j++,k++)

doesn't do what you think it does, and you would've (hopefully) noticed that if you compiled with warnings (warning: relational comparison result unused).

It has 2, related, major problems:

  1. Since i<myNameSpace::d1,j<myNameSpace::d2,k<myNameSpace::d3 only returns the value of the last comparison, due to the comma operator being used. So, you are effectively iterating until k<myNameSpace::d3.

  2. The for loop you wrote - is just a single loop. It doesn't iterate through all possible combinations of values of i, j, and k, as you might have wanted.

    It initializes i, j, k to 0; checks comparison expression (which, as explained by (1) only checks the value of k); and after the code in the loop was run - increments all of i, j, k by 1. Hence - you are setting only the 0/0/0, 1/1/1, 2/2/2, ..., up until k/k/k indices of your array. And, because your middle array has a bound, which is smaller than k - you invoke undefined behavior by stepping out of bounds.

And, lastly, you are printing only the i/1/1 index of your array, and since the only one value in the index range 0/1/1-d1/1/1 that's set is 1/1/1 - it is, exactly what's printed with a non-zero value.

To iterate over the whole array, as, might have been your intention - you should use nested loops, so they would allow all of the loop variables to change independently of one another:

for (i=0; i<myNameSpace::d1; i++)
    {
    for (j=0; j<myNameSpace::d2; j++)
        {
        for (k=0; k<myNameSpace::d3; k++)
            {
            array[i][j][k]=i+j+k+1.0;
            }
        }
    }
Community
  • 1
  • 1
Algirdas Preidžius
  • 1,769
  • 3
  • 14
  • 17
0

I tried to compile your code, and I got an error in this line:

for (int i=0;j<myNameSpace::d1;j++)

The variable j is undeclared. As you can note, you declared the variable i inside the for loop, but not j. Do you want to loop using i or j? ...Maybe it's i because inside the body of the loop you used it as first-dimension index?

So, maybe you meant this code?

for (int i = 0; i < myNameSpace::d1; i++)
    std::cout << myNameSpace::array[i][1][1] << std::endl;

In addition, are you sure the loop inside doSomething does what you mean?

Or maybe you want to loop using three nested loops for each array dimension? E.g.:

void doSomething(double (&array)[myNameSpace::d1][myNameSpace::d2][myNameSpace::d3])
{   
    for (int i = 0; i < myNameSpace::d1; i++) {
        for (int j = 0; j < myNameSpace::d2; j++) {
            for (int k = 0; k < myNameSpace::d3; k++) {
                array[i][j][k] = i + j + k + 1.0;
            }
        }
    }
}

Note that in C++ raw arrays are passed by reference, so the &array syntax is unnecessary. Moreover, the compiler also ignores the raw array dimensions (myNameSpace::d1, etc.) for array parameters. Those may be good for documentation purposes though.

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
0

If your array declared with those sizes it's way shorter (and readable)to write:

void doSomething( declspec(myNameSpace::array) &array )

or much better to declare type alias to use it everywhere:

using  myArrayType = double[myNameSpace::d1][myNameSpace::d2][myNameSpace::d3];

not to mention that d1,d2 and d3 should be const. Toset ALL elements of array your loops should look like this:

void doSomething( myArrayType &array )
{
   int i,j,k;
   for ( i = 0; i < myNameSpace::d1; i++)
     for ( j = 0; j < myNameSpace::d2; j++)
      for (k = 0; k < myNameSpace::d3; k++)
         array[i][j][k]=i+j+k+1.0;
}

Everything written in single for divided by comma is happening in single iteration. There are perverted ways to write it in single for() but I don't recommend that code. for() loop is very flexible. pretty much it looks like

for(expressionFirst; expressionCheck; expressionEach )
    statement to execute

expressionFirst can be ANY statement OR a single declaration, it executes only once, before loop starts. expressionCheck executed at beginning of each iteration, it must be any expression that is contextually convertible to bool (i.e. if even explicit T::operator bool() const; is applicable in this case), if it returns false, the loop stops. expressionEach is any expression that evaluates at end of each iteration.

Equivalent of for()

{
   expressionFirst
   while ( expressionCheck ) 
   { 
     statement to execute
     expressionEach; 
   }  
} 

All expressions are optional, so you can use for(;;) - a "forever" loop.

Comma operator you use allows to sequence several expressions, only last one is returned as result. Thus it is called sequence operator. And that's why your loop is wrong.

And you have a typo in main function, which led you to print only the first element of array, no increment of i.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
0

for start you have a problem with your for loop initialize i and running over j. once I changed it, I received some values.

maayanwis
  • 5
  • 3