Zwracanie tablic wielowymiarowych za pomocą funkcji

0

Witam,
Mam problem ze zwróceniem tablicy dwuwymiarowej z funkcji tak, aby rekordy tablicy dało się przesortować/wyświetlić w następnej funkcji.
Przy tablicach jednowymiarowych wyświetlanie zawartości tablicy daje ten sam wynik w funkcji wprowadzenie_danych() oraz w funkcji wyswietlanie_danych().
Wyniki automatycznie są zwracane dalej, w dwuwymiarowych niestety nie chce mi to działać.

Poniżej kod :

#include <iostream>
#include <iomanip>
#include <windows.h>
#include <time.h>
#include <cmath>
#include <conio.h>
#include <stdlib.h>
#include <limits>

using namespace std;

int licznik = 0;
int licznik1 = 0;
int tab[24][1];

int wprowadzenie_danych()
{
    for (int j = 0; j <= 4; j++) {

        for (int i = 5; i <= 9; i++) {
            tab[licznik][0] = i;
            tab[licznik][1] = j;
            //cout<<"a = "<<tab[licznik][0]<<"   b = "<<tab[licznik][1]<<endl<<endl;   PRAWIDŁOWE WYŚWIETLANIE
            licznik++;
        }
    }
}
int wyswietlanie_danych()
{

    for (int i = 0; i <= 24; i++) {
        cout << "a = " << tab[i][0];
        cout << "   b = " << tab[i][1] << endl
             << endl; // NIE PRAWIDŁOWE WARTOŚĆI
    }
}

int main()
{
    wprowadzenie_danych();
    wyswietlanie_danych();
    return 0;
}
5

Mamy 2020 C++11 jest już dość stare, a tablice z C dość kłopotliwe (szczególnie dla początkujących).
Dlatego radziłbym, używać std::array, albo starego poczciwego std:::vector.

A problem polega na tym, że wykraczasz poza zakres tablicy.
int tab[24][1]; oznacza, że pierwszy indeks ma zakres od 0 do 23 a drugi tylko indeks 0 ma sens.
24 oznacza liczbę elementów, a nie ostatni możliwy indeks.

1

Nie wiem czemu tak Chcesz to robić, tak jak powyżej jest lepiej. Ale, taki kod, co prawda w C, ale to chyba nie problem, generuje i zwraca losową, dwuwymiarową, N x N, tablicę integerów, (wskaźnik do wskaźnika na integera):

int ** genRandomTwoDimArray(int N, int rank){
    srand((unsigned) time(NULL));
    int **out;
    out = malloc(sizeof(int*) * N); 
    for (int i = 0; i < N; ++i) {
		out[i] = malloc(sizeof(int*) * N);
	}
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<N; j++)
        {
            out[i][j] = rand()%rank;
        }
    }
    return out;
}
2
MarekR22 napisał(a):

Mamy 2020 C++11 jest już dość stare, a tablice z C dość kłopotliwe (szczególnie dla początkujących).
Dlatego radziłbym, używać std::array, albo starego poczciwego std:::vector.

A problem polega na tym, że wykraczasz poza zakres tablicy.
int tab[24][1]; oznacza, że pierwszy indeks ma zakres od 0 do 23 a drugi tylko indeks 0 ma sens.
24 oznacza liczbę elementów, a nie ostatni możliwy indeks.

Dodam, że prezentowany kod w "C ze strumieniami" marnuje wiele szans jakie są możliwe w najprostszych "szkolnych" rozwiązaniach obiektowych.
Multum tutaj zadań z tablic dwuwymiarowych. Czy ja kiedyś zobaczę, że początkujący zrobi klasę implementującą tablicę?

A są potworki na zmiennych globalnych itd... BTW "zwracanie tablic" tutaj jest niemożliwe z samej zasady.

1

@AnyKtokolwiek:

BTW "zwracanie tablic" tutaj jest niemożliwe z samej zasady

Tak, ale można to "zasymulować" wskaźnikami.

1
lion137 napisał(a):

@AnyKtokolwiek:

BTW "zwracanie tablic" tutaj jest niemożliwe z samej zasady

Tak, ale można to "zasymulować" wskaźnikami.

Gdy są statyczne? Zresztą pytający nawet nie próbuje (paradoksalnie słusznie) ich zwracać

0

Hmm, dzięki za odpowiedzi. Pamiętam, że tak uczyłem się w szkole i jakoś mi tak zostało, po edycji int taba na [25][2] jest wszystko w porządku :) wartość nie jest "zwracana" returnem ale można z niej korzystać dalej w kodzie. Jak skończę ten program spróbuje się przestawić na dzisiejsze standardy :D

1
gritness napisał(a):

Hmm, dzięki za odpowiedzi. Pamiętam, że tak uczyłem się w szkole i jakoś mi tak zostało, po edycji int taba na [25][2] jest wszystko w porządku :) wartość nie jest "zwracana" returnem ale można z niej korzystać dalej w kodzie. Jak skończę ten program spróbuje się przestawić na dzisiejsze standardy :D

Sądzę, że dopasowanie tablicy do (początkowo błędnej) pętli to zły kierunek. Nigdy w życiu tak nie będziesz miał.
Zwyczajowo i skutecznie się to załatwia przez ostrą nierówność w warunku pętli. Z wielu powodów, np prawdopodobnie masz po dwie stałe: 24 i 25 (źle!) oraz 1 i 2 i z innych powodów

(mniejsze zamiast mniejsze lub równe)


 for (int i = 0; i < 24; i++)
0
AnyKtokolwiek napisał(a):
gritness napisał(a):

Hmm, dzięki za odpowiedzi. Pamiętam, że tak uczyłem się w szkole i jakoś mi tak zostało, po edycji int taba na [25][2] jest wszystko w porządku :) wartość nie jest "zwracana" returnem ale można z niej korzystać dalej w kodzie. Jak skończę ten program spróbuje się przestawić na dzisiejsze standardy :D

Sądzę, że dopasowanie tablicy do (początkowo błędnej) pętli to zły kierunek. Nigdy w życiu tak nie będziesz miał.
Zwyczajowo i skutecznie się to załatwia przez ostrą nierówność w warunku pętli. Z wielu powodów, np prawdopodobnie masz po dwie stałe: 24 i 25 (źle!) oraz 1 i 2 i z innych powodów

(mniejsze zamiast mniejsze lub równe)


 for (int i = 0; i < 24; i++)

poniżej część funkcji z pętlami :

for(a=24;a<=115;a++)
{

        for(b=24;b<=115;b++)
            {
                for(c=24;c<=115;c++)
                {
                    for(d=24;d<=115;d++)
                    {
                        e=a/b;
                            e=round(e*1000000)/1000000;

                            f=c/d;
                                f=round(f*1000000)/1000000;

                                I=e*f;
                                    I=round(I*1000000)/1000000;



                           if(I <= p_plus && I >= p_minus)
                            {



                                tab_wyniki[licznik][0]=a;
                                tab_wyniki[licznik][1]=b;
                                tab_wyniki[licznik][2]=c;
                                tab_wyniki[licznik][3]=d;
                                tab_wyniki_i[licznik][0]=I;


                                /*cout<<tab_wyniki[licznik][0]<<endl;
                                cout<<tab_wyniki[licznik][1]<<endl;
                                cout<<tab_wyniki[licznik][2]<<endl;
                                cout<<tab_wyniki[licznik][3]<<endl;
                                cout<<tab_wyniki_i[licznik][0]<<endl<<endl;*/
                            licznik++;
                        }



                }

            }


    }
0

Dużo mam na nie.

  1. Seria podstawień [0] ...[3] pachnie jak struktura (tzn cztery liczby o różnym charakterze)
  2. Magiczne stałe (a C++ ma const'y)
  3. mam wrażenie męczysz się z tym zaokrągleniem (nie podałeś deklaracji). Pachnie jak źle dobrane typy, i to ma konsekwencje. Coś nie gra EDIT: czytam ten kod kolejny raz i jestem pewien, że nie gra, chcesz wygrzebać się z jakiegoś problemu (jak socjalizm), który sam spowodowałeś.
  4. Dodam z komentarza: olbrzymia deklaracja tablicy na zapas.
  5. dzielenie całkowitoliczbowe. W 99% nie to, o co pomysłodawcy chodzi. Jak o to chodzi, warto to jakoś wyraziście zformalizować.
    Deklaracji nie dałeś. Ten kod nie ma sensu zarówno jak domniemać a,b,c,d int, jak i double.
  6. Niepotrzebne #includy od sasa do lasa, od windows.h do conio.h
  7. Nie wierzę (w tym również samemu sobie), gdy autor mówi "to na pewno jest dobrze", zwłaszcza w C. Starzy programiści przejeżdżają tablice, nie kupuję wiary poczatkujaćych
  8. skąd wiara w zaokrąglenie w górę?
0

AnyKtokolwiek nie czepiaj się :
6.includy są potrzebne do innej części kodu
5.nie ma dzielenia całkowito-liczbowego, bo np wynik e/f z założenie nie jest liczbą całkowitą (deklaracja long double)
4.rozmiar tablicy jest uzależniony od danych zewnętrznych
3. zaokrąglanie jest mi po prostu potrzebne (jest to założenie z dokumentacji, żeby wyszukać odpowiednie wyniki)
2.Magiczne stałe, bo to zwyczajna ilość
1.Mi tam ładnie pachnie D

0
gritness napisał(a):

6.includy są potrzebne do innej części kodu

Tym gorzej: nie masz podziału na tematyczne moduły.
Wg mnie conio.h nie ma sensu razem w windows.h.

4.rozmiar tablicy jest uzależniony od danych zewnętrznych

Sam zapewniasz, że 1000

  1. zaokrąglanie jest mi po prostu potrzebne (jest to założenie z dokumentacji, żeby wyszukać odpowiednie wyniki)

Pewnie autor (dokumentacji) też czegoś nie rozumiał. Tak prosta rzecz, jak zmienny przecinek, jest bardzo często rozumiana źle.
A przez elektroników od maszyn tym bardziej (w większości).

Użycie tutaj long double świadczy raczej o panice przed nieznanymi duchami, niż wiedzy i świadomości.
Po czym poznać spanikowanego żołnierza? Ma hełm na lewej stronie

   long double e=a/b;
   e=round(e*1000000)/1000000;

To wyrażenie jest BARDZO charakterystyczne i na kilometr czuć problem autora.

2.Magiczne stałe, bo to zwyczajna ilość

Tak czy inaczej, tego się nie robi.

1.Mi tam ładnie pachnie D

Bo struktura ładnie pachnie, wystarczy ją użyć (w tym punkcie się nie upieram, tylko mi pachnie)

Dowiemy się, jakiego typu są a,b,c,d ?

0

zmienne są typu int od 24 do 115, dla przykładu 113/27
... daje wynik ... 4, a Ty mi wytłumacz dlaczego

0

Ale grasz gritnes:
edit są zadeklarowane double, właśnie z tego powodu

jeśli a,b,c,d masz zadeklarowane double, to jedynie kwestią wiary (w wyżej wymienione duchy) i kadzidełek jest, czy ostatni przebieg pętli jest dla 114.99999, czy dla 113.000001.
Przenigdy się nie robi takich pętli na zmiennym przecinku (choć mogą się "udać", ale to ma działać na pewno, a nie z kadzidełkami)

0

AnyKtokolwiek pewnie nie możesz uwierzyć, że to działa :) Ale działa

0

Np dla wcześniejszego przykładu 27/113 gdzie a=27 b=113
e=a/b;
e=round(e*1000000)/1000000;

0

Do zamknięcia, problem rozwiązani 20 zbędnych komentarzy wcześniej. Pozdrawiam :)

1

A jakie jest zapotrzebowanie na zaokrąglanie do określonej liczby miejsc dziesiętnych? Bo jeśli chodzi o wyświetlanie liczb, to możesz się zawieść, bo niekoniecznie dostaniesz wynik, którego reprezentacja dziesiętna będzie miała 6 liczb po przecinku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1