OldComp.cz

Komunitní diskuzní fórum pro fanoušky historických počítačů


Právě je 20.04.2024, 00:54

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 39 ]  Přejít na stránku 1, 2, 3  Další
Autor Zpráva
PříspěvekNapsal: 24.07.2020, 18:19 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3663
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 797 times
Ahojte, mam taku malu otazocu na miestnych znalcov cecka.

Ako dynamicky vytvorit 2D pole ? Namiesto pevneho int pole[10],[20] chcem cosi ako int pole[X][Y] kde X,Y su premenne ktore budu zname az za behu programu. Na nete som nasiel vseliake navody, ale vsetky su zalozene na riadku pointerov ktore ukazuju na jednotlive stlpce pola. Ale toto ja nechcem, Ja potrebujem nejak nadeklarovat symbol pole tak aby ked urobim
Kód:
pole = malloc(X*Y*sizeof(int));
tak budem moct pouzivat obvyklu konstrukciu pole[index1][index1] ktoru kompiler spravne pochopi a skompiluje ju ako priamy pristup do pola, t.j. v style riadok * dlzka_stlpca + stlpec a nechcem aby sa vykonavanie programu zbytocne zdrzovalo citanim pointerov ktore ukazuju na jednotlive stlpce pola.

A da sa to vobec ?


Nahoru
 Profil  
 
PříspěvekNapsal: 24.07.2020, 18:55 
Offline
Pan Generální
Uživatelský avatar

Registrován: 23.03.2014, 20:13
Příspěvky: 2779
Has thanked: 226 times
Been thanked: 605 times
Jen od oka (muselo by se to prakticky vyzkoušet), co bude rychlejší: jedno čtení z pole indexů do pole prvků, nebo výpočet souřadnic ve dvourozměrné matici, převedené do lineární paměti?

_________________
Plesnivý sýr z Tesca, zatuchlé kuřecí řízky z Albertu, oslizlé hovězí a myší trus z Lidlu.
Nákup potravinářské inspekce v ČR, říjen 2023.


Nahoru
 Profil  
 
PříspěvekNapsal: 24.07.2020, 19:20 
Offline
Pan Štábní

Registrován: 11.11.2013, 10:29
Příspěvky: 1200
Has thanked: 364 times
Been thanked: 304 times
Program se "zbytecne" nezdrzuje zadnym ctenim pointru. Pointer je promenna, ktera ukazuje nekam do pameti. Pokud ti vadi to nasobeni, tak mi ver, ze vnitrne se stejne nasobeni nevyhnes. Proste radek je jeho 'cislo * delka + sloupec'. Zapisem pole[x][y] rikas to same, jen to nevidis. A jeste, pokud je pole dynamicke, tak kompilator nemuze vedet, kde je konec radku, potazmo celeho pole. To si musis pohlidat.
Zkus tohle:
https://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/
a nezapomen na:
Kód:
free(pole);

;-)

_________________
Sharp MZ-800++, MZ-1500++, MZ-2500++, SM-B-80T, MK-14_replica, HP-85, ZX-80+replica, ZX81, ZX-Spectrum+replica++, PMI-80+replica, SAM coupe++, PMD-85-2A+3, Didaktik-M, SORD-M5, TI-57, TI-59+PC-100, TI99/4A, ZetaV2+ppp, ZX-uno, Petr


Nahoru
 Profil  
 
PříspěvekNapsal: 24.07.2020, 21:11 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3663
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 797 times
faraon píše:
Jen od oka (muselo by se to prakticky vyzkoušet), co bude rychlejší: jedno čtení z pole indexů do pole prvků, nebo výpočet souřadnic ve dvourozměrné matici, převedené do lineární paměti?
Jednoznacne rychlejsi bude vypocet suradnic v matici na linearnu adresu. Kedze cely vypocet sa urobi v ramci procesora, je hotovy prakticky okamzite, kdezto citanie z pola pointerov je jeden pristup do pameti navyse, a to vzdy velmi zdrzuje.

Mikes21 píše:
Program se "zbytecne" nezdrzuje zadnym ctenim pointru.
No, takto. Bud si si moj dotaz poriadne neprecital, alebo mozno som to iba ja nenapisal dost zretelne. Takze skusim byt viac nazorny a konkretny.
Mikes21 píše:
Pointer je promenna, ktera ukazuje nekam do pameti. Pokud ti vadi to nasobeni, tak mi ver, ze vnitrne se stejne nasobeni nevyhnes.
Nasobenie ktore si tam kompiler vlozi sam, mi praveze vobec nevadi ! A okrem toho, ako som uz vyssie napisal, je to iba interna operacia v praci procesora, a ta je hotova velmi rychlo, vobec nezdrzuje.
Mikes21 píše:
Proste radek je jeho 'cislo * delka + sloupec'. Zapisem pole[x][y] rikas to same, jen to nevidis.
Presne toto chcem, aby kompiler interne robil, ked ja napisem pole[x][y].
Mikes21 píše:
A jeste, pokud je pole dynamicke, tak kompilator nemuze vedet, kde je konec radku, potazmo celeho pole.
Ved prave to je "gro" mojej otazky. Ako kompiler prinutit vygenerovat taky kod, aby velkost riadku nebral ako vopred znamu konstantu, ale ako premenlivu hodnotu, a nasobenie, ktore sa interne vykonava pri pouziti pole[x][y], robil nie s konstantou, ale s touto premennou.
Mikes21 píše:
A toto prave nechcem ! Ked sa poriadne pozries na vsetky tie priklady, tak je to bud o tom, ze ty ako programator musis "rucne" robit to nasobenie *(arr + i*c + j) = ..., alebo v pripade ak chces priamo pouzivat obvyklu konstrukciu pole[x][y] tak zase potrebujes este pridavne pole pointrov a pristup ku kazdemu prvku pola potrebuje dva pristupy do pameti.
Lenze ja kvoli prehladnosti vyslovene chcem pouzivat tento obvykly klasicky zapis pole[x][y] ale dvojity pristup do pameti je pre mna z dovodov efektivity jednoducho neakceptovatelny.
Mikes21 píše:
a nezapomen na:
Kód:
free(pole);
;-)
Tak na toto nastastie kludne zabudnut mozem, pretoze pri ukonceni procesu sa vsetka jeho pamet aj tak uvolni defaultne a akekolvek *free* je tu uplne zbytocne :)


Nahoru
 Profil  
 
PříspěvekNapsal: 24.07.2020, 21:33 
Offline
Kecálek

Registrován: 10.07.2014, 01:57
Příspěvky: 169
Has thanked: 25 times
Been thanked: 225 times
Busy píše:
Lenze ja kvoli prehladnosti vyslovene chcem pouzivat tento obvykly klasicky zapis pole[x][y] ale dvojity pristup do pameti je pre mna z dovodov efektivity jednoducho neakceptovatelny.


co tak:
Kód:
#define POLE(x,y) p[y*w+x]


Nahoru
 Profil  
 
PříspěvekNapsal: 24.07.2020, 21:52 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3663
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 797 times
ub880d píše:
Busy píše:
Lenze ja kvoli prehladnosti vyslovene chcem pouzivat tento obvykly klasicky zapis pole[x][y] ale dvojity pristup do pameti je pre mna z dovodov efektivity jednoducho neakceptovatelny.
co tak:
Kód:
#define POLE(x,y) p[y*w+x]
Ak by to slo takto:
Kód:
#define pole[x][y] p[y*w+x]
potom by to bolo riesenim. Ale takuto syntax v #define kompilery obvykle nepodporuju...


Nahoru
 Profil  
 
PříspěvekNapsal: 24.07.2020, 22:23 
Offline
Pan Štábní

Registrován: 11.11.2013, 10:29
Příspěvky: 1200
Has thanked: 364 times
Been thanked: 304 times
To ti vadi ty hranate zavorky? Tak to ti asi neni rady.

Citace:
... programator musis "rucne" robit to nasobenie *(arr + i*c + j) = ...,
on to prece dela ten program ;-) za chodu. Kompilator o tom ve sve dobe nema ani potuchy (A tvoje ruce taky ne, aby jsi to delal rucne). To nasobeni prece dela procesor uvnitr nebo... asi jsem nejaky unaveny a nechapu to. Pardon.

_________________
Sharp MZ-800++, MZ-1500++, MZ-2500++, SM-B-80T, MK-14_replica, HP-85, ZX-80+replica, ZX81, ZX-Spectrum+replica++, PMI-80+replica, SAM coupe++, PMD-85-2A+3, Didaktik-M, SORD-M5, TI-57, TI-59+PC-100, TI99/4A, ZetaV2+ppp, ZX-uno, Petr


Nahoru
 Profil  
 
PříspěvekNapsal: 24.07.2020, 23:28 
Offline
Kecálek

Registrován: 08.11.2019, 17:24
Příspěvky: 131
Bydliště: Beroun
Has thanked: 32 times
Been thanked: 8 times
Nemuzes misto pole pointeru alokovat pointer na pole, ktere ma rozmer tebou nactene cislo Y? Neco v tomto duchu:

Kód:
#include <stdio.h>
#include <stdlib.h>

int main()
{
   int x, y;
   scanf("%d%d", &x, &y);
   int (*a)[y] = malloc(x * y * sizeof(int));

   for (int i = 0; i < x; i++)
      for (int j = 0; j < y; j++)
         printf("a[%d][%d]: %p\n", i, j, &a[i][j]);

   return 0;
}


Vystup programu pak muze byt napr.:

Kód:
2
10
a[0][0]: 0x15656b0
a[0][1]: 0x15656b4
a[0][2]: 0x15656b8
a[0][3]: 0x15656bc
a[0][4]: 0x15656c0
a[0][5]: 0x15656c4
a[0][6]: 0x15656c8
a[0][7]: 0x15656cc
a[0][8]: 0x15656d0
a[0][9]: 0x15656d4
a[1][0]: 0x15656d8
a[1][1]: 0x15656dc
a[1][2]: 0x15656e0
a[1][3]: 0x15656e4
a[1][4]: 0x15656e8
a[1][5]: 0x15656ec
a[1][6]: 0x15656f0
a[1][7]: 0x15656f4
a[1][8]: 0x15656f8
a[1][9]: 0x15656fc


Nahoru
 Profil  
 
PříspěvekNapsal: 25.07.2020, 00:07 
Offline
Kecálek

Registrován: 10.07.2014, 01:57
Příspěvky: 169
Has thanked: 25 times
Been thanked: 225 times
Jakub píše:
Nemuzes misto pole pointeru alokovat pointer na pole, ktere ma rozmer tebou nactene cislo Y? Neco v tomto duchu:


na moje pocudovanie, netreba ani malloc:
Kód:
#include <stdio.h>

int main()
{
   int x, y;
   scanf("%d%d", &x, &y);
   int a[x][y];

   for (int i = 0; i < x; i++)
      for (int j = 0; j < y; j++)
         a[i][j]=i*y+j;
         
   for (int i = 0; i < x; i++)
      for (int j = 0; j < y; j++)
         printf("a[%d][%d]: %p, val=%d\n", i, j, &a[i][j], a[i][j]);

   return 0;
}

Kód:
$ ./test
2 4
a[0][0]: 0xbfbb5d20, val=0
a[0][1]: 0xbfbb5d24, val=1
a[0][2]: 0xbfbb5d28, val=2
a[0][3]: 0xbfbb5d2c, val=3
a[1][0]: 0xbfbb5d30, val=4
a[1][1]: 0xbfbb5d34, val=5
a[1][2]: 0xbfbb5d38, val=6
a[1][3]: 0xbfbb5d3c, val=7


otazka ale je, ako to je prenositelne medzi roznymi kompilermi...


Nahoru
 Profil  
 
PříspěvekNapsal: 25.07.2020, 00:19 
Offline
Kecálek

Registrován: 08.11.2019, 17:24
Příspěvky: 131
Bydliště: Beroun
Has thanked: 32 times
Been thanked: 8 times
ub880d píše:
Jakub píše:
Nemuzes misto pole pointeru alokovat pointer na pole, ktere ma rozmer tebou nactene cislo Y? Neco v tomto duchu:


na moje pocudovanie, netreba ani malloc:


Tak jasne, kdyz to nechces dynamicky alokovane, tak muzes pouzit staticke dvourozmerne pole (s promennou delkou).

ub880d píše:
otazka ale je, ako to je prenositelne medzi roznymi kompilermi...


IMHO jakykoliv slusny prekladac, co umi C99, ktere pridalo variable-length arrays. Ted jeste koukam, ze C11 VLA nemusi podporaovat, kdyz definuji makro __STDC_NO_VLA__.


Nahoru
 Profil  
 
PříspěvekNapsal: 25.07.2020, 00:23 
Offline
Radil

Registrován: 14.10.2013, 23:12
Příspěvky: 342
Has thanked: 261 times
Been thanked: 25 times
tohle je sice c++, ale kdyz nahradis new za malloc a poresis delete na konci, tak mas dynamicky alokovanou matici matice[ROW][COL]

Kód:
    int** matice = new int*[COL];
    for(int i = 0; i < ROW; ++i)
      *(matice + i) = new int[COL];
 
    for(int i = 0; i < ROW; ++i)
      for(int j = 0; j < COL; ++j)
        *(*(matice + i) +j) = i + j;
 
    for(int i = 0; i < ROW; ++i)
      for(int j = 0; j < COL; ++j)
        cout << "[i, j] = " << *(*(matice + i) +j) << endl;
 
    for(int i = 0; i < ROW; ++i)
      delete [] *(matice + i);
    delete [] matice;



nebo totez zapsano jinak:

Kód:
   int (*matice)[COL] = new int[ROW][COL];
 
    for(int i = 0; i < ROW; ++i)
      for(int j = 0; j < COL; ++j)
        matice[i][j] = i + j;
 
    for(int i = 0; i < ROW; ++i)
      for(int j = 0; j < COL; ++j)
        cout << "[i, j] = " << matice[i][j] << endl;
 
    delete [] matice;


Nahoru
 Profil  
 
PříspěvekNapsal: 25.07.2020, 21:17 
Offline
Pan Štábní
Uživatelský avatar

Registrován: 24.05.2018, 22:32
Příspěvky: 1975
Bydliště: Most, Praha
Has thanked: 870 times
Been thanked: 699 times
JohnBlbec píše:
tohle je sice c++, ale kdyz nahradis new za malloc a poresis delete na konci, tak mas dynamicky alokovanou matici matice[ROW][COL]
Kód:
    int** matice = new int*[COL];
    for(int i = 0; i < ROW; ++i)
      *(matice + i) = new int[COL];
 ...
To je pole pointerů, kterému se chtěl Busy vyhnout. Chce lineární pole, kde se offset prvku počítá jednoduchým násobením. K čemuž má nejblíž buď #define POLE(x,y) v C, nebo přetížení operátoru [] v C++ ( int* & Matrix::operator [](const int &index) const { return &mat[index * cols]; } ... tedy jedno lineární pole alokované s malloc, operátor [] vrací adresy řádků které spočítá násobením, druhý [] přičte sloupec ).

_________________
i++ (INC) increment
i-- (DEC) decrement
i@@ (EXC) excrement


Nahoru
 Profil  
 
PříspěvekNapsal: 26.07.2020, 11:46 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3663
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 797 times
Mikes21 píše:
To ti vadi ty hranate zavorky?
...
asi jsem nejaky unaveny a nechapu to. Pardon.
Ano, asi to tak bude :)
Pretoze ja som predtym napisal:
Busy píše:
Lenze ja kvoli prehladnosti vyslovene chcem pouzivat tento obvykly klasicky zapis pole[x][y]


Nahoru
 Profil  
 
PříspěvekNapsal: 26.07.2020, 11:52 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3663
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 797 times
Jakub píše:
Nemuzes misto pole pointeru alokovat pointer na pole, ktere ma rozmer tebou nactene cislo Y? Neco v tomto duchu:
Kód:
#include <stdio.h>
#include <stdlib.h>

int main()
{
   int x, y;
   scanf("%d%d", &x, &y);
   int (*a)[y] = malloc(x * y * sizeof(int));

   for (int i = 0; i < x; i++)
      for (int j = 0; j < y; j++)
         printf("a[%d][%d]: %p\n", i, j, &a[i][j]);

   return 0;
}
To vyzera zaujimavo, ale nedari sa mi to rozbehat:
Kód:
>gcc pole2.cpp
pole2.cpp: In function 'int main()':
pole2.cpp:8: error: invalid conversion from 'void*' to 'int (*)[(((unsigned int)(((int)y) + -0x000000001)) + 1)]'
Nemal by to byt iba warning ? To sa mi nejak nezda. Co vlastne realne vadi tomu kompileru ? Nedari sa mi najst vhodne pretypovanie aby mi to zozral.


Nahoru
 Profil  
 
PříspěvekNapsal: 26.07.2020, 11:58 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3663
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 797 times
Panda38 píše:
To je pole pointerů, kterému se chtěl Busy vyhnout. Chce lineární pole, kde se offset prvku počítá jednoduchým násobením.
Presne tak !
Panda38 píše:
přetížení operátoru [] v C++ ( int* & Matrix::operator [](const int &index) const { return &mat[index * cols]; } ... tedy jedno lineární pole alokované s malloc, operátor [] vrací adresy řádků které spočítá násobením, druhý [] přičte sloupec ).
Toto riesenie sa mi vidi zatial najlepsie. Mohol by si mi prosim uviest nejaky konkretny priklad typu tych vyssie uvedenych (co rovno skompilujem) ? S pretazovanim hranatych zatvoriek nemam vela skusenosti, a tie co mam, koncia u toho klasickeho znameho skolskeho prikladu na pretazene + - * / ktore pocitaju kompexne cisla...


Nahoru
 Profil  
 
Zobrazit příspěvky za předchozí:  Seřadit podle  
Odeslat nové téma Odpovědět na téma  [ Příspěvků: 39 ]  Přejít na stránku 1, 2, 3  Další

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 9 návštevníků


Nemůžete zakládat nová témata v tomto fóru
Nemůžete odpovídat v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete přikládat soubory v tomto fóru

Hledat:
Přejít na:  
cron
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz