3

I want to initialize an double array with size 200, and its value is from 0 to 199 from index 0 to 199 in c++. i know i can do it by a simple For loop, but is there a way just to initialize the double array like this?

Thanks

2

8 Answers 8

10

Not really. A for loop is your best option:

double array[200];
for(int i = 0; i < 200; i++)
    array[i] = static_cast<double>(i);
Sign up to request clarification or add additional context in comments.

12 Comments

This is the only answer, I think. Even a c++ newbie will understand it with no effort. Other answers (std::generate, counting_iterator<>, whatever) are to show the tricks of c++, not to solve the actual problem. Code should be kept as simple as possible (but not simplier) =)
@Sad: The counting_iterator solution is simple.
@Sad: Such projects are poor then. The standard library is part of the language; failure to use it indicates failure of the programmer programming in C++. Boost should be used when allowed, though that's not always possible for some poeple. (Then again, you can extract individual libraries easily.) Lack of knowledge of std::copy is to be in a position not to judge C++ code, for one isn't a C++ programmer.
@SadSido: I agree with GMan, to an extent. Every programmer need a debugged, high-performance library for basic operations. Whatever that library is actually. EA Games uses the EASTL for example, which has been geared toward higher performance using dedicated allocators, and allocation and initialization strategies. But I would say it does not matter: I expect any C++ programmer to be able to search on the internet and understand what's happening when I use some STL or Boost part as simple as those mentionned here (I am so not speaking of boost::mpl).
@SadSido: You may not like it, but GMan is right. C++ is the language plus the standard libraries and puts great emphasis on the latter. And that one out of not even half a dozen answers using a loop got the loop wrong at first shows why loops aren't superior.
|
7

Here's a way with std::generate:

template <typename T>
class nexter
{
public:
    nexter(T start = T())
        : value_(start)
    {
    }

    T operator()()
    {
        return value_++;
    }

private:
    T value_;
};

int main()
{
    double data[200];
    std::generate(data, data + 200, nexter<double>());
}

And if you were using C++0x, you could skip the functor:

int main()
{
    double data[200];
    double next = 0.0;
    std::generate(data, data + 200, [&next]() { return next++; } );
}

8 Comments

Strictly speaking, I think for_each isn't actually suppose to mutate the elements. Also, if you want to ignore a parameter just don't name it. Lastly, might as well use std::generate if you're gonna use a functor. :)
@GMan - thanks, I forgot about std::generate - updated my example and also gave an example using C++0x lambdas.
@RSamuel: +1 Nice, the C++0x solution is arguably cleanest thus far. (If only the standard library used damn ranges instead of iterators!) For the record that -1 isn't me.
@GMan - thanks. And I can't wait until lambda's aren't considered cutting edge as they are so damn nice to use.
+1 But only for showing a glimpse of nice C++0x lambda. Functor version is... No. Please. Don't do that.
|
7

Using counting_iterator:

const int SIZE = 200;
double array[SIZE];
std::copy(counting_iterator<int>(0), counting_iterator<int>(SIZE), array);

3 Comments

IMHO, ::std:;copy should've been written to require the destination begin and end, and the source begin instead of the other way around. You can get buffer overflows either way, but harder to exploit when the overflow is only reading, not writing.
@Omnifarious: better yet, requiring both ;) But I agree that a reading overflow is less likely to cause a problem.
like GMan I didn't know about this little marvel. So simple and so useful!
2

Same as anthony-arnold, but with C++ vectors (or lists, or deque):

std::vector<double> array ;
array.reserve(200) ; // only for vectors, if you want
                     // to avoid reallocations

for(int i = 0; i < 200; i++)
    array.push_back(i) ;

Comments

1

If all value of array are same , you can do it easily. But values are different from each other so i don't think you do it directly.

double array[200];

for(int i=0 ; i<200 ; i++) { 
    array[i] = (double)i; 
}

8 Comments

Your code leads to an invalid memory access when i = 200 as it will write to array[200]. Put the assignment to array[i] into the body of the for statement where it belongs!
Oh, furthermore, array[0] is not written and stays uninitialized.
I don't think how c++ for mechanism. If it parse sentence from left then there isn't any invalid memory access. The for loop ends until coming " array[i] = (double)i "
Sorry. I think it check condition after doing "i++ , array[i] = (double)i" . I suppose it check after every operation like i++ and a condition.
@Judas: No, it does the check after the assignment.
|
0

If the 200 is a fixed constant and you don't want runtime overhead, I see basically two solutions.

For a C solution, you could solve it through the preprocessor. In think Boost has preprocessor for loops for such a thing. This would have the advantage to be done at compile time, no runtime overhead at all.

The constant 200 by itself might be a bit big for all compilers/preprocessors, though, but most modern ones should be able to handle this.

For a C++ solution, you could do it with template metaprogramming, I think. A recursive type with the number of elements in the template parameter could do the trick. But for constants that large the compile time overhead can be prohibitive.

2 Comments

Interesting options but neither could reasonable be called easier than a loop. Especially the template recursion is a difficult thing to understand
@Elemental: depends for whom it is simpler. If you have e.g a generic macro that does that, the call side becomes extremely simple, something like double A[] = INIT_DARRAY(200);. Sure the implementation of such a macro ain't simple, but that is really a different side of the coin. And whether such a macro hides a genuine macro definition à la Boost or a recursive template doesn't matter in that respect.
0

The only way to initialize values of arrays is at the point of declarations (if the initializer is smaller than the array all other elements are initialized to zero;

double arr[5] = {0, 1, 2}; // arr = [0.0 ,1.0 ,2.0 ,0.0 ,0.0]

Otherwise there's no way to initialize the values and you'll have to loop over the array.

So what you can do is:

double arr[] = {0, 1, 2, 3, /* ... */, 199}; 

Although looping would be much better in most cases.

2 Comments

As an additional advantage over the loop notation is that this can be resolved at compilation. The disadvantage being this is a pain to write...
@paercebel, of course the fact that it's done at compilation time is the only advantage. As for writing it, I would generate it with a script once so as not to risk making an error.
0

I think that for-loop is the simplest and most appropriate solution for your case. If you want just to know one more way to do it you could use std::transform:

#include <vector>
#include <algorithm>

double op_increase (double i) { return static_cast<double>(static_cast<int>(i)+1); }

int main() 
{ 
    std::vector<double> x( 200 ); // all elements were initialized to 0.0 here
    std::transform( x.begin(), x.end()-1, x.begin()+1, op_increase );

    return 0; 
} 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.