C/C++ 中是不是存在锯齿状数组?
Posted
技术标签:
【中文标题】C/C++ 中是不是存在锯齿状数组?【英文标题】:Do jagged arrays exist in C/C++?C/C++ 中是否存在锯齿状数组? 【发布时间】:2010-11-08 04:37:44 【问题描述】:C 或 C++ 中是否存在锯齿状数组?
当我编译这个时:
int jagged[][] = 0,1, 1,2,3 ;
我收到此错误:
错误:将“锯齿状”声明为多维数组必须对除第一个维度之外的所有维度都有边界
【问题讨论】:
【参考方案1】:如果你只是想初始化它,你可以说:
int jagged[][3] = 0,1, 1,2,3 ;
但数组仍将具有 [2][3] 的形状。如果您想要一个真正的锯齿状数组,则必须动态创建它。如果你这样做,并且使用 C++,你应该使用 std::vector
,正如 friol 建议的那样。
【讨论】:
【参考方案2】:在 C++ 中(未编译,可能有更紧凑的语法):
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] 等来访问元素。
【讨论】:
【参考方案3】:在 C 中我会使用一个指针数组。
例如:
int *jagged[5];
jagged[0] = malloc(sizeof(int) * 10);
jagged[1] = malloc(sizeof(int) * 3);
等等等等
【讨论】:
在这个例子中,释放内存的正确方法是什么? 免费(锯齿状[0]);免费(锯齿状[1]);【参考方案4】:有很多方法可以做到这一点。这是另一种方式:
int jagged_row0[] = 0,1;
int jagged_row1[] = 1,2,3;
int *jagged[] = jagged_row0, jagged_row1 ;
【讨论】:
+1。这就是 C99 的复合文字大显身手的地方:int *jagged[] = (int[])0,1, (int[])1, 2, 3 ;
是不是也很好?
这个解决方案的问题是子数组会立即衰减为指针,所以你无法知道边界是什么。
@Neil,我完全没有想到这一点。你当然是对的。好点:)
@Neil:这就是监护人值可以派上用场来标记数组末尾的地方
@Christoph Guardian 值对于数字数组可能存在问题,因为可能没有允许的“特殊”值。我认为以某种方式显式存储数组维度是更好的做法。【参考方案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])
不会编译) - 但它们看起来像是锯齿状的;)
【讨论】:
我认为你不能制作不完整类型的数组......哦,你正在制作一个指向不完整类型的指针数组,这是可能的,但不会为你买任何东西超过 rampion 的答案。 【参考方案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】:使用 C++11 初始化列表 this 可以更紧凑地编写:
#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
供参考:
http://en.cppreference.com/w/cpp/utility/initializer_list【讨论】:
【参考方案8】:您还可以使用 c 中的复合文字来初始化一个真正的锯齿状数组,该数组在内存中是连续的,如下所示:
int (*arr[]) = (int []) 0, 1, (int []) 2, 3, 4, (int [])5, 6, 7, 8
这将在内存中连续排列。
【讨论】:
只是出于好奇:您知道需要哪种 C 标准才能工作吗? @Cherusker,C99 确实支持这一点。更多详情请见here。【参考方案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;
【讨论】:
嘿...您可以查看我的代码以在 c++ 中实现锯齿状数组【参考方案10】:通过在 cpp 中使用动态分配,我们可以创建锯齿状数组。
例如:
#include<iostream>
using namespace std;
int main()
int n;
cout<<"Enter n:";
cin>>n;
cout<<"Enter elements:";
int **p = new int *[n];
for(int i=0;i<n;i++)
p[i] = new int[i+1];
for(int j=0;j<(i+1);j++)
cin>>p[i][j];
cout<<"Jagged Array:"<<endl;
for(int i=0;i<n;i++)
for(int j=0;j<(i+1);j++)
cout<<p[i][j]<<" ";
cout<<endl;
for(int i=0;i<n;i++)
delete []p[i];
delete []p;
对于n=3
,我们创建了一个锯齿状数组,如下所示:
输入元素: 1 1 2 1 2 3 锯齿状阵列: 1 1 2 1 2 3
【讨论】:
【参考方案11】:c++/c 中确实存在锯齿状数组,但语法相当复杂,需要处理很多事情。
c++中有两种类型的锯齿状数组。1) STATIC JAGGED ARRAY(一个二维数组,其中大小为常数,每行有不同的列数) . 2) DYNAMIC JAGGED ARRAY(一个二维数组,其大小可以是从用户那里获取的任意数字,并且每行的列数不同)1)实现静态锯齿阵列的步骤
使用数组和指针 1) 用您需要的行数声明一维数组 2) 每个数组(行中元素的数组)的大小将是行中的列数(或元素) 3) 声明一个包含箭头地址的一维指针数组 4) 一维数组的大小就是你想要的锯齿数组中的行数#include<iostream>
#include<string>
using namespace std;
int main()
int row0[4] = 1,2,3,4 ;
int row1[2] = 5,6 ;
int* jagged[2] = row0,row1 ;
int Size[2] = 4,2 , k = 0;
for (int i = 0; i < 2; i++)
int* ptr = jagged[i];
for (int j = 0; j < Size[k]; j++)
cout << *ptr << "";
ptr++;
cout << endl;
k++;
jagged[i]++;
return 0;
输出如下
123456
1)实现动态锯齿阵列的步骤
使用指针数组 1) 声明一个指针数组(锯齿状数组) 2) 该数组的大小将是锯齿状数组中所需的行数 3) 为数组中的每个指针分配内存,以满足您在该行中所需的元素数量。#include<iostream>
#include<string>
using namespace std;
int main()
//2 rows
int* jagged[2];
//Allocate memeory for the elements in the row 0
jagged[0] = new int[1];
//Allocate memory for the elements in row 1
jagged[1] = new int[5];
//Array to hold the size of each row
int Size[2] = 1,5 ,k = 0, number = 100;
//User enters the numbers
for (int i = 0; i < 2; i++)
int* p = jagged[i];
for (int j = 0; j < Size[k]; j++)
*p = number++;
//move the pointer
p++;
k++;
k = 0;
//Display elements in Jagged array
for (int i = 0; i < 2; i++)
int* q = jagged[i];
for (int j = 0; j < Size[k]; j++)
cout << *q << "";
//move the pointer to the next element
q++;
cout << endl;
k++;
//move the pointer to the next row
jagged[i]++;
delete[] jagged[0];
delete[] jagged[1];
return 0;
输出如下
100 101102103104105
【讨论】:
我很确定这应该使用delete[] jagged[0];
和delete[] jagged[1];
,而不是delete[] jagged;
。
@Ruzihm 但是你知道当我们删除一个指针时,所有的索引都会被自动删除,所以我们想删除它们而不是只删除一个我们想要释放内存的索引。希望你理解。谢谢。
用 valgrind 在这个答案中运行代码说 肯定会丢失:2 个块中的 24 个字节,两者都在 operator new[](unsigned long)
。但是,删除jagged[i]++;
并用delete[] jagged[0]; delete[] jagged[1];
替换delete[] jagged;
报告不可能有泄漏。
即使在 g++ 中编译此代码也会发出警告:foo.cpp:49:14: warning: deleting array ‘jagged’ 49 | delete[] jagged;
@Ruzihm 谢谢先生。根据您的建议编辑。以上是关于C/C++ 中是不是存在锯齿状数组?的主要内容,如果未能解决你的问题,请参考以下文章
数组写为 name[x, y] 而不是 name[x][y] [重复]