在C++; 我是Fortran用户,不太熟悉C++。我需要对现有C++代码做一些补充。我需要创建一个类型为double的2d矩阵(例如a),其大小(例如m x n)仅在运行期间已知。使用Fortran,可以按如下方式执行此操作 real*8, allocatable :: A(:,:) integer :: m, n read(*,*) m read(*,*) n allocate(a(m,n)) A(:,:) = 0.0d0 < >如何在C++中创建矩阵A(m,n),当编译时M和N不知道时?我相信C++中的运算符新< /Cord>可以很有用,但不知道如何用双倍实现它。另外,当我在C中使用following时++ int * x; x = new int [10];
使用在C++; 我是Fortran用户,不太熟悉C++。我需要对现有C++代码做一些补充。我需要创建一个类型为double的2d矩阵(例如a),其大小(例如m x n)仅在运行期间已知。使用Fortran,可以按如下方式执行此操作 real*8, allocatable :: A(:,:) integer :: m, n read(*,*) m read(*,*) n allocate(a(m,n)) A(:,:) = 0.0d0 < >如何在C++中创建矩阵A(m,n),当编译时M和N不知道时?我相信C++中的运算符新< /Cord>可以很有用,但不知道如何用双倍实现它。另外,当我在C中使用following时++ int * x; x = new int [10];,c++,arrays,dynamic-arrays,C++,Arrays,Dynamic Arrays,使用sizeof(x)/sizeof(x[0])检查x的大小,我没有10条注释,为什么?要动态分配类似于二维阵列的结构,请使用以下模板 #include <iostream> int main() { int m, n; std::cout << "Enter the number of rows: "; std::cin >> m; std::cout << "Enter the number of columns:
sizeof(x)/sizeof(x[0])检查x的大小
,我没有10条注释,为什么?要动态分配类似于二维阵列的结构,请使用以下模板
#include <iostream>
int main()
{
int m, n;
std::cout << "Enter the number of rows: ";
std::cin >> m;
std::cout << "Enter the number of columns: ";
std::cin >> n;
double **a = new double * [m];
for ( int i = 0; i < m; i++ ) a[i] = new double[n]();
//...
for ( int i = 0; i < m; i++ ) delete []a[i];
delete []a;
}
至于这个代码片段
int * x;
x = new int [10];
然后x
具有类型int*
和x[0]
具有类型int
。因此,如果指针的大小等于4,并且int类型的对象的大小也等于4,那么sizeof(x)/sizeof(x[0])
将产生1。指针不保留信息,不管它们是只指向单个对象还是指向某些对象序列的第一个对象。int**x;
int ** x;
x = new int* [10];
for(int i = 0; i < 10; i++)
x[i] = new int[5];
x=新整数*[10];
对于(int i=0;i<10;i++)
x[i]=新整数[5];
不幸的是,您必须将矩阵的大小存储在其他地方。
C/C++不会为您做这件事。sizeof()仅在编译器知道大小时才起作用,这在动态数组中是不正确的
如果您想用比动态阵列更安全的方法实现它:
#include <vector>
// ...
std::vector<std::vector<int>> vect(10, std::vector<int>(5));
vect[3][2] = 1;
#包括
// ...
std::vector vect(10,std::vector(5));
向量[3][2]=1;
我建议使用std::vector
,避免手动分配和释放内存的所有麻烦
下面是一个示例程序:
#include <iostream>
#include <vector>
typedef std::vector<double> Row;
typedef std::vector<Row> Matrix;
void testMatrix(int M, int N)
{
// Create a row with all elements set to 0.0
Row row(N, 0.0);
// Create a matrix with all elements set to 0.0
Matrix matrix(M, row);
// Test accessing the matrix.
for ( int i = 0; i < M; ++i )
{
for ( int j = 0; j < N; ++j )
{
matrix[i][j] = i+j;
std::cout << matrix[i][j] << " ";
}
std::cout << std::endl;
}
}
int main()
{
testMatrix(10, 20);
}
#包括
#包括
typedef std::向量行;
向量矩阵;
void testMatrix(int M,int N)
{
//创建一行,将所有元素设置为0.0
行(N,0.0);
//创建一个所有元素都设置为0.0的矩阵
矩阵(M,行);
//测试访问矩阵。
对于(int i=0;i STD::CUT< P>正式的C++方式是:
std::vector<std::vector<int>> a;
(您还可以推送
或插入
元素)
我们现在拥有的是一个由10个向量组成的向量。不幸的是,它们都是独立的,因此您需要:
for (size_t i = 0; i < a.size(); ++i) {
a[i].resize(10);
}
请注意,向量是完全动态的,因此我们可以根据需要调整元素的大小:
a[1].push_back(10); // push value '10' onto a[1], creating an 11th element in a[1]
a[2].erase(2); // remove element 2 from a[2], reducing a[2]s size to 9
要获取特定插槽的大小,请执行以下操作:
a.size(); // returns 10
a[1].size(); // returns 11 after the above
a[2].size(); // returns 9 after teh above.
遗憾的是,C++没有提供一种强大的、一流的方式来分配一个保持大小信息的数组。但是,您可以在堆栈上创建一个简单的C样式数组:
int a[10][10];
std::cout << "sizeof a is " << sizeof(a) <<'\n';
此时,“指针”是一个数值,为零表示内存不足,或者表示内存中第一个连续的10个整数存储空间所在的位置
指针装饰器语法的使用告诉编译器,这个整数值将被用作存储地址的指针,因此允许通过变量进行指针操作
这里最重要的是,我们只有一个地址,而最初的C标准没有指定内存分配器如何跟踪大小信息,因此无法检索大小信息。(好的,从技术上讲是这样的,但它需要使用编译器/os/实现特定的信息,这些信息会经常更改)
在与内存分配系统接口时,必须将这些整数视为单个对象——例如,您不能:
delete pointer + 5;
删除第5个整数。它们是一个分配单元
;这个概念允许系统跟踪块而不是单个元素
删除数组时,C++语法为
delete[] pointer;
要分配二维数组,您需要:
展平阵列并自行调整大小/偏移:
static const size_t x = 10, y = 10;
int* pointer = new int[x * y];
pointer[0] = 0; // position 0, the 1st element.
pointer[x * 1] = 0; // pointer[1][0]
或者你可以用
int access_2d_array_element(int* pointer, const size_t xSize, const size_t ySize, size_t x, size_t y)
{
assert(x < xSize && y < ySize);
return pointer[y * xSize + x];
}
int-access\u 2d\u-array\u元素(int*指针、常量大小、常量大小、大小)
{
断言(x
这是一种痛苦,因此您可能会被引导到封装:
class Array2D
{
int* m_pointer;
const size_t m_xSize, m_ySize;
public:
Array2D(size_t xSize, size_t ySize)
: m_pointer(new int[xSize * ySize])
, m_xSize(xSize)
, m_ySize(ySize)
{}
int& at(size_t x, size_t y)
{
assert(x < m_xSize && y < m_ySize);
return m_pointer[y * m_xSize + x];
}
// total number of elements.
size_t arrsizeof() const
{
return m_xSize * m_ySize;
}
// total size of all data elements.
size_t sizeof() const
{
// this sizeof syntax makes the code more generic.
return arrsizeof() * sizeof(*m_pointer);
}
~Array2D()
{
delete[] m_pointer;
}
};
Array2D a(10, 10);
a.at(1, 3) = 13;
int x = a.at(1, 3);
类数组2d
{
int*m_指针;
常量大小、大小、大小;
公众:
Array2D(大小X大小,大小Y大小)
:m_指针(新int[xSize*ySize])
,mxsize(xSize)
,m_ySize(ySize)
{}
内部和外部(尺寸x,尺寸y)
{
断言(x
或者
对于每个第N维(N
const size_t xSize = 10, ySize = 10;
int* pointer = new int*(x); // the first level of indirection.
for (size_t i = 0; i < x; ++i) {
pointer[i] = new int(y);
}
pointer[0][0] = 0;
for (size_t i = 0; i < x; ++i) {
delete[] pointer[i];
}
delete[] pointer;
const size_t xSize=10,ySize=10;
int*pointer=new int*(x);//第一级间接寻址。
对于(尺寸i=0;i
最后一个或多或少做着同样的工作,它只是比前一个产生了更多的内存碎片
-----------编辑-----------
回答“为什么我没有10”的问题,你可能是用64位模式编译,这意味着“x”是一个10个指针的数组,因为你在64位模式中,指针是64位长,而INT是32位。
< P>你的FORTRAN代码的C++等价物是:
int cols, rows;
if ( !(std::cin >> cols >> rows) )
// error handling...
std::vector<double> A(cols * rows);
特别注意,通过避免newint access_2d_array_element(int* pointer, const size_t xSize, const size_t ySize, size_t x, size_t y)
{
assert(x < xSize && y < ySize);
return pointer[y * xSize + x];
}
class Array2D
{
int* m_pointer;
const size_t m_xSize, m_ySize;
public:
Array2D(size_t xSize, size_t ySize)
: m_pointer(new int[xSize * ySize])
, m_xSize(xSize)
, m_ySize(ySize)
{}
int& at(size_t x, size_t y)
{
assert(x < m_xSize && y < m_ySize);
return m_pointer[y * m_xSize + x];
}
// total number of elements.
size_t arrsizeof() const
{
return m_xSize * m_ySize;
}
// total size of all data elements.
size_t sizeof() const
{
// this sizeof syntax makes the code more generic.
return arrsizeof() * sizeof(*m_pointer);
}
~Array2D()
{
delete[] m_pointer;
}
};
Array2D a(10, 10);
a.at(1, 3) = 13;
int x = a.at(1, 3);
const size_t xSize = 10, ySize = 10;
int* pointer = new int*(x); // the first level of indirection.
for (size_t i = 0; i < x; ++i) {
pointer[i] = new int(y);
}
pointer[0][0] = 0;
for (size_t i = 0; i < x; ++i) {
delete[] pointer[i];
}
delete[] pointer;
int cols, rows;
if ( !(std::cin >> cols >> rows) )
// error handling...
std::vector<double> A(cols * rows);
struct FortranArray2D // actually easily extensible to any number of dimensions
{
FortranArray2D(size_t n_cols, size_t n_rows)
: n_cols(n_cols), n_rows(n_rows), content(n_cols * n_rows) { }
double &operator()(size_t col, size_t row)
{ return content.at(row * n_rows + col); }
void resize(size_t new_cols, size_t new_rows)
{
FortranArray2D temp(new_cols, new_rows);
// insert some logic to move values from old to new...
*this = std::move(temp);
}
private:
size_t n_rows, n_cols;
std::vector<double> content;
};