C++ - Fråga om std::accumulate

Permalänk
Medlem

C++ - Fråga om std::accumulate

Hej,
Jag håller på att lära mig C++ (på Linux) och har en fråga om att få summan av elementen i en array av stilen:

int array[] = {1, 2, 3, 4};

Enligt denna tutorial:
How to find the sum of values in an array in C++

så ska koden se ut som så:

sum = std::accumulate(arr, arr+size, sum);

Min fråga är varför har vi "arr+size" som andra argument?
I denna dokumentation används vektorer.

Permalänk
Medlem

Jag rekommenderar att du använder dig av en bättre källa som t.ex. Cppreference.
Här har du en direktlänk till std::accumulate.
https://en.cppreference.com/w/cpp/algorithm/accumulate

Det ser ut som std::accumulate vill ha aktuella intervallet för vectorn som ska summeras.
begin() & end() kanske makes more sense?

std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = std::accumulate(v.begin(), v.end(), 0);

Permalänk
Medlem

Det är en kvarleva från C att arrayer ofta fungerar som pekare, så arr+size tar en pekare till arr och ökar den med size element. Resultatet blir då en pekare till addressen efter det sista elementet i arrayen.

Istället för att använda pekararitmetik så kan man i det här fallet använda std::begin och std::end istället:

sum = std::accumulate(std::begin(arr), std::end(arr), sum);

Detta fungerar med både C-arrayer och C++-datastrukturer som std::array och std::vector.

Jag kan för övrigt tipsa om Learn C++ om du vill lära dig C++, det är en av de bästa sidorna för att lära sig "korrekt" C++.

Permalänk
Medlem
Skrivet av perost:

Det är en kvarleva från C att arrayer ofta fungerar som pekare, så arr+size tar en pekare till arr och ökar den med size element. Resultatet blir då en pekare till addressen efter det sista elementet i arrayen.

Istället för att använda pekararitmetik så kan man i det här fallet använda std::begin och std::end istället:

sum = std::accumulate(std::begin(arr), std::end(arr), sum);

Detta fungerar med både C-arrayer och C++-datastrukturer som std::array och std::vector.

Jag kan för övrigt tipsa om Learn C++ om du vill lära dig C++, det är en av de bästa sidorna för att lära sig "korrekt" C++.

Tack! Jag har dock redan en bra bok från en bekant som har jobbat med programmering i +40 år (boken täcker C++11 till C++20).

Permalänk
Medlem

Tillägg på frågan i OP:
Har någon av er en rekommendation för hur jag bäst fyller en integer-array med (pseudo)slumpmässiga värden som är inom ett given omfång (aka range)? Range kan vara 0-999 (inklusiva gränsvärden).

Arrayen har en fast storlek på 10 element.

Permalänk
Medlem
Skrivet av Apollo11:

Tillägg på frågan i OP:
Har någon av er en rekommendation för hur jag bäst fyller en integer-array med (pseudo)slumpmässiga värden som är inom ett given omfång (aka range)? Range kan vara 0-999 (inklusiva gränsvärden).

Arrayen har en fast storlek på 10 element.

Använd std::uniform_int_distribution och full arrayen på valfritt sätt. Du kan t.ex. använda std::generate, men jag skulle nog bara använda en enkel for-loop i det fallet eftersom generate kommer bli mer komplicerat och svårare att läsa:

for (auto &e: arr) { e = ...; }

Permalänk
Medlem
Skrivet av perost:

Använd std::uniform_int_distribution och full arrayen på valfritt sätt. Du kan t.ex. använda std::generate, men jag skulle nog bara använda en enkel for-loop i det fallet eftersom generate kommer bli mer komplicerat och svårare att läsa:

for (auto &e: arr) { e = ...; }

Exempel från länken ni skickade med lite frågor från mig:

#include <random> #include <iostream> int main() { std::random_device rd; //Will be used to obtain a seed for the random number engine std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd() std::uniform_int_distribution<> distrib(1, 6); //Jag antar efter lite testning att detta ger ett range som värderna kan landa inom? for (int n = 0; n < 10; ++n) //Spelar det någon viktig roll om jag använder pre- eller post-increment här? //Use `distrib` to transform the random unsigned int generated by gen into an int in [1, 6] std::cout << distrib(gen) << ' '; std::cout << '\n'; }