Имеются ли зубчатые массивы в C/С++?

Есть ли такая вещь, как зубчатый массив на C или С++?

Когда я скомпилирую это:

int jagged[][] = { {0,1}, {1,2,3} };

Я получаю эту ошибку:

error: объявление `jagged 'как многомерного массива должно иметь границы для всех измерений, кроме первого

Ответ 1

В C я бы использовал массив указателей.

Например:

int *jagged[5];

jagged[0] = malloc(sizeof(int) * 10);
jagged[1] = malloc(sizeof(int) * 3);

и т.д.

Ответ 2

Там есть множество способов сделать это. Здесь другой способ:

int jagged_row0[] = {0,1};
int jagged_row1[] = {1,2,3};
int *jagged[] = { jagged_row0, jagged_row1 };

Ответ 3

Если вы просто хотите его инициализировать, вы можете сказать:

int jagged[][3] = { {0,1}, {1,2,3} };

но массив все равно будет иметь форму [2] [3]. Если вам нужен истинный зубчатый массив, вам придется его динамически создавать. И если вы это сделаете и используете С++, вы должны использовать std::vector, как предполагает фриол.

Ответ 4

В С++ (не скомпилированный и, возможно, более компактный синтаксис):

std::vector<std::vector<int> > myArray;

myArray.push_back(std::vector<int>());
myArray.push_back(std::vector<int>());

myArray[0].push_back(0);
myArray[0].push_back(1);

myArray[1].push_back(1);
myArray[1].push_back(2);
myArray[1].push_back(3);

Итак, теперь вы можете получить доступ к элементам с помощью, например, myArray [0] [0] и т.д.

Ответ 5

В C99 вы можете сделать следующее:

int jagged_row0[] = {0,1};
int jagged_row1[] = {1,2,3};

int (*jagged[])[] = { &jagged_row0, &jagged_row1 }; // note the ampersand

// also since compound literals are lvalues ...
int (*jagged2[])[] = { &(int[]){0,1}, &(int[]){1,2,3} };  

Единственная разница здесь (по сравнению с ответом на rampion) заключается в том, что массивы не распадаются на указатели, и приходится обращаться к отдельным массивам через другой уровень косвенности - (например, *jagged[0] - и размер каждой строки должен быть записан - т.е. sizeof(*jagged[0]) не будет компилироваться) - но они зубчатые - появляются в кости;)

Ответ 6

Причина, по которой вы получили сообщение об ошибке, заключается в том, что вы должны указать границы для, по крайней мере, внешнего измерения; то есть.

int jagged[][3] = {{0,1},{1,2,3}};

Вы не можете иметь jagged [0] быть 2-элементным массивом int и jagged [1] быть 3-элементным массивом int; массив N элементов - это другой тип из массива M-элементов (где N!= M), и все элементы массива должны быть одного типа.

Что вы можете сделать, это то, что другие предложили выше, и создать зазубренный массив массивов указателей на int; таким образом, каждый элемент может указывать на целые массивы разных размеров:

int row0[] = {0,1};
int row1[] = {1,2,3};
int *jagged[] = {row0, row1};

Несмотря на то, что row0 и row1 являются разными типами (2-элементные и 3-элементные массивы int), в контексте инициализатора оба они неявно преобразуются в один и тот же тип (int *).

Ответ 7

С списками инициализаторов С++ 11 этот можно записать более компактно:

#include <vector>
#include <iostream>

int main() {
    // declare and initialize array
    std::vector<std::vector<int>> arr = {{1,2,3}, {4,5}};
    // print content of array
    for (auto row : arr) {
        for (auto col : row)
            std::cout << col << " ";
        std::cout << "\n";
    }
}

Вывод:

$ g++ test.cc -std=c++11 && ./a.out
1 2 3 
4 5 

Для справки:

Ответ 8

Вы также можете использовать составные литералы в c для инициализации действительно зубчатого массива, который непрерывен в памяти следующим образом:

int (*arr[]) = { (int []) {0, 1}, (int []){ 2, 3, 4}, (int []){5, 6, 7, 8} }

Это будет выложено непрерывно в памяти.

Ответ 9

//
//jaggedArrays.cpp
//
//program to implement jagged arrays in c++
//
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
    int rows, i, j;
    cout << endl << "Enter no of rows : ";
    cin >> rows;

    int columnsSizeOfEachRow[rows];

    cout << endl;
    for( i = 0 ; i < rows ; i++ )
    {
        cout << "Enter column size for row no " << i + 1 << " : ";
        cin >> columnsSizeOfEachRow[i];
    }

    int *jaggedArray[rows];
    for (i = 0 ; i < rows ; i++)
        jaggedArray[i] = new int[columnsSizeOfEachRow[i]];

    cout << endl;
    for(i = 0 ; i < rows ; i++)
    {
        for ( j = 0 ; j < columnsSizeOfEachRow[i] ;j++)
        {
            cout << "Array[" << i + 1 << "][" << j + 1 << "] << ";
            cin >> jaggedArray[i][j];
        }
        cout << endl;
    }

    cout << endl << endl << "Jagged array is as follows : " << endl;
    for( i = 0 ; i < rows ; i++)
    {
        for ( j = 0 ; j < columnsSizeOfEachRow[i] ;j++)
            cout << setw(3) <<jaggedArray[i][j] << " ";
        cout << endl;
    }    

    return 0;
}