user3540561
user3540561

Reputation: 81

Working with arrays in C++

I am trying to get this simple program to work but I have some errors I don't understand as I am new to C++. I am getting a not declared in scope for my function initialize and am having trouble using arrays in the function header. Can someone help me please?

My code is the following:

#include <iostream>
#include <string>
using namespace std;

char[][] initialize(char[][]);

int main(){

    int array[3][3];
    initialize(array);

    cout << array[0];

    return 0;
}

char[][] initialize(char[][] a){

    for(int i = 0; i < a.length(); i++){
        for(int j = 0; j < a[].length(); j++){
            a[i][j] = '\0';
        }
    }

    return a;

}

Upvotes: 0

Views: 98

Answers (4)

user4581301
user4581301

Reputation: 33931

Trick one: Save yourself the trouble of forward declaring initialize by placing the function definition ahead of main. This eliminates one potential source of errors.

Trick two: Jens beat me to. Use std::array.

Trick three: Use std::vector.

#include <iostream>
#include <string>
#include <vector>
//using namespace std; this can be dangerous. Recommend the following as a replacement
using std::vector;
using std::cout;

void initialize(vector<vector<char>> &a) // pass vector by reference 
{   
    for(int i = 0; i < a.size(); i++)
    {   
        for(int j = 0; j < a[i].size(); j++)
        {   
            a[i][j] = '\0';
        }
    }
}

int main()
{
    vector<vector<char>> array(3, vector<char>(3));
    initialize(array);

    cout << array[0][0];

    return 0;
}

Two points to make here

  1. This has performance problems. A vector of vectors (or an array of arrays) is unlikely to have contiguity (memory all in one block) and will cause unnecessary delays loading array data from RAM to cache. If all the data is close together, and small enough to fit, one cache read will get the whole array. If it is scattered, each piece needs to be read separately and loading one piece may overwrite another forcing it to be loaded again (which may write over another piece of memory needed a few instructions latter, forcing it to be re-read as well and this may force the other piece or yet another piece out, ad infinitum. This is called Cache Thrashing.

  2. std::vector can initialize the array contents for you

Need text here for some reason to preserve the formatting of the next code block. Weird.

int main()
{
    vector<vector<char>> array(3, vector<char>(3), '\0');
    cout << array[0][0];

    return 0;
}

And if because of assignment restriction you are not allowed to use std::array or std::vector, a trivial clone of std::array is easy to write.

struct TwoD
{
    char array[3][3];
    char &operator()(int row, int col)
    {
        return array[row][col];
    }
};

is probably all you need.

Upvotes: 0

Jens
Jens

Reputation: 9406

If you have fixed-size arrays, you can (and should) use std::array instead of raw C-style arrays. I will use you initialize function as an example, although there are other ways to initialize the array.

#include <iostream>
#include <string>
#include <array>
using namespace std;

void initialize(std::array<std::array<char, 3>, 3>&);

int main(){

    std::array<std::array<char, 3>, 3> array{};
    initialize(array);

    return 0;
}

void initialize(std::array<std::array<char, 3>, 3>& a) {
    for(auto& outer: a) {
        for(auto& x: outer) {
             x = '\0';
        }
    }
}

Of course if you want to work with arrays of strings, and this is what I think you actually want, you should do so and use std::string instead of zero-terminated C-style strings.

#include <iostream>
#include <string>
#include <array>


int main(){

    std::array<std::string, 3> array{};
    array.fill( std::string(3, '\0') );

    std::cout << array[0];

    return 0;
}

The initialization is not necessary in this case since std::string is correctly initialized by its constructor.

If you need dynamic storage, you should use a std::vector instead of std::array. In any case, my advice would be to use the type-safe and way more convenient C++ tools instead of the error-prone and - frankly - painfully to use C equivalents.

Upvotes: 1

wrangler
wrangler

Reputation: 3576

Since you know the size of array and passing array by reference so no need to return array:

void initialize(char[][3]);//declaration

Function:

void initialize(char a[][3]){
//no such function as array.lenth()
for(int i = 0; i < 3; i++){
    for(int j = 0; j <3; j++){
        a[i][j] = '\0';
    }
}

Also i can see you have declared an integer array and passed to a char array.So either have an integer array or char array but not both.

Upvotes: 0

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42889

You could initialize your 2d array elements to \0 simply by:

char array[3][3] = {0};

Now if you want to pass your array to a function (e.g., print_2d_array()), and in order to have the dimensions of your 2d array you need to pass your array by reference in the following manner:

template<typename T, std::size_t N, std::size_t M>
void print_2d_array(T (&a)[N][M]){

    for(int i = 0; i < N; ++i){
        for(int j = 0; j < M; ++j){
            std::cout << a[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

The above function prints an arbitrary type/dimensions 2d array.

Upvotes: 1

Related Questions