所以我上周开始学习C ++,当然,我想熟悉整个指针和面向对象的业务等等。
为此,我为一些基本矩阵计算编写了一个非常简单的程序:
# include <iostream>
using std::cout;
using std::cin;
class Matrix {
int columns; // x
int rows; // y
double* matrix;
public:
Matrix (int*);
void printMatrix();
void free() {
delete[] matrix;
return;
};
};
Matrix::Matrix(int* dim){
rows = *dim;
columns = *(dim + 1);
matrix = new double [columns*rows];
}
void Matrix::printMatrix(){
int i, j;
for(i = 0; i < columns; i++){
for(j=0; j < rows; j++){
cout << matrix[columns*i + j] << " ";
}
cout << "\n";
}
return;
}
int* getMatrix ();
int main () {
Matrix matrix (getMatrix());
matrix.printMatrix();
matrix.free();
return 0;
}
int* getMatrix (){
int* dim = new int [2];
cout << "(m x n)-Matrix, m? ";
cin >> dim[0];
cout << "n? ";
cin >> dim[1];
return dim;
}
当我选择(4,2)矩阵时,会出现问题(如我所见)。据我从各种教程中了解,
matrix = new double [columns*rows];
应该分配这么多内存:列*行次 sizeof(double)。此外,每个小区&#39;应使用 0 初始化。
但是,选择一个(4,2)矩阵,得到函数printMatrix()的以下输出:
0 0
0 0
0 6.6727e-319
0 0
为什么(3,2)条目未使用 0 初始化?
谢谢!
答案 0 :(得分:3)
此外,每个小组&#39;应该用0初始化。
不。当您编写new double[N]
时,该语言不适合您。
为什么(3,2)条目没有用0初始化?
如果,你会写new double[N]()
而不是!
[C++11: 5.3.4/15]:
创建类型为T
的对象的 new-expression 按如下方式初始化该对象:
- 如果省略 new-initializer ,则对象为 default-initialized (8.5);如果没有执行初始化,则该对象具有不确定的值。
- 否则, new-initializer 将根据8.5的 direct-initialization 的初始化规则进行解释。
当然,这有点含糊不清,因为它似乎在讨论new
的非数组版本,但实际上它意味着两者; T
为double[4]
。
事实上,我们可以看到相同的措辞部分谈论&#34;对象&#34;在数组和非数组的情况下,设置完美的先例:
[C++11: 5.3.4/1]:
[..] 如果实体是非数组对象, new-expression 将返回指向所创建对象的指针。如果是数组,则为new-expression 返回指向数组初始元素的指针。
现在,证明这条规则基本上是不可能的,因为即使这些值实际上是不确定的,你也可能发现不幸并获得全零,但下面的代码完全无法令人信服一个好的开始:
#include <iostream>
#include <vector>
int main() {
const std::size_t n = 4;
{
std::vector<double> hack;
hack.push_back(5);
hack.push_back(6);
hack.push_back(7);
hack.push_back(8);
hack.push_back(9);
hack.push_back(10);
hack.push_back(11);
hack.push_back(12);
}
double* a = new double [n];
double* b = new double [n]();
for (std::size_t i = 0; i < n; i++)
std::cout << a[i] << '/' << b[i] << ' ';
std::cout << '\n';
delete[] a;
delete[] b;
}
我设法从中获得0/0 6/0 7/0 8/0
,这要归功于一些堆乱,但它仍然只是纯粹的机会,并没有真正展示任何东西(live demo)。 / p>
不幸的是,new double[4](316)
无效(根据()
,在直接初始化期间,[C++11: 8.5/16]
内的值被明确禁止用于数组)所以我们不能建议new double[4](0)
是可靠的,并使用316
的示例来说服你。
答案 1 :(得分:2)
在C ++中,只有静态变量初始化为0 自动和动态变量应由您初始化。