8

Trying to learn C++ and working through a simple exercise on arrays.

Basically, I've created a multidimensional array and I want to create a function that prints out the values.

The commented for-loop within Main() works fine, but when I try to turn that for-loop into a function, it doesn't work and for the life of me, I cannot see why.

#include <iostream>
using namespace std;


void printArray(int theArray[], int numberOfRows, int numberOfColumns);

int main()
{

    int sally[2][3] = {{2,3,4},{8,9,10}};

    printArray(sally,2,3);

//    for(int rows = 0; rows < 2; rows++){
//        for(int columns = 0; columns < 3; columns++){
//            cout << sally[rows][columns] << " ";
//        }
//        cout << endl;
//    }

}

void printArray(int theArray[], int numberOfRows, int numberOfColumns){
    for(int x = 0; x < numberOfRows; x++){
        for(int y = 0; y < numberOfColumns; y++){
            cout << theArray[x][y] << " ";
        }
        cout << endl;
    }
}
1

4 Answers 4

7

C++ inherits its syntax from C, and tries hard to maintain backward compatibility where the syntax matches. So passing arrays works just like C: the length information is lost.

However, C++ does provide a way to automatically pass the length information, using a reference (no backward compatibility concerns, C has no references):

template<int numberOfRows, int numberOfColumns>
void printArray(int (&theArray)[numberOfRows][numberOfColumns])
{
    for(int x = 0; x < numberOfRows; x++){
        for(int y = 0; y < numberOfColumns; y++){
            cout << theArray[x][y] << " ";
        }
        cout << endl;
    }
}

Demonstration: http://ideone.com/MrYKz

Here's a variation that avoids the complicated array reference syntax: http://ideone.com/GVkxk

If the size is dynamic, you can't use either template version. You just need to know that C and C++ store array content in row-major order.

Code which works with variable size: http://ideone.com/kjHiR

Sign up to request clarification or add additional context in comments.

4 Comments

To be pedantic, using references increases backward compatibility concerns, since C has no references :P
@Tomalek: Backward compatibility states that existing valid C code should still do the same thing when compiled as C++. This isn't valid C code, so there's no requirement to behave the same way as C.
That printArray(*sally, 2, 3); implementation is what I was alluding to... but I got it completely wrong! Thanx for the fish.
@corlettk: Oh, ok.... I thought you meant jagged array style, and I read your comment twice. The version with *sally does require the dimensions (except the first) to be known at compile time, they're just hidden in the type T inferred by the compiler.
2

Since theArray is multidimensional, you should specify the bounds of all its dimensions in the function prototype (except the first one):

void printArray(int theArray[][3], int numberOfRows, int numberOfColumns);

3 Comments

... or pass the matrix as an array of pointers-to-int-array... which is one alternative when you don't know (at "write time", ie when you are writing the printArray method) what the subsequent-dimension(s) are. Another alternative is to #define the subsequent-dimension(s). I prefer the latter approach, where possible.
@corlettk: A C++ (or C) multidimensional array is not an array of pointers.
@corlettk: Which is not to say you couldn't do things that way, you'd just have to set up the pointer array first.
1

I'm aware of the date of this post, but just for completeness and perhaps for future reference, the following is another solution. Although C++ offers many standard-library facilities (see std::vector or std::array) that makes programmer life easier in cases like this compared to the built-in array intrinsic low-level concepts, if you need anyway to call your printArray like so:

printArray(sally, 2, 3);

you may redefine the function this way:

void printArray(int* theArray, int numberOfRows, int numberOfColumns){
    for(int x = 0; x < numberOfRows; x++){
        for(int y = 0; y < numberOfColumns; y++){
            cout << theArray[x * numberOfColumns + y] << " ";
        }
        cout << endl;
    }
}

In particular, note the first argument and the subscript operation:

  • the function takes a pointer, so you pass the name of the multidimensional array which also is the address to its first element.

  • within the subscript operation (theArray[x * numberOfColumns + y]) we access the sequential element thinking about the multidimensional array as an unique row array.

3 Comments

Exactly what i was searching for. Could you explain a little bit more the way you computed the formula between brackets?
@Cătălina Sîrbu, as stated by the second point of the ending list, the formula returns the integer of the current element if you traverse the array thinking to it as a one dimensional array. If that is not yet clear, you should before understand how arrays, and particularly multidimensional arrays, are effectively stored in memory. Tell me if you need further explanations.
i got it finnaly
0

If you pass array as argument you must specify the size of dimensions except for the first dim. Compiler needs those to calculate the offset of each element in the array. Say you may let printArray like

void printArray(int theArray[][3], int numberOfRows, int numberOfColumns){
    for(int x = 0; x < numberOfRows; x++){
        for(int y = 0; y < numberOfColumns; y++){
            cout << theArray[x][y] << " ";
        }
        cout << endl;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.