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

Przekazywanie struktury przez argumenty funkcji.

Object Storage Arubacloud
0 głosów
220 wizyt
pytanie zadane 15 grudnia 2015 w C i C++ przez GameFreak Początkujący (450 p.)

Witam

Mam taki kodzik. Nie potrafie zrobić tego w taki sposób żeby zapytać usera o ilość kulek które mają być wylosowane. Moją ilość kulek oznacza zapis const int numbers = 10; RRecordData tab[numbers]; Nie wiem jak zrobić to w inny sposób aby posłać tyle kulek ile user by chciał. Prosze o pomoc. 

#include <iostream>
#include <cstdio>
#include <windows.h>
#include <clocale>
#include <cstring>
#include <time.h>

using namespace std;

struct RRecordData
{
    int ID;
    int Number;
};

const int numbers = 10;
RRecordData tab[numbers];

int RandRange(int min, int max)
{
    return min + rand() % (1 + max - min);
}

void RetrunNumbers(int minimum, int maximum)
{
    for(int i = 0; i < numbers; i++)
    {
    tab[i].ID = i;
    tab[i].Number = RandRange(minimum,maximum);
    }
}

void ShowNumbers()
{
    for(int i = 0; i<numbers; i++)
    printf("| %d | %3d   |\n", tab[i].ID, tab[i].Number);
}

int main()
{
    int mini,maxi;
    //const int numbers;
    //printf("Podaj ilosc kulek do wylosowania: ");
    //scanf("%d", &numbers);

    printf("Podaj najmniejsza wartosc losowanej kulki: ");
    scanf("%d", &mini);
    printf("Podaj najwieksza wartosc losowanej kulki: ");
    scanf("%d", &maxi);

    printf("-------------\n");
    printf("|ID | Number|\n");
    printf("-------------\n");

    srand(time(NULL));

    RetrunNumbers(mini,maxi);

    ShowNumbers();

    return 0;
}

 

2 odpowiedzi

0 głosów
odpowiedź 15 grudnia 2015 przez Sebastian Fojcik Nałogowiec (43,040 p.)

Dołączasz bibliotekę <iostream> a korzystasz z przestarzałych funkcji wypisujących tekst "print"...

Musisz najpierw wczytać rozmiar tablicy, a później zaalokować pamięć na tablicę o takim rozmiarze. Robi się to dynamicznie. Nie musisz tego jeszcze rozumieć w 100%, ale pokażę Ci jak to się zapisuje, abyś otrzymał tablicę typu: "RRecordData"

int rozmiar;
// wczytaj rozmiar od usera
RRecordData * tab = new RRecordData[ rozmiar ];

Od teraz posługujesz się tablicą "tab" tak jak normalną tablicą. Wszystko powinno śmigać. Wczytywanie zapisałem jako komentarz, bo nigdy nie używałem funkcji scanf(), bo to standard "C" :-)

U Ciebie żadna funkcja nie przyjmuje jako argumentu tablicy, bo owa tablica jest globalna (FATALNE ROZWIĄZANIE!!!). Funkcja NIGDY nie powinna pracować na zmiennych globalnych. Deklaruj tablicę w main(), a później przekaż do funkcji.
Funkcja przyjmująca tablicę:

void funkcja( RRecordData tab[], int rozmiar )

Wywołanie funkcji:

funkcja( tab, rozmiar );

Żadnej większej filozofii :-)

komentarz 15 grudnia 2015 przez GameFreak Początkujący (450 p.)

No jestem na I roku studiów. WYmagają odemnie żebym używał printf itp. Wiesz mi że z wielką checią nie korzystałbym z elementów języka C ale nie nie poradzę :P Najpierw chciałem zrobić to zadanie właśnie bez dynamicznej alokacji pamięci a potem właśnie to pozmieniać. Muzse w tym zadaniu użyć struktury. Już teraz się zamotałem kompletnie :P Przypuśćmy że zadeklaruje RRecordData tab[numbers]; w main, ponieważ chcę pobrać numbers od użytkownika. To jest moja pierwsza funkcja którą wywołuje RetrunNumbers( RRecordData tab​,mini,maxi); posyłam jej minimalna liczbe od ktorej ma zaczać losować i maksymalna czyli poporstu zakres losowania. JAK WYSŁAĆ DO NIEJ TĄ TABLICE ? I potem w void RetrunNumbers(RRecordData tab[], int minimum, int maximum) CO wpisać  w pogrubione miejsca bo nie ejstem w stanie już nic wymyslec :P

komentarz 15 grudnia 2015 przez Sebastian Fojcik Nałogowiec (43,040 p.)
edycja 15 grudnia 2015 przez Sebastian Fojcik

Najpierw przenieś tablicę tab oraz zmienną numbers do main'a.
W main'ie wczytaj numbers od użytkownika i dynamicznie utwórz tablicę tak jak pokazałem to wcześniej.
(bez dynamicznej tablicy nie masz szans tego zrobić. Chyba, że wolno wam korzystać z vectorów, które bądź co bądź też są dynamicznymi tablicami :-P)

Następnie pozamieniaj deklaracje funkcji na następujące:

void RetrunNumbers( RRecordData tab[], int numbers, int minimum, int maximum)

oraz

void ShowNumbers( RRecordData tab[], int numbers )

Natomiast funkcje wywołujesz w main'ie od teraz następująco:

RetrunNumbers(tab, numbers, mini, maxi);
ShowNumbers( tab, numbers );

Wprowadź powyższe poprawki, które zasugerowałem i powinno śmigać. Jeśli nie, to pytaj dalej, będziemy działać :-)

PS. Zauważyłeś, że funkcję nazwałeś "Retrun" a nie "Return"? To tak specjalnie? :-D

komentarz 15 grudnia 2015 przez GameFreak Początkujący (450 p.)

#include <iostream>
#include <cstdio>
#include <windows.h>
#include <clocale>
#include <cstring>
#include <time.h>

using namespace std;

struct RRecordData
{
    int *ID;
    int Number;
};

int RandRange(int min, int max)
{
    return min + rand() % (1 + max - min);
}

int main()
{
    int mini,maxi;
    int numbers;

    printf("Podaj ilosc kulek do wylosowania: ");
    scanf("%d", &numbers);

    printf("Podaj najmniejsza wartosc losowanej kulki: ");
    scanf("%d", &mini);

    printf("Podaj najwieksza wartosc losowanej kulki: ");
    scanf("%d", &maxi);

    RRecordData Losowanie;

    Losowanie.ID = new int [numbers];
    srand(time(NULL));

    for(int i = 0; i < numbers ; i++)
    {
     Losowanie.ID[i]=i;
     Losowanie.Number=RandRange(mini,maxi);
    }

    printf("-------------\n");
    printf("|ID | Number|\n");
    printf("-------------\n");

    for(int i = 0; i<numbers; i++)
    printf("| %d | %3d   |\n", Losowanie.ID[i], Losowanie.Number[i]);// tu mam blad jakas rada ?:P

    delete [] Losowanie.ID;


    return 0;
}

komentarz 15 grudnia 2015 przez GameFreak Początkujący (450 p.)
HELP !!!! :D
komentarz 15 grudnia 2015 przez Sebastian Fojcik Nałogowiec (43,040 p.)
edycja 15 grudnia 2015 przez Sebastian Fojcik

Błąd masz tutaj:

Losowanie.Number[ i ]

Zauważ, że składnik "Number" w twojej strukturze jest zwykłym intem, zwykłą pojedynczą zmienną. Nie możesz więc używać kwadratowych nawiasów, które są zarezerwowane dla tablic (chyba, że je przeładujesz :-P)
Zamień to po prostu na:

Losowanie.Number

No... po tej poprawce pozwoliłem sobie skompilować Twój program i prawie działa:Dasz radę naprawić losowanie? Wiesz czego Ci jeszcze brakuje, czy podpowiedzieć?

komentarz 15 grudnia 2015 przez GameFreak Początkujący (450 p.)

Chodzilo mi o wyswietlanie wsyzstkich zapisanych liczb. Zrobilem to teraz tak. Nie wiem czy tak można i czy to najlepsze rozwiazanie ale dziala.

#include <iostream>
#include <cstdio>
#include <windows.h>
#include <clocale>
#include <cstring>
#include <time.h>

using namespace std;

struct RRecordData
{
    int *ID;
    int *Number;
};

int RandRange(int min, int max)
{
    return min + rand() % (1 + max - min);
}

int main()
{
    int mini,maxi;
    int numbers;

    printf("Podaj ilosc kulek do wylosowania: ");
    scanf("%d", &numbers);

    printf("Podaj najmniejsza wartosc losowanej kulki: ");
    scanf("%d", &mini);

    printf("Podaj najwieksza wartosc losowanej kulki: ");
    scanf("%d", &maxi);

    RRecordData Losowanie;

    Losowanie.ID = new int [numbers];
    Losowanie.Number = new int [numbers];

    srand(time(NULL));

    for(int i = 0; i < numbers; i++)
    {
     Losowanie.ID[i]=i;
     Losowanie.Number[i]=RandRange(mini,maxi);
    }

    printf("----------------\n");
    printf("|  ID  | Number |\n");
    printf("-----------------\n");

    for(int j = 0; j<numbers; j++)
    printf("| %4d | %4d   |\n", Losowanie.ID[j], Losowanie.Number[j]);

    delete [] Losowanie.ID;
    delete [] Losowanie.Number;

    return 0;
}

 

komentarz 15 grudnia 2015 przez Sebastian Fojcik Nałogowiec (43,040 p.)

Haha, zabawnie to jest napisane. Okej, poprawię kod i po prostu napiszę, co zrobiłem. Tak będzie najszybciej i najefektywniej :-)

#include <iostream>
#include <cstdio>
#include <windows.h>
#include <clocale>
#include <cstring>
#include <time.h>

using namespace std;

struct RRecordData
{
	int ID;
	int Number;
};

int RandRange( int min, int max )
{
	return min + rand() % (1 + max - min);
}

int main()
{
	int mini, maxi;
	int numbers;

	printf( "Podaj ilosc kulek do wylosowania: " );
	scanf( "%d", &numbers );

	printf( "Podaj najmniejsza wartosc losowanej kulki: " );
	scanf( "%d", &mini );

	printf( "Podaj najwieksza wartosc losowanej kulki: " );
	scanf( "%d", &maxi );

	RRecordData * Losowanie = new RRecordData[ numbers ];

	srand( time( NULL ) );

	for( int i = 0; i < numbers; i++ )
	{
		Losowanie[ i ].ID = i;
		Losowanie[ i ].Number = RandRange( mini, maxi );
	}

	printf( "----------------\n" );
	printf( "|  ID  | Number |\n" );
	printf( "-----------------\n" );

	for( int j = 0; j<numbers; j++ )
		printf( "| %4d | %4d   |\n", Losowanie[ j ].ID, Losowanie[ j ].Number );

	delete[] Losowanie;

	return 0;
}

Linijka 35: Nie tworzyłem tak jak Ty, jednego obiektu struktury z dwoma tablicami, lecz tablicę obiektów z dwoma zmiennymi (Twój sposób, jest trochę komiczny :-P)
Linijka 41 i 42: Zamieniłem: Losowanie.ID[ i ] = i; na Losowanie[ i ].ID = i;
Linijka 50:
 Zamieniłem:
Losowanie.ID.[ j ], Losowanie.Number.[ j ]
na
Losowanie[ j ].ID, Losowanie[ j ].Number
Linijka
 52: Zmieniłem sposób usunięcia tablicy

No, teraz Twój program jest bajlando majstersztyk :-D
Przeanalizuj moje poprawki i zastanów się dlaczego Twój sposób był komiczny :-P

Jeżeli nie rozumiesz skąd coś, to pisz jeszcze. Już tyle czasu Ci poświęciłem, że wynagrodź mi to chociaż yes XD

komentarz 15 grudnia 2015 przez GameFreak Początkujący (450 p.)
Dziękówa bardzo. Dopiero zaczynam z programowaniem ale dzieki za dobre wskazówki. Pozdrawiam
–1 głos
odpowiedź 15 grudnia 2015 przez Delebrith Początkujący (250 p.)
Proponuję stworzyć listę jednokierunkową. Jedna kulka jest strukturą. W strukturze dodatkowo umieszczasz wskaźnik na kolejną strukturę i dynamicznie przydzielasz pamięć każdej kolejnej. Wtedy w pętli zrobisz tyle ile użytkownik poda.
komentarz 15 grudnia 2015 przez adrian17 Ekspert (344,860 p.)
Listy pisze się najwyżej żeby się nauczyć wskaźników, ale nie po to żeby je używać w praktyce; jeśli ktoś chce normalnie przekazywać jakiś kontener ze nieznaną liczbą elementów to używa się zwykłych wskaźników na tablice albo po prostu std::vector.

Podobne pytania

0 głosów
1 odpowiedź 1,020 wizyt
pytanie zadane 26 sierpnia 2018 w C i C++ przez Hinzeq Użytkownik (860 p.)
0 głosów
2 odpowiedzi 567 wizyt
pytanie zadane 29 grudnia 2018 w Java przez studenciak Nowicjusz (230 p.)

92,579 zapytań

141,429 odpowiedzi

319,657 komentarzy

61,963 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!

...