Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Ik plaats het in een blok omgeven met [ CODE ] en [ /CODE ] maar dan zonder de spaties tussen de brackets en CODEHoe krijg je je code hier geplaatst? Dat lukt mij al een tijdje niet meer. Bij mij wordt het geweigerd.![]()
// like this
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
#include <iostream>
Ik denk dat er andere randvoorwaarden gelden zoals maximale lengte of iets dergelijks. Misschien kan een mod hier iets over zeggen?Nu werkt het weer wel, of misschien zag mijn eerdere code er te gevaarijk uit?
Je threading doet niet echt iets. Wat je typisch wilt doen is workload verdelen over threads. Ik heb hier een klein programmaatje dat priemgetallen berekent door het werk uit te besteden aan meerdere threads. Iedere thread krijgt zijn eigen struct met de beschrijving van het werk en waar de thread de gevonden priemgetallen kan opslaan. De main thread gaat vervolgens voortgang rapportage doen over de threads. Er is dus communicatie tussen de threads en het hoofdprogramma. In de struct zie je een atomic 'percent' (init op 0) dat gezet wordt door de thread en gelezen wordt door de main thread (programma). De atomicity zorgt ervoor dat schrijven en lezen van deze locatie gesynchroniseerd is. Een lees operatie wordt gedaan als een schrijf actie klaar is of een schrijf operatie wordt gedaan als een lees actie klaar is.
Als alle threads klaar zijn dan kan het hoofdprogramma veilig alle data lezen uit de individuele structs die ooit aan threads toebedeeld zijn.
C++:// primes2.cpp - the smallest version: no command line, options are constants. // // NUM_THREADS threads search the numbers 1..RANGE for primes. Each thread // gets its own PrimeRange object (its part of the range + a counter). // While working, every thread stores its progress (0..100 %) in its object // and the main program keeps drawing one progress bar per thread on screen. // // Compile: g++ -std=c++17 -Wall -Wextra -O2 -pthread primes2.cpp -o primes2 // Run: ./primes2 #include <atomic> #include <chrono> #include <iostream> #include <thread> #include <vector> const int NUM_THREADS = 10; // how many threads const int RANGE = 1000000000; // inspect the numbers 1..RANGE const bool SHOW_PRIMES = false; // true: store and print the primes too const int BAR_WIDTH = 50; // progress bar columns (1 column = 2 %) struct PrimeRange { int low, high; // the part this thread checks (inclusive) long long count = 0; // primes found std::vector<int> primes; // the primes themselves (only if SHOW_PRIMES) std::atomic<int> percent{0}; // progress 0..100; the thread writes it, main // reads it -> atomic makes that safe }; bool isPrime(int n) { if (n < 2) return false; for (int d = 2; d * d <= n; ++d) if (n % d == 0) return false; return true; } void findPrimes(PrimeRange* r) // this is what every thread runs { long long size = r->high - r->low + 1; for (int n = r->low; n <= r->high; ++n) { if (isPrime(n)) { ++r->count; if (SHOW_PRIMES) r->primes.push_back(n); } int done = (long long)(n - r->low + 1) * 100 / size; if (done != r->percent) r->percent = done; // report progress } r->percent = 100; // also for an empty range } // Draw one bar: a full block per 2 %, a half block for an odd 1 %. void drawBar(int threadNo, int percent) { std::cout << "Thread " << (threadNo < 10 ? " " : "") << threadNo << " ["; for (int col = 0; col < BAR_WIDTH; ++col) { int p = percent - col * 2; // how much of this column is filled: 0, 1 or 2+ std::cout << (p >= 2 ? "█" : p == 1 ? "▌" : " "); } std::cout << "] " << (percent < 100 ? " " : "") << (percent < 10 ? " " : "") << percent << " %\n"; } int main() { // Divide 1..RANGE over the threads; thread 1 gets the leftovers. std::vector<PrimeRange> ranges(NUM_THREADS); int next = 1; for (int i = 0; i < NUM_THREADS; ++i) { int size = RANGE / NUM_THREADS + (i == 0 ? RANGE % NUM_THREADS : 0); ranges[i].low = next; ranges[i].high = next + size - 1; next = ranges[i].high + 1; } // Start the threads, each with a pointer to its own object. auto start = std::chrono::steady_clock::now(); std::vector<std::thread> threads; for (int i = 0; i < NUM_THREADS; ++i) threads.push_back(std::thread(findPrimes, &ranges[i])); // Show the progress bars until every thread reports 100 %. // "\033[<n>A" is the terminal code for "move the cursor n lines up", so // the bars stay in place and are overwritten instead of scrolling. // "\033[?25l" hides the cursor (no flickering), "\033[?25h" shows it again. std::cout << "\033[?25l"; while (true) { bool allDone = true; for (int i = 0; i < NUM_THREADS; ++i) { int p = ranges[i].percent; drawBar(i + 1, p); if (p < 100) allDone = false; } std::cout << std::flush; if (allDone) break; std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::cout << "\033[" << NUM_THREADS << "A"; } std::cout << "\033[?25h"; // Wait for the threads (they are done, this just cleans up). for (std::thread& t : threads) t.join(); auto stop = std::chrono::steady_clock::now(); // Report. long long total = 0; for (int i = 0; i < NUM_THREADS; ++i) { if (SHOW_PRIMES) for (int p : ranges[i].primes) std::cout << p << "\n"; std::cout << "Thread " << i + 1 << ": " << ranges[i].low << " .. " << ranges[i].high << " -> " << ranges[i].count << " primes\n"; total += ranges[i].count; } std::cout << "\nRange 1 .. " << RANGE << " -> " << total << " primes in total\n" << "Time: " << std::chrono::duration<double, std::milli>(stop - start).count() << " ms\n"; }
void findPrimes(PrimeRange* r) // this is what every thread runs
{
long long size = r->high - r->low + 1;
for (int n = r->low; n <= r->high; ++n) {
if (isPrime(n)) {
++r->count;
if (SHOW_PRIMES) r->primes.push_back(n);
}
int done = (long long)(n - r->low + 1) * 100 / size;
if (done != r->percent) r->percent = done; // report progress
}
r->percent = 100; // also for an empty range
}
struct PrimeRange {
int low, high; // the part this thread checks (inclusive)
long long count = 0; // primes found
std::vector<int> primes; // the primes themselves (only if SHOW_PRIMES)
std::atomic<int> percent{0}; // progress 0..100; the thread writes it, main
// reads it -> atomic makes that safe
};
#include <iostream>
int main( void )
{
int a = 10;
int b = 20;
int *p = &a; // pointer p wijst naar het geheugen waar a leeft
std::cout << "a: " << a << " b:" << b << " *p:" << *p << " p:" << p <<'\n';
*p = 12; // de inhoud van het geheugen waar pointer p naar wijst wordt 12
std::cout << "a: " << a << " b:" << b << " *p:" << *p << " p:" << p <<'\n';
p = &b; // pointer p wijst nu naar het geheugen waar b leeft
std::cout << "a: " << a << " b:" << b << " *p:" << *p << " p:" << p <<'\n';
*p = *p + a; // de inhoud van het geheugen waar pointer p naar wijst wordt zichzelf + a
std::cout << "a: " << a << " b:" << b << " *p:" << *p << " p:" << p <<'\n';
}
#include <iostream>
int main( void )
{
int a = 10;
int *p = &a; // pointer p wijst naar het geheugen waar a leeft
std::cout << "a: " << a << std::endl;
std::cout << "&a: " << &a << std::endl;
std::cout << "*p:" << *p << std::endl;
std::cout << "p:" << p << std::endl;
std::cout << std::endl;
std::cout << "Dus geldt niet dat:*p = &a ." << std::endl;
}
Ik vind die notatie nog steeds verwarrend:
Code:#include <iostream> int main( void ) { int a = 10; int *p = &a; // pointer p wijst naar het geheugen waar a leeft std::cout << "a: " << a << std::endl; std::cout << "&a: " << &a << std::endl; std::cout << "*p:" << *p << std::endl; std::cout << "p:" << p << std::endl; std::cout << std::endl; std::cout << "Dus geldt niet dat:*p = &a ." << std::endl; }
Bekijk bijlage 3875769
Ja pointers, references, dereferencing is meer iets voor datastructuren. Zolang je programmatuur dat niet nodig heeft kun je gelukkig zonder.Ik programmeer beroepsmatig, en ik haak ook enigszins af bij dat soort zaken. Ik heb het liefst code die als een romannetje leest. Ik heb programma's met multithreading gemaakt, maar daar was het wat minder abstract dan deze C++ code. En in de Arduino C++ gebruik ik pointers nooit (tenminste, onder de motorkap wel in de libraries en bv de pinnamen die je gebruikt zijn op zich al referenties naar andere variabelen, maar ik bedoel zelf expliciet).
Het is toch automatisch al zo dat p een pointer moet zijn als p = &a? Waarvoor is dat sterretje dan nog nodig?
Vanwege typering. We hebben in dit voorbeeld 'int' gebruikt als type maar het kan een pointer zijn naar van alles en nog wat. Zoals in mijn priem proggeltje: daar hebben we een pointer naar een struct gebruikt. Je compiler moet weten naar WAT de pointer wijst. Het is niet voldoende om te weten dat het een pointer (geheugenadres) is. Je moet dus expliciet aangeven welk type pointer het is.Het is toch automatisch al zo dat p een pointer moet zijn als p = &a? Waarvoor is dat sterretje dan nog nodig?
char *p; // pointer naar een enkel karakter
PrimeRange *x; // pointer naar een struct
PrimeRange *p = &ranges[1];
*p.count += 1;
p->count += 1;