I C-programmering används funktionerna rand() och srand() för att generera slumpmässiga tal. Trots att dessa funktioner kan ge till synes slumpmässiga resultat vid första anblicken, är de faktiskt inte helt slumpmässiga utan pseudo-slumpmässiga. Det innebär att de förlitar sig på en förutbestämd sekvens, vilket gör att samma tal kan genereras varje gång programmet körs om inte en förändring sker i den så kallade fröet, eller seed.

Vid användning av rand() kommer programmet att generera samma sekvens av tal om inget annat anges. Detta beror på att värdet för fröet är förinställt och konstant. För att åstadkomma en verklig variation i de genererade talen, behöver vi använda funktionen srand() som sätter ett unikt frö vid varje körning. Om samma frö används varje gång kommer samma tal att genereras. Ett enkelt exempel på detta är:

c
#include <stdio.h>
#include <stdlib.h> int main() { int i; printf("Enter a seed integer = "); scanf("%d", &i); srand(i); printf("%d\n", rand()); return 0; }

I det här fallet sätts fröet via användarens inmatade värde och ger ett resultat som beror på detta värde. Programmet genererar ett tal som är samma varje gång om samma frö anges. För att säkerställa att varje körning ger en annan uppsättning tal, kan man använda sig av tidsfunktionen time(NULL), som returnerar det antal sekunder som förflutit sedan 1 januari 1970 (UNIX-epoken). Detta kan användas för att generera ett dynamiskt frö:

c
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand(time(NULL)); printf("%d\n", rand()); return 0; }

Här ser vi att varje gång programmet körs vid olika tidpunkter får vi olika resultat. Om programmet körs flera gånger inom en sekund, kan dock samma tal genereras eftersom fröet i sådana fall inte ändras tillräckligt snabbt.

För att skapa slumpmässiga tal inom ett specifikt intervall kan man använda en enkel matematisk omvandling av det genererade talet. rand() ger ett heltal mellan 0 och RAND_MAX. Detta värde kan omvandlas till ett tal inom vilket intervall som helst. Några exempel på sådana omvandlingar är:

  • rand() % 7 ger ett tal mellan 0 och 6.

  • rand() % 7 + 10 ger ett tal mellan 10 och 16.

  • 1.0 * rand() / RAND_MAX ger ett flyttal mellan 0 och 1.

  • 5.0 * rand() / RAND_MAX ger ett flyttal mellan 0 och 5.

En annan metod för att skapa slumpmässiga tal inom en viss intervall är att multiplicera resultatet från rand() med ett konstant värde och justera med ett förskjutningsvärde.

Simuleringar med Slumpmässiga Tal: Monte Carlo-metoden

En av de mest kända tillämpningarna av slumpmässiga tal är i Monte Carlo-metoden, som används för att genomföra numeriska simuleringar. Genom att generera stora mängder slumpmässiga tal kan man approximera resultatet av komplexa integraler. Till exempel, för att approximera värdet på π kan man använda metoden för att beräkna arean av en fjärdedel av en enhetscirkel genom att generera slumpmässiga punkter inom en kvadrat.

Om vi slumpar fram punkterna (x, y) där både x och y ligger mellan 0 och 1, kan vi kontrollera om dessa punkter ligger innanför cirkeln genom att använda formeln x² + y² < 1. Antalet punkter som ligger innanför cirkeln jämfört med det totala antalet punkter ger oss en approximation av π/4, som genom att multipliceras med 4 ger en approximation av π.

Programmet nedan implementerar denna metod:

c
#include <stdio.h>
#include <stdlib.h> #include <time.h> #define PI 3.141592 int main() { float x, y; int i, count = 0; int n; printf("Enter iteration number = "); scanf("%d", &n); srand(time(NULL)); for (i = 0; i < n; i++) { x = 1.0 * rand() / RAND_MAX; y = 1.0 * rand() / RAND_MAX; if (x * x + y * y < 1.0) { count = count + 1; } } printf("True value = %f\n", PI / 4); printf("Appx value = %f\n", 1.0 * count / n); return 0; }

När programmet körs kommer resultatet att närma sig det verkliga värdet på π efter flera iterationer. Ju fler iterationer som genomförs, desto noggrannare blir resultatet. Men det är viktigt att förstå att Monte Carlo-metoden inte är den mest effektiva för endimensionella integraler, även om den ger en bra approximation i högre dimensioner.

Användning av Monte Carlo-metoden

Det är också värt att notera att Monte Carlo-metoden kan tillämpas på många andra typer av beräkningar där en exakt lösning är svår eller omöjlig att få. För mer komplexa volymberäkningar, som att uppskatta volymen på en enhetssfär i tre dimensioner, kan denna metod ge effektiva resultat. För denna typ av problem beräknas förhållandet mellan punkter som faller inom ett område (t.ex. en sfär) och totalt antal genererade punkter.

Viktiga Aspekter att Tänk På

För att få tillförlitliga resultat när man använder slumpmässiga tal är det viktigt att:

  • Använda en bra seed för rand(), annars riskerar man att alltid få samma talserie.

  • Använda rätt formel för att skapa tal inom ett önskat intervall.

  • Förstå att trots att tal är pseudo-slumpmässiga, kommer de att ge acceptabla resultat för de flesta tillämpningar, men är inte "verkligt slumpmässiga".

  • Vid användning av Monte Carlo-metoden bör antalet iterationer vara tillräckligt stort för att säkerställa att resultaten är tillförlitliga, särskilt när precisionen är av betydelse.

Hur fungerar strängar och kommandoradsargument i C-språket?

I C-språket är strängar inte ett särskilt datatyp, utan behandlas som arrayer av tecken som avslutas med ett nulltecken (\0). När en pekare som char *a tilldelas ett värde som "HELLO!", pekar den på den första bokstaven i strängen – tecknet H. Det är betydligt mer effektivt att direkt tilldela hela strängen med dubbla citattecken än att ange varje tecken enskilt med exempelvis a[0] = 'H'; a[1] = 'E'; och så vidare.

Vid utskrift av en sträng används format-specifikatorn %s i printf()-funktionen, eftersom %c endast skriver ut ett enskilt tecken. När en sträng deklareras med hjälp av en array, exempelvis char s[4] = "ABC";, måste arrayens storlek rymma ett extra element för nulltecknet – alltså fyra tecken totalt, inte tre.

När användaren matar in en sträng via tangentbordet med scanf("%s", str); måste man vara medveten om att endast den första delen av inmatningen upp till ett mellanslag kommer att registreras. Om man exempelvis skriver in "Good morning", kommer endast "Good" att sparas i variabeln. Vill man läsa flera ord, måste man antingen använda flera %s eller använda funktioner som fgets() för att läsa hela raden.

Vid strängoperationer såsom kopiering, jämförelse eller att ber