I have a two-dimensional templated array of integers that I need to perform division on and convert to doubles (in order to create a percentage). It is being passed to my function in the function definition as
int votesarr[4][2]
For each int in the array, I need to run a for loop (I assume) to divide the number by 10,000 and cout the resulting double value.
I'm unsure how to work this with the conversion as well as what I need to pass to the function that I haven't already (if anything).
This should do:
int arint[4][2] { {1,2},{ 2,3 },{0,1},{0,2} }; //example intarray arint[x][y];
for (auto &x : arint)for (auto &y : x)std::cout << y / 10000.0 << std::endl;
This will iterate each of arint[x] and for them each of arint[y], and output those with a line seperating. I just left the formatting as basic as possible. The .0 after 10.000 will output the result with decimals.
Based on the extra information you provided in the comments, here is a simple way to just iterate through the int matrix and output the values as floating-point values.
const std::size_t rows = 4;
const std::size_t cols = 2;
double divisor = 10000.0;
int votesarr[rows][cols]; // fill this somewhere...
for (std::size_t i = 0; i < rows; ++i) {
for (std::size_t j = 0; j < cols; ++j)
std::cout << static_cast<double>(votesarr[i][j])/divisor << ' ';
std::cout << '\n';
}
That said, if you are passing votesarr around to different functions then I'd advise to use either:
std::array<std::array<int, 2>, 4> votesarr; // compile time dimensions known
or
std::vector<std::vector<int>> votesarr(4, std::vector<int>(2));
to make it simpler, instead of using C-style arrays which decay to pointers when passing to methods (preventing proper use of sizeof to determine dimensions, forcing you to pass the rows, cols to the functions).
so you need something like:
double percentage = (double)votesarr[i][j]/10000.0;
std::cout >> percentage >> std::endl;
the (double) tells the compiler that you want to cast this to a double. You can do this with (char), (int), (customType) etc...
However, division is a special case--because my 10000.0 has that ".0" at the end, the compiler treats it as a double, and (int) / (double) is treated like (double)/(double)
#include <iostream>
using namespace std;
int main()
{
int votesarr[4][2] = {{1,1},{1,1},{1,1},{1,1}};
double result[4][2];
double temp;
for (int i = 0; i <= 3; i++) {
for (int j = 0; j <= 1; j++) {
temp = votesarr[i][j];
temp = temp/10000;
result[i][j] = temp;
}
}
// I just filled out the arrays by i+j
//then you need to divide each one by 10,000
//
return 0;
}
Related
I am trying to write a function to extract a slice from a given matrix, where the input is 1D and the slice can be 1D or 2D.
I am trying to use the push_back function for this purpose but for some reasons the push_back does not work.
I receive an error in my line OutPut.push_back(DumyValue);
Can anyone help me why I am receiving this error?
Also, it would be appreciated if you can tell me how to solve this issue.
Also, if the first part becomes clear, can anyone tell me how I should use the push_back for inserting an integer in a specific location so I can use it for extracting a 2D slice?
If you remove the line OutPut.push_back(DumyValue); the code should work.
#include<iostream>
#include<vector>
using namespace std;
int MatrixSlice(vector<vector<int>> Input, int Row1, int Row2, int Col1, int Col2) {
//define the slice size, if it is iD or 2D
if (abs(Row1-Row2)>1 && abs(Col1-Col2)>1){
vector<vector<int>> OutPut;
}else{
vector<int> OutPut;
}
int i2;
int j2;
for (int i = Row1; i <= Row2; i++) {
i2=0;
for (int j = Col1; j <= Col2; j++) {
int DumyValue=Input[i][j];
OutPut.push_back(DumyValue);
i2++;
//cout << Input[i][j] << endl;
}
j2++;
}
return 0;
}
int main() {
//Define a matrix for test:
vector<vector<int>> Matrix2(4, vector<int>(5, 1));
int R = 4;
int C = 4;
vector<vector<int>> MatrixInput(R, vector<int>(C, 1));;
for (int i = 0; i < MatrixInput.size(); i++) {
for (int j = 0; j < MatrixInput[0].size(); j++) {
int temp;
temp = i^2+j^2;
MatrixInput[i][j] = temp;
}
}
MatrixSlice(MatrixInput, 0, 3, 1, 1);
printf("\n");
return 0;
}
Matrix slice has a couple problems:
It is impossible define a variable with two possible types and have both active in the same scope.
The return type of int makes little sense. The matrix is sliced up, but then what? It can't be handed back to the caller to do anything with it.
This can be fixed with a union, but yikes! The bookkeeping on that will be a Smurfing nightmare. Don't do it!
The next is to always use a vector of vectors, but I don't like that idea for a couple reasons I'll get into below.
Instead I pitch a simple wrapper object around a single vector. This is done for two reasons:
It preserves the ability to back a 1 dimensional matrix with a 1 dimensional container. If you have many rows of one column, all of the row data remains contiguous and cache friendly.
It tends to be much faster. The data of one vector is contiguous in memory and reaps the rewards of cache friendliness. A vector of vectors is basically a list of pointers to arrays of data, sending the poor CPU on an odyssey of pointer-chasing through memory to find the columns. If the columns are short, this can really, really hurt performance.
Here we go:
template<class TYPE>
class Matrix
{
private:
size_t mNrRows; // note size_t. This is unsigned because there is no reason
// for a matrix with a negative size. size_t is also guaranteed
// to fit anything you can throw at it.
size_t mNrColumns;
std::vector<TYPE> mVec;
public:
// make a default-initialized matrix
Matrix(size_t nrRows, size_t nrColumns) :
mNrRows(nrRows), mNrColumns(nrColumns), mVec(mNrRows * mNrColumns)
{
}
// make a def-initialized matrix
Matrix(size_t nrRows, size_t nrColumns, TYPE def) :
mNrRows(nrRows), mNrColumns(nrColumns), mVec(mNrRows * mNrColumns,
def)
{
}
// gimme a value and allow it to be changed
TYPE & operator()(size_t row, size_t column)
{
// could check for out of bounds and throw an exception here
return mVec[row * mNrColumns + column];
}
//gimme a value and do not allow it to be changed
TYPE operator()(size_t row, size_t column) const
{
return mVec[row * mNrColumns + column];
}
// gimme the number of rows
size_t getRows() const
{
return mNrRows;
}
// gimmie the number of columns.
size_t getColumns() const
{
return mNrColumns;
}
// printing convenience
friend std::ostream & operator<<(std::ostream & out, const Matrix & mat)
{
int count = 0;
for (TYPE val: mat.mVec)
{
out << val;
if (++count == mat.mNrColumns)
{
out << '\n';
count = 0;
}
else
{
out << ' ';
}
}
return out;
}
};
The vector member handles all of the heavy lifting so the Rule of Zero recommends leaving the copy and move constructors, assignment operators, and destructor up to the compiler.
What does this do to MatrixSlice? Well, first it now received and returns a Matrix instead of vector<vector> and int. The insides use Matrix and the confusion about 1D or 2D is just plain gone, resulting in a simpler function.
Matrix<int> MatrixSlice(const Matrix<int> & Input,
int Row1,
int Row2,
int Col1,
int Col2)
{
Matrix<int> OutPut(Row2-Row1 + 1,
Col2-Col1 + 1); // but what if Row1 > Row2?
int i2;
int j2= 0; // definitely need to initialize this sucker.
for (int i = Row1; i <= Row2; i++) // logical problem here: What if Row2 >= input.getRows()?
{
i2 = 0;
for (int j = Col1; j <= Col2; j++) // similar problem here
{
int DumyValue = Input(i, j);
OutPut(j2, i2) = DumyValue;
i2++;
}
j2++;
}
return OutPut;
}
Not that this completely ignores the very logical option of making slice a Matrix method. While it makes sense, it doesn't need to be a method and the stock recommendation is to prefer a free function. One good improvement is to make the function a template so that it can handle all sorts of Matrix in addition to Matrix<int>.
And finally, what happens to main?
int main()
{
//Define a matrix for test:
Matrix<int> Matrix2(4, 5, 1); // initialize matrix to all 1s
int R = 4;
int C = 4;
Matrix<int> MatrixInput(R, C); // default initialize the matrix
for (int i = 0; i < MatrixInput.getRows(); i++)
{
for (int j = 0; j < MatrixInput.getColumns(); j++)
{
int temp;
temp = i ^ 2 + j ^ 2;
// WARNING: ^ is XOR, not exponent. Maybe OP wants i XOR 2, but not
// likely. But if XOR is the desired operation, there is a lurking
// order of operation bug that needs to be addressed
MatrixInput(i, j) = temp;
}
}
std::cout << MatrixInput << '\n';
std::cout << MatrixSlice(MatrixInput, 0, 3, 1, 1);
return 0;
}
In your code
if (abs(Row1-Row2)>1 && abs(Col1-Col2)>1){
vector<vector<int> > OutPut;
// OutPut dies here
}else{
vector<int> OutPut;
// OutPut dies here
}
// here is no OutPut
OutPut lives only to the end of IF statement.
You either use it without the if statement or you add all code that uses it to the if statement.
In order to get more familiar with C++, I have started working on some algebraic problems. Now, I have created an algorithm which generate a combination of numbers, with some constraints, based on an input number:
void abc(const int n) {
std::vector<int> aOut, bOut, cOut; // creating vectors to store values (dynamic int arrays)
for (int a = 9; a <= n - 2; a++) {
for (int b = a + 1; b <= n - 1; b++) {
for (int c = b + 1; c <= n; c++) {
aOut.push_back(a);
bOut.push_back(b);
cOut.push_back(c);
// std::cout << "a = " << a << " b = " << b << " c = " << c << std::endl;
}
}
}
Now, I need to continue working with these vectors, so I need to return them somehow. I have tried to create an int array of the size: int ABC[N][3], where const int N = cOut.size();. This does not work, as N is not accepted as a constant.
I also tried making a counter in the loop where I generate the vectors, which I then transferred to a string which I then transferred to a constant integer - this did not work either.
I tried making a pointer to a constant int, and using it to change the constant in the loop, which did not work either.
I even found a way to calculate the size based on my loops:
const int n = 20;
const int n1 = n - 10; // Manipulating input
const int N = n1*(n1 + 1)*(n1 + 2) / 6; // Size of vectors
And then passing the value to the function as:
void abc(const int n, const int N) { // same code as before }
But nothing works. I am honestly out of ideas (and losing my head). I have browsed trough the forum and google, but without luck. If someone could point me in the right direction, I would be forever grateful.
Of cause the solution includes changing the void to a function that returns the parameters. I added the void as I would like to check if the values were printed correctly.
How about creating an element (container) which encapsulates your 3 vectors as a return element?
The problem you're having is that functions (like Mathemematicians want to) return one value, but this can be any value :).
You could use a class or a struct which will has the vectors as attributes:
struct returnElement { // choose an adequate name
std::vector<int> aOut, bOut, cOut;
};
so now your abc function would return the returnElement struct. It could look something like this:
returnElement abc (const int n) {
returnElement ret; // creating vectors to store values (dynamic int arrays)
for (int a = 9; a <= n - 2; a++) {
for (int b = a + 1; b <= n - 1; b++) {
for (int c = b + 1; c <= n; c++) {
ret.aOut.push_back(a);
ret.bOut.push_back(b);
ret.cOut.push_back(c);
}
}
return ret;
}
Why not have an std::array of std::vector?
std::array<std::vector<int>, 3> abc(int const n)
{
std::array<std::vector<int>, 3> outArray;
for (int a = 9; a <= n - 2; a++)
{
for (int b = a + 1; b <= n - 1; b++)
{
for (int c = b + 1; c <= n; c++)
{
outArray[0].push_back(a);
outArray[1].push_back(b);
outArray[2].push_back(c);
}
}
}
return outArray;
}
To answer your question concerning array sizes,
I have tried to create an int array of the size: int ABC[N][3], where const int N = cOut.size();. This does not work, as N is not accepted as a constant.
The size of an array (whether raw or std::array) must be compile-time constant. If the size is not known at compile-time you must either create a dynamic array (using new) or use an std::vector.
If you know how large the vector is to be, you can reserve space in it for your elements, like so:
std::vector<int> yourVec;
yourVec.reserve(100); // reserve space for 100 ints
or
std::vector<int> yourVec;
yourVec.resize(100, 0); // populates yourVec with 100 ints with value 0
See Choice between vector::resize() and vector::reserve() for the differences between reserve and resize.
I have that error but I'm sure I have the same data type and I didn't do anything wrong I suppose. It's for calculating the determinant of a matrix. Someone help. I really can't think of why I have this error :(
#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
double determinant(double matrix[100][100], int order)
{
double det, temp[100][100]; int row, col;
if (order == 1)
return matrix[0][0];
else if (order == 2)
return ((matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]));
else
{
for (int r = 0; r < order; r++)
{
row = 0;
col = 0;
for (int i = 1; i < order; i++)
{
for (int j = 0; j < order; j++)
{
if (j == r)
continue;
temp[row][col] = matrix[i][j];
col++;
}
row++;
}
det += (matrix[0][r] * pow(-1, r) * determinant(temp, order - 1));
}
return det;
}
}
int main()
{
int n;
cout << "Enter the dimension: ";
cin >> n;
double elem[n][n];
for (int i = 0; i < n; i++)
{
cout << "Enter row " << i << ": ";
for (int j = 0; j < n; j++)
{
cin >> elem[i][j];
}
cout << endl;
}
cout << determinant(elem, n);
return 0;
}
your prototype is
double determinant(double matrix[100][100], int order)
and you call it with
determinant(elem, n);
when
double elem[n][n]; that is a "dynamic" array size so not 100x100
it seam compiler assumes n is 1 at compile time so
obviously double array [1][1] can't be converted to [100][100]
as you wrote it even if your input matrix data is 1x1 you have to store it in 100x100 array.
just declare double elem[100][100];
finally at run time ensure user input n < 100 to avoid a bug
You have three problems.
First, the size of elem is unknown at compile time. You should use elem[100][100] if you really want the variable on the stack and the size of the matrix really is 100x100.
Second, your determinant function creates a 10 thousand element matrix on the stack and it is recursive, which means you'll get a lot of them and likely run out stack space. You should consider using a single temp matrix and reusing this for each recursive step.
Third, since you need the matrix size it to be dynamic, declare it on the heap. Something like:
double* elem = new double[n * n];
Strictly speaking you do not need to do this, but it will not waste as much memory as a 100x100 matrix if you are calculating the determinant of small matrices.
If you use a one dimensional array, you can pass in an array of any size to determinant (the determinant function should also take a one-dimensional array or double* instead of double[100][100]). You will have to calculate the index yourself using matrix[order*j+i].
double elem[n][n]; is illegal in C++. Arrays must have dimensions known at compiletime.
Your bizarre error message is a result of a compiler attempting to support double elem[n][n] as an extension, but not doing a very good job of it.
One way to fix this would be to change your code to be double elem[100][100]; .
To fix it without wasting memory and sticking to Standard C++, you should use std::vector instead of a C-style array. It is simpler to code to use a vector of vectors, although for performance reasons you may want to use a 1-D vector.
Also, you would need to refactor determinant slightly as you don't really want to be allocating new memory each time you do another step of the recursion. The determinant function needs to know what dimension of memory is allocated, as well as what dimension you want to calculate the determinant on.
I am a Fortran user and do not know C++ well enough. I need to make some additions into an existing C++ code. I need to create a 2d matrix (say A) of type double whose size (say m x n) is known only during the run. With Fortran this can be done as follows
real*8, allocatable :: A(:,:)
integer :: m, n
read(*,*) m
read(*,*) n
allocate(a(m,n))
A(:,:) = 0.0d0
How do I create a matrix A(m,n), in C++, when m and n are not known at the time of compilation? I believe the operator new in C++ can be useful but not not sure how to implement it with doubles. Also, when I use following in C++
int * x;
x = new int [10];
and check the size of x using sizeof(x)/sizeof(x[0]), I do not have 10, any comments why?
To allocate dynamically a construction similar to 2D array use the following template.
#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;
}
Also you can use class std::vector instead of the manually allocated pointers.
#include <iostream>
#include <vector>
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;
std::vector<std::vector<double>> v( m, std::vector<double>( n ) );
//...
}
As for this code snippet
int * x;
x = new int [10];
then x has type int * and x[0] has type int. So if the size of the pointer is equal to 4 and the size of an object of type int is equal also to 4 then sizeof( x ) / sizeof( x[0] ) will yields 1. Pointers do not keep the information whether they point to only a single object or the first object pf some sequence of objects.
I would recommend using std::vector and avoid all the headache of manually allocating and deallocating memory.
Here's an example program:
#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);
}
The formal C++ way of doing it would be this:
std::vector<std::vector<int>> a;
This creates container which contains a zero size set of sub-containers. C++11/C++13 provide std::array for fixed-sized containers, but you specified runtime sizing.
We now have to impart our dimensions on this and, unfortunately. Lets assign the top-level:
a.resize(10);
(you can also push or insert elements)
What we now have is a vector of 10 vectors. Unfortunately, they are all independent, so you would need to:
for (size_t i = 0; i < a.size(); ++i) {
a[i].resize(10);
}
We now have a 10x10. We can also use vectors constructor:
std::vector<std::vector<int>> a(xSize, std::vector<int>(ySize)); // assuming you want a[x][y]
Note that vectors are fully dynamic, so we can resize elements as we need:
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
To get the size of a particular slot:
a.size(); // returns 10
a[1].size(); // returns 11 after the above
a[2].size(); // returns 9 after teh above.
Unfortunately C++ doesn't provide a strong, first-class way to allocate an array that retains size information. But you can always create a simple C-style array on the stack:
int a[10][10];
std::cout << "sizeof a is " << sizeof(a) <<'\n';
But using an allocator, that is placing the data onto the heap, requires /you/ to track size.
int* pointer = new int[10];
At this point, "pointer" is a numeric value, zero to indicate not enough memory was available or the location in memory where the first of your 10 consecutive integer storage spaces are located.
The use of the pointer decorator syntax tells the compiler that this integer value will be used as a pointer to store addresses and so allow pointer operations via the variable.
The important thing here is that all we have is an address, and the original C standard didn't specify how the memory allocator would track size information, and so there is no way to retrieve the size information. (OK, technically there is, but it requires using compiler/os/implementation specific information that is subject to frequent change)
These integers must be treated as a single object when interfacing with the memory allocation system -- you can't, for example:
delete pointer + 5;
to delete the 5th integer. They are a single allocation unit; this notion allows the system to track blocks rather than individual elements.
To delete an array, the C++ syntax is
delete[] pointer;
To allocate a 2-dimensional array, you will need to either:
Flatten the array and handle sizing/offsets yourself:
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]
or you could use
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];
}
That's kind of a pain, so you would probably be steered towards encapsulation:
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);
Or,
For each Nth dimension (N < dimensions) allocate an array of pointers-to-pointers, only allocating actual ints for the final dimension.
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;
This last is more-or-less doing the same work, it just creates more memory fragmentation than the former.
-----------EDIT-----------
To answer the question "why do I not have 10" you're probably compiling in 64-bit mode, which means that "x" is an array of 10 pointers-to-int, and because you're in 64-bit mode, pointers are 64-bits long, while ints are 32 bits.
The C++ equivalent of your Fortran code is:
int cols, rows;
if ( !(std::cin >> cols >> rows) )
// error handling...
std::vector<double> A(cols * rows);
To access an element of this array you would need to write A[r * rows + c] (or you could do it in a column-major fashion, that's up to you).
The element access is a bit clunky, so you could write a class that wraps up holding this vector and provides a 2-D accessor method.
In fact your best bet is to find a free library that already does this, instead of reinventing the wheel. There isn't a standard Matrix class in C++, because somebody would always want a different option (e.g. some would want row-major storage, some column-major, particular operations provided, etc. etc.)
Someone suggested boost::multi_array; that stores all its data contiguously in row-major order and is probably suitable. If you want standard matrix operations consider something like Eigen, again there are a lot of alternatives out there.
If you want to roll your own then it could look like:
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;
};
Note in particular that by avoiding new you avoid the thousand and one headaches that come with manual memory management. Your class is copyable and movable by default. You could add further methods to replicate any functionality that the Fortran array has which you need.
int ** x;
x = new int* [10];
for(int i = 0; i < 10; i++)
x[i] = new int[5];
Unfortunately you'll have to store the size of matrix somewhere else.
C/C++ won't do it for you. sizeof() works only when compiler knows the size, which is not true in dynamic arrays.
And if you wan to achieve it with something more safe than dynamic arrays:
#include <vector>
// ...
std::vector<std::vector<int>> vect(10, std::vector<int>(5));
vect[3][2] = 1;
This question already has answers here:
how to use memset for double dimentional array?
(2 answers)
Closed 9 years ago.
What is the fastest way to set a 2-dim array of double,such as double x[N][N] all to -1?
I tried to use memset, but failed. Any good idea?
Use: std::fill_n from algorithm
std::fill_n(*array, sizeof(array) / sizeof (**array), -1 );
Example:
double array[10][10];
std::fill_n( *array, sizeof(array) / sizeof (**array), -1.0 );
//Display Matrix
for(auto i=0;i<10;i++)
{
for(auto j=0;j<10;j++)
cout<<array[i][j]<< " ";
cout<<endl;
}
A simple loop:
#include <stdio.h>
int main(void)
{
#define N 5
double x[N][N];
size_t i, n = sizeof(x) / sizeof(double);
for (i = 0; i < n; i++)
x[0][i] = -1.0;
for (i = 0; i < n; i++)
printf("%zu) %f\n", i, x[0][i]);
}
// create constants
const int rows = 10;
const int columns = 10;
// declare a 2D array
double myArray [rows][columns];
// run a double loop to fill up the array
for (int i = 0; i < rows; i++)
for (int k = 0; k < columns; k++)
myArray[rows][columns] = -1.0;
// print out the results
for (int i = 0; i < rows; i++) {
for (int k = 0; k < columns; k++)
cout << myArray[rows][columns];
cout << endl;
}
Also you can set directly
double x[4][4] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
if the array index is small.
Using std::array and its fill method:
#include <array>
#include <iostream>
int main()
{
const std::size_t N=4
std::array<double, N*N> arr; // better to keep the memory 1D and access 2D!
arr.fill(-1.);
for(auto element : arr)
std::cout << element << '\n';
}
Using C++ containers you can use the fill method
array<array<double, 1024>, 1024> matrix;
matrix.fill(-1.0);
if, for some reason, you have to stick with C-style arrays you can initialize the first row manually and then memcpy to the other rows. This works regardless if you have defined it as static array or allocated row by row.
const int rows = 1024;
const int cols = 1024;
double matrix[rows][cols]
for ( int i=0; i<cols; ++i)
{
matrix[0][cols] = -1.0;
}
for ( int r=1; r<rows; ++r)
{
// use the previous row as source to have it cache friendly for large matrices
memcpy(&(void*)(matrix[row][0]), &(void*)(matrix[row-1][0]), cols*sizeof(double));
}
But I rather would try to move from C style arrays to the C++ containers than doing that kind of stunt.
memset shouldn't be used here because it is based on void *. So all bytes in are the same. (float) -1 is 0xbf800000 (double 0xbff0000000000000) so not all bytes are the same...
I would use manual filling:
const int m = 1024;
const int n = 1024;
double arr[m][n];
for (size_t i = 0; i < m*n; i++)
arr[i] = -1;
Matrix is like array in memory, so better to have 1 loop, it slightly faster.
Or you can use this:
std::fill_n(arr, m*n, -1);
Not sure which one is faster, but both looks similar. So probably you'll need to make small test to find it out, but as far as I know people usually use one or another. And another thing first one is more C on some compiler it won't work and second is real C++ it and never works on C. So you should choose by the programming language I think :)