• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Prawdopodobieństwo, Programowanie C

Object Storage Arubacloud
0 głosów
478 wizyt
pytanie zadane 26 maja 2019 w C i C++ przez ciocialol Nowicjusz (180 p.)

Może mi ktoś pomóc, jak poradzić sobie z tym kodem? Jest napisany w C, i nie wiem jak spowodować wyzerowanie tablic. Program ma losować 3 liczby z rzutu kostką i mają być one rosnąco np. (1,3,5) albo (1,2,3).

Dla 1 "patrii" tablica ma przyjąć jakieś 3 randomowe liczby, ma je wypisać a potem dla x=2 znowu musi to zrobić itd.

ale nie wiem jak zwolnić tablice. HALP :)

#include <stdio.h>
#include <time.h>
#define N 6
int main()
{
    int i,x;
    time_t t;
    float tab[3];
    printf("podaj ilosc powtorzen");
    scanf(" %d",&x);

    srand(time(&t));

    do{
    for(i=0;i<3;i++)
    {
        tab[i] = rand() % N + 1;
        printf("%f ",tab[i]);

    }

    if(tab[0]<tab[1]<tab[2])
    {
        float h=0;
        h++;

    }
    else
    {
        float y=0;
        y++;
    }

    }while(x);
    float prawdopodobieństwo
    prawdopodobieństwo = h/x;

    return 0;
}

 

3 odpowiedzi

0 głosów
odpowiedź 26 maja 2019 przez dawid6512 Gaduła (4,550 p.)
komentarz 26 maja 2019 przez j23 Mędrzec (194,920 p.)

To aż linka musiałeś dać, żeby powiedzieć, żeby użył std::fill/std::fill_n, choć OP pisze w C a nie C++.

komentarz 26 maja 2019 przez dawid6512 Gaduła (4,550 p.)
uświadamiam innym, że klasyczne problemy są już dawno opisane na internecie, więc nie ma sensu pytać o coś co jest opisane tylko po angielsku :)
komentarz 26 maja 2019 przez tkz Nałogowiec (42,000 p.)
Lepiej dać wędkę, niż rybę.
komentarz 26 maja 2019 przez dawid6512 Gaduła (4,550 p.)
mam takie samo zdanie :)
komentarz 26 maja 2019 przez j23 Mędrzec (194,920 p.)

Tyle że z tą wędką kiepsko jest. OP pisze w C, a "wędka" jest głównie w C++ (funkcją memset nie powinno się zerować tablic float[]).

 

Co do uświadamiania: z takim podejściem to większość for internetowych (szczególnie polskich) nie miałoby racji bytu, bo zawsze ktoś gdzieś tam w świecie już zadał takie pytanie. No i dostał odpowiedź.

komentarz 26 maja 2019 przez ciocialol Nowicjusz (180 p.)

@dawid6512, Tylko ja jestem laikiem z programowania, i za bardzo tego nie widzę... laugh

komentarz 26 maja 2019 przez dawid6512 Gaduła (4,550 p.)
albo zamiast czyścic tablice zainteresuj się tablicami 2 wymiarowymi eng.Two dimensional Array
komentarz 26 maja 2019 przez niezalogowany

@ciocialol, 

A mnie zastanawia poco masz czyścić tablice, skoro je nadpisujesz za każdym razem.

I jakiś warunek zatrzymania pętli by się przydał przynajmniej mi się tak wydaje np(x--).

linia 24 - h masz zdefiniowane lokalnie, a 36 linii odwołujesz się do h poza zasięgiem definicji

a co do samego liczenia prawdopodobieństwa to ja nie kumam jak to się robi w powyższym programie

komentarz 26 maja 2019 przez ciocialol Nowicjusz (180 p.)
#include <stdio.h>
#include <time.h>
#define N 6
int main()
{
    float h=0,y=0;
    int x, counter = 0;
    time_t t;
    float tab[3];
    printf("podaj ilosc powtorzen: ");
    scanf(" %d",&x);

    srand(time(&t));

    do{
    int i;
    for(i=0;i<3;i++)
    {
        memset(tab, 0, 3);
        tab[i] = rand() % N + 1;

    }

    if(tab[0]<tab[1]<tab[2])
    {
        h++;

    }
    else
    {

        y++;
    }

    counter++;

    }while(counter<x);

    float prawdopodobienstwo;
    prawdopodobienstwo = h/x;

    printf("prawdopodobienstwo wynosi %f",prawdopodobienstwo);


    return 0;
}

mam już

 

komentarz 26 maja 2019 przez niezalogowany
Ale że co już rozwiązane czy co. Bo ja nie wiem dokładnie o co Ci chodzi z tym prawdopodobieństwem. Prawdopodobieństwo wylosowania kolejnych cyfr czy co.

    if(tab[0]<tab[1]<tab[2]) myślę że powinno być zapisane tak  if((tab[0]<tab[1])&&(tab[1]<tab[2]) )
komentarz 26 maja 2019 przez Maciej Złotorowicz Gaduła (4,230 p.)
edycja 26 maja 2019 przez Maciej Złotorowicz

możesz użyć memset do ustawienia tablicy na daną wartość (0) https://pl.wikibooks.org/wiki/C/memset tylko w rozmiarze musisz podać wartość w bajtach czyli sizeof(float)*N (N to liczba komórek tablicy)

komentarz 26 maja 2019 przez tkz Nałogowiec (42,000 p.)
Nie możesz użyć memset, ponieważ akceptuje int jako typ wartości.
komentarz 26 maja 2019 przez Maciej Złotorowicz Gaduła (4,230 p.)
do memseta wchodzi każdy wskaźnik. Problem jest jak chce się ustawić na konkretną wartość zmienną większą niż 1 bajt. Ale przy zerze/maksimum(każdy bajt na 255) nie ma problemu.
komentarz 26 maja 2019 przez j23 Mędrzec (194,920 p.)

Panowie, może po prostu:

tab[0] = tab[1] = tab[2] = 0.0;

:)

komentarz 26 maja 2019 przez niezalogowany
a ja nadal nie kumam po co zerować tablice skoro i tak za każdą pętlą jest nadpisywana chyba, że na początku tab[3]{0.0}
komentarz 7 listopada 2019 przez reaktywny Nałogowiec (40,990 p.)
dokładnie tak samo zmienna h i y.
komentarz 7 listopada 2019 przez mokrowski Mędrzec (155,460 p.)

@j23, 

.... funkcją memset nie powinno się zerować tablic float[]...

Z tego co czytałem, standard IEEE754 dla C, wymaga obsługi +0 i -0. Stąd dla samego 0 (tożsamego w reprezentacji z "zerem int"), zerowanie tablicy float czy double, nie jest niebezpieczne. Będzie bardzo niebezpieczne dla wypełniania takich tablic wartością.

Jeśli się mylę, proszę podaj źródła. Chętnie się zapoznam.

komentarz 8 listopada 2019 przez j23 Mędrzec (194,920 p.)
Chodzi o to, że liczba zmiennoprzecinkowa może być różnie kodowana i takie zerowanie jak leci ciągu bajtów może po prostu nie zadziałać poprawnie (mało prawdopodobne, ale...).
komentarz 8 listopada 2019 przez mokrowski Mędrzec (155,460 p.)
edycja 8 listopada 2019 przez mokrowski

W świetle standardu C, zmienny przecinek (float i double) ma być kodowany zgodnie z IEEE754. Tam występuje różna bitowa reprezentacja zera. Tzw. "dodatnie zero" i "ujemne zero". Język ma obsługiwać obydwa jako "wartość zero". Stąd akurat wstawienie zera tożsamego z reprezentacją bitową "integerowego zera", nie niesie ze sobą problemów. Inaczej jest dla innych wartości (różnych od zera). Dla long double które zapisane jest na większej ilości bitów niż 64, nie mam pewności.

Prosty przykład:

#include <stdio.h>
#include <stddef.h>

void show_repr(float val) {
    size_t size = sizeof(val);
    char * byte_ptr_to_val = (void *)(&val);
    printf("value: %10f bytes: ", val);
    for(size_t i = 0; i < size; ++i) {
        printf("%4d ", *(byte_ptr_to_val + i));
    }
    putchar('\n');
}

void show_repr_ldouble(long double val) {
    size_t size = sizeof(val);
    char * byte_ptr_to_val = (void *)(&val);
    printf("value: %10Lf bytes: ", val);
    for(size_t i = 0; i < size; ++i) {
        printf("%4d ", *(byte_ptr_to_val + i));
    }
    putchar('\n');
}

int main(void) {
    float z = -10.0e-30f * 10.0e-30f;
    show_repr(z);
    z = 0.0;
    show_repr(z);
    long double r = -10.0e-30f * 10.0e-30f;
    show_repr_ldouble(r);
    r = 1.0 - 1.0 + z;
    show_repr_ldouble(r);
    return 0;
}

Chociaż i dla long double, sprawdzałem że jest ok ale już nie szukałem czy to jest Implementation Defined czy ścisłe.

Stąd miałem pytanie skąd informacja by memset'em nie zerować floata lub doble (nie long double). Zerować IMHO można. Ustawiać już jest bardzo niebezpiecznie.

0 głosów
odpowiedź 7 listopada 2019 przez mokrowski Mędrzec (155,460 p.)

Masz trochę niezręczności.

1. Zasiew generatora wykonujesz podając mu unsigned int. Jeśli Twoją intencją jest inicjowanie czasem, to warto w time(...) podać NULL.

2. Jeśli chcesz wyzerować tablicę w C, to wystarczy:

float table[100] = { 0 };

W C to załatwia sprawę zerowania (ale taki zapis nie działa w C++).

3. Jeśli chcesz wyzerować tablicę już gdzieś w programie, możesz to zrobić z użyciem pętli niejako "ręcznie", lub z użyciem memset(...):

#include <stdio.h>
#include <string.h>

int main(void) {
    int tab[10000]; /* tu teraz są "śmiecie" */
    memset(tab, 0, sizeof(tab)); /* teraz następuje wypełnianie 0 */
    printf("%d\n", tab[9999]); /* Próba wyświetlenia ostatniej wartości z tablicy */
    return 0;
}

 

4. Jedną z prawidłowych definicji main(), jest:

int main(void) { //... 

W C jeśli nie podasz ilości argumentów, to funkcja potrafi przyjąć ich nieokreśloną liczbę. Stąd w C zawsze przy pustej liście argumentów, podaje się void.

4. Jeśli wylosowane liczby mają być umieszczone rosnąco, nie masz wyjścia i powinieneś je posortować. Dla 3 elementów wystarczy zestaw warunków i prosty kod. Pytanie tylko czy wylosowane wartości mają być powtarzalne czy nie?

5. Jeśli tablic nie alokujesz na stercie (malloc(...) i "przyjaciele"), to alokowane na stosie, zwalniane są po wyjściu z zakresu (czyli bloku kodu). Nie trzeba więc ich zwalniać.

 

–1 głos
odpowiedź 7 listopada 2019 przez mmarszik Mądrala (7,390 p.)

Proszę, ogólnie dla N liczb i M wartości (bez zerowania, bo to bez sensu jak w tablicy mają znaleźć się zaraz liczby)

https://github.com/mmarszik/eduUniqRndOrder/tree/master

/**
* Program losuje N liczb z zakresu od 1 do M w porządku rosnącym.
*/
#include <iostream>
#include <cstdlib>
#include <ctime>

static int getN() {
    std::cout << "Podaj ilość liczb: ";
    int n;
    std::cin >> n;
    return n;
}

static int getM() {
    std::cout << "Podaj zakres liczb: ";
    int m;
    std::cin >> m;
    return m;
}


int main(int argc, char *argv[])
{
    srand(time(NULL));
    const int N = getN();
    const int M = getM();
    if( M < N || N < 1 || M < 1 ) {
        std::cout << "Bledne dane! " << std::endl;
    }
    int *tab = new int[N];
    tab[0] = rand() % (M-N+1) + 1;
    for( int i=1 ; i<N ; i++ ) {
        tab[i] = rand() % ( M - tab[i-1] - (N-i) + 1 ) + tab[i-1] + 1;
    }
    for( int i=1 ; i<=N ; i++ ) {
        std::cout << i << " => " << tab[i-1] << std::endl;
    }
    delete[] tab;
    return 0;
}

 

komentarz 7 listopada 2019 przez mokrowski Mędrzec (155,460 p.)
Oj... recydywa.. :-) Znów zauważ że to C a nie C++.
komentarz 7 listopada 2019 przez mmarszik Mądrala (7,390 p.)
Trochę C++ nie zaszkodzi ;-)

Podobne pytania

+3 głosów
3 odpowiedzi 653 wizyt
pytanie zadane 7 listopada 2018 w Matematyka, fizyka, logika przez schedz Nowicjusz (220 p.)
0 głosów
2 odpowiedzi 467 wizyt
0 głosów
1 odpowiedź 1,674 wizyt

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...