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

Macierze, deklaracja dynamiczna

0 głosów
984 wizyt
pytanie zadane 4 stycznia 2016 w C i C++ przez Macek Kolo Mądrala (5,480 p.)

Dostałem zadanie by zrobić kilka zadań związanych z macierzami(proste operacje dodawania, czy zerowanie). Oczywiście nie znam wielkości, więc mam to zrobić dynamicznie(zaznaczę, ze to język C, nie C++). I teraz moje pytanie, kolega powiedział, że jeśli chodzi akurat o macierze to lepiej zrobić je na "jednym" wskaźniku:

int * ptr = (int*)malloc(m*n*sizeof(int)); 

a nie z wskaźnikiem na wskaźnik. I moje pytanie, czy to jest normalny zabieg? Czy tak jest prościej? Tak trzeba przy macierzach, czy to wymysł tylko? 

3 odpowiedzi

+2 głosów
odpowiedź 4 stycznia 2016 przez Krawiec91 Pasjonat (19,600 p.)
wybrane 4 stycznia 2016 przez Macek Kolo
 
Najlepsza

Przy tym sposobie, czy przy sposobie z tablicą wskaźników zostanie zaalokowana pamięć na (m*n) zmiennych typu int, więc w tym względzie nie ma żadnej różnicy.
 

Czy tak jest prościej?

Zrób eksperyment, wypróbuj jeden i drugi sposób. Będziesz mógł stwierdzić, czy jest prościej czy nie.;)
Dla osoby średnio otrzaskanej we wskaźnikach, tablicach, zakładając, że stworzymy tablicę dwuwymiarową 4 x 5 i chcemy się odwołać do elementu w 3 wierszu i 4 kolumnie, moim zdaniem bardziej strawny będzie zapis:

//tworzenie tablicy 2-wym
int** matrix=(int**)malloc(4*sizeof(int*));
for (i=0;i<4;i++)
   matrix[i]=(int*)malloc(5*sizeof(int)));

//odwolanie do elementu w 3 wierszu i 4 kolumnie
  printf("%d",matrix[3][4]);

niż zapis:

int* matrix=(int*)malloc(20*sizeof(int));

printf("%d",matrix[19]);  //4 wiersze (0,1,2,3) po 5 kolumn = 20
                                          

Zapis pierwszy jest bardziej naturalny w tym przypadku, drugi nie jest już tak intuicyjny, co wcale nie oznacza że nie jest poprawny.
 

Tak trzeba przy macierzach, czy to wymysł tylko?

Ten sposób działania nie ma specjalnego przeznaczenia, że tylko przy macierzach.

komentarz 4 stycznia 2016 przez Macek Kolo Mądrala (5,480 p.)
ale przy wypełnianiu, czy manipulacjach te dwie pętle strasznie przeszkadzają. A jak dochodzi jeszcze jedna pętla bo chcesz wyznacznik obliczyć, to już w ogóle jakoś głupio.

Osobiście wole chyba jednak to podejście z jednym wskaźnikiem. A dodatkowo znalazłem to: http://forum.4programmers.net/C_i_C++/262823-struktura_definiujaca_macierz?p=1204394#id1204394 więc tym bardziej mnie utwierdza w "jednej słusznej drodze" ;P
komentarz 4 stycznia 2016 przez Krawiec91 Pasjonat (19,600 p.)
Przedstawiłem jak to widzę, moim zdaniem z tablicą wskaźników bardziej czytelny. Ale to, też może z przyzwyczajenia, "że tak się robi" i koniec. Dla jednego prościej będzie tak, dla innego prościej będzie sposób. Jeden lubi blondynki, drugi brunetki a trzeci murzynki.;)
Jak sposób z jednym wskaźnikiem jest dla Ciebie lepszy, poręczniejszy, nie gubisz się w nim, to rób w ten sposób.
Pozdrawiam
+3 głosów
odpowiedź 4 stycznia 2016 przez draghan VIP (106,230 p.)

Tak trzeba przy macierzach, czy to wymysł tylko? 

Nie trzeba - macierz można potraktować jak tablicę dwuwymiarową (tablica dwuwymiarowa jest programistycznym odpowiednikiem matematycznej dwuwymiarowej macierzy).

A że tablicę dwuwymiarową można potraktować jak jednowymiarową, to i takie rzeczy można zrobić. Teoretycznie taka operacja jest szybsza, bo alokujesz od razu cały blok potrzebnej Ci pamięci...

Jednak musisz odpowiedzieć sobie na pytanie: czy warto, kosztem czytelności? :)

komentarz 4 stycznia 2016 przez Macek Kolo Mądrala (5,480 p.)
W sumie z tego co zrozumiałem to niezależnie, czy zrobimy to na *, czy na ** to w pamięci komputera i tak wszystko będzie "liniowe", a co do dostawania się do elementów to nie będę chyba mieć problemów, bo w sumie uczyliśmy się wszystkich bajerów z wyłuskaniem jak *(tab+2) i innymi.
komentarz 4 stycznia 2016 przez draghan VIP (106,230 p.)
W programowaniu chodzi o dwie sprawy:

1. Dostarczyć działający produkt. Tak pisać kod, żeby to działało zgodnie z założeniami i autor-programista powinien raczej wiedzieć, dlaczego. ;)

2. Tak pisać kod, aby był łatwy do czytania i zrozumienia. I to nie tylko przez Ciebie. Jak mówiłem i ja, i Krawiec91 - zapis tablicy dwuwymiarowej jest czytelniejszy w kontekście macierzy. Programy pisane w C rządzą się dziwnymi prawami - nie wiedzieć dlaczego ludzie bardzo często komplikują sobie zapis (a innym odczyt).
Ludzie myślą, że jak napiszą jakąś pogmatwaną, pokrętną instrukcję, to wygląda profesjonalnie... A jest dokładnie na odwrót. Profesjonalny kod jest przede wszystkim przejrzysty.

Pozdrawiam. :)
komentarz 4 stycznia 2016 przez Macek Kolo Mądrala (5,480 p.)
edycja 4 stycznia 2016 przez Macek Kolo
Nie no, to a wiem, że ktoś może kiedyś ten kod czytać, czytałem "Czysty kod", ale teraz tak szukam po internetach i wychodzi na to, że ten zapis z jednym wskaźnikiem, jest szybszy dlatego się go stosuje przy macierzach. Przy jakiś małych, nie ma problemu, ale jak masz wiele i są duże, to podobno lepiej :)

EDIT. W GNU Scientific Library(GSL) właśnie macierze są na jednym wskaźniku.
0 głosów
odpowiedź 4 stycznia 2016 przez nouveu Bywalec (2,560 p.)

W sumie z tego co zrozumiałem to niezależnie, czy zrobimy to na *, czy na ** to w pamięci komputera i tak wszystko będzie "liniowe"

Ktoś napisał taki komentarz. Otóż niekoniecznie, tab[5*5] będzie miała 25 komórek koło siebie czyli "liniowo", tablica[5][5] będzie miała 1+5 obszarów "liniowych" po 5 komórek każdy.

Jaka jest różnica? A no taka że przy rozmiarze 100000000 komputer musi znaleźć taki ciągły obszar pamięci albo go sobie zrobić przenosząc inne dane. W najgorszym przypadku komputer nie da rady zarezerwować takiego obszaru i program się wysypie.

komentarz 4 stycznia 2016 przez Macek Kolo Mądrala (5,480 p.)
no ale co ma tablica do wskaźnika na obszar pamięci? Przecie to dwie bajki. Jak robisz realloc to szuka w pamięci wystarczająco dużo wolnego miejsca i tam dodaje do istniejącej wielkości dodatkowe komórki pamięci. W pamięci są obok siebie ustawiane(nie mówie tutaj o fizycznej)

Podobne pytania

0 głosów
0 odpowiedzi 423 wizyt
+1 głos
1 odpowiedź 1,038 wizyt
pytanie zadane 7 stycznia 2016 w C i C++ przez dreez Początkujący (320 p.)
0 głosów
2 odpowiedzi 1,156 wizyt

93,425 zapytań

142,421 odpowiedzi

322,647 komentarzy

62,787 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

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...