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

Prawdopodobieństwo, Programowanie C

VPS Starter Arubacloud
0 głosów
472 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 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,650 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 639 wizyt
pytanie zadane 7 listopada 2018 w Matematyka, fizyka, logika przez schedz Nowicjusz (220 p.)
0 głosów
2 odpowiedzi 458 wizyt
0 głosów
1 odpowiedź 1,656 wizyt

92,455 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...