Funkce vracející pointer na pole – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Funkce vracející pointer na pole – C / C++ – Fórum – Programujte.comFunkce vracející pointer na pole – C / C++ – Fórum – Programujte.com

 

Martin
~ Anonymní uživatel
1601 příspěvků
21. 2. 2013   #1
-
0
-

Zdravim,
v první řadě mne nekamenujte za lamadotaz, s C začínám a problém jsem se snažil hledat(asi nedostatečně).
Chtěl bych vrátit funkcí pointer na pole typů (holý C). Jak mám deklarovat funkci? Jak mám deklarovat a inicializovat ten vracenej pointer? Myslel jsem, že nějak třeba takhle, ale překladač mi to celkem reklamoval:

int *p_pole(int a, int b){
    int soucet;
    soucet = a+b;
    int pole[3];
    pole[0]=a;
    pole[1]=b;
    pole[2]=soucet;
    int (*p_pole)[];  //pointer na pole
    p_pole=&pole[0];
    return p_pole;
}

díky za tip, jednou se tomu budu smát...

Nahlásit jako SPAM
IP: 193.35.102.–
vitamin+8
Grafoman
21. 2. 2013   #2
-
0
-

pole == pointer;   //su tam dake rozdieli, ale pre tvoj pripad to vyzera takto:

int pole[8];
int* pointer;

pointer = pole;	//pointer ukazuje na 1. prvok pola 'pole'

return pointer;	//vratis pointer

Problem je ale inde, ty vracias pointer(pole je tiez pointer) na lokalnu premennu. Po opusteni funckie sa zmaze pole a vrat sa  pointer na prvy prvok pola (samozrejme ten prvok tam uz oficialne nie je    )

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Martin
~ Anonymní uživatel
1601 příspěvků
21. 2. 2013   #3
-
0
-

#2 vitamin
ok, fajn, ale jak teda vrátim z nějaké funkce pole, když pokaždé bude nutně lokální? Třeba ve složitějších případech nebudu vědět, jak to pole bude vypadat a budu ho muset vytvořit až ve funkci? Globální proměnné používat nechci.

že pole[0]== *pointer je jasné...

Nahlásit jako SPAM
IP: 193.35.102.–
KIIV
~ Moderátor
+43
God of flame
21. 2. 2013   #4
-
0
-

dynamicka alokace pameti... s ni ale pak vyvstane problem s jejim uvolnovanim... (coz neni problem u neceho co hned skonci, ale u sluzby co bezi porad uz by to delalo slusne problemy)

Nahlásit jako SPAM
IP: 62.216.147.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Radek Chalupa
~ Redaktor
+1
Super člen
21. 2. 2013   #5
-
0
-

#1 Martin
Třeba nějak takhle:

void vrat_pole(int** p_pole, ...)
{
  *p_pole = (int*)malloc(pocet_prvku);
  // nějak naplnit pole
}

void volani()
{
  int* pole = NULL;
  vrat_pole(&pole);
  // použít pole
  free(pole);
}

Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 213.220.211.–
Martin
~ Anonymní uživatel
1601 příspěvků
21. 2. 2013   #6
-
0
-

Bezva, díky... Takhle to bude asi většinou stačit. Už si jenom zvyknout na pointry na pointry na pole pointrů na pointry na funkce třeba... život není krásný. :)

Nahlásit jako SPAM
IP: 193.35.102.–
Martin
~ Anonymní uživatel
1601 příspěvků
25. 2. 2013   #7
-
0
-

ok, technická. nemůžu přijít na to, proč mi to kape na i==2. Kód by měl generovat náhodné souřadnice pro známou hru lodě:

void vytvorLode(lod**pole,int pocet){
        *pole = (lod *) calloc(pocet,sizeof(lod));
         srand ( time(NULL) );
        int nahodne = ((int) rand())%5;
        for (int i=0; i<pocet;i++){
            pole[i]->x = nahodne;
            int nahodne2 = ((int) rand())%5;
            pole[i]->y  = nahodne2;
            pole[i]->potopena=0;
        }//for
}//vytvorLode

struktura lod jsou tři integery. funkci volám takhle:

lod *pole=NULL;
vytvorLode(&pole,3);

překladač mi vynadal do "Signal received: SIGSEGV (Segmentation fault)". Asi se odkazuju nějak nesmyslně..
Moje představy: funkci předávám pointer na typ lod; funkce vezme pointer a alokuje místo v paměti na několik struktur typu lod; pak nasází náhodně hodnoty do struktur lod v alokované paměti... tak co mi uniká?
Díky za tipy....

Nahlásit jako SPAM
IP: 193.35.102.–
KIIV
~ Moderátor
+43
God of flame
25. 2. 2013   #8
-
0
-

pole je pointer na pointer...      pole[i]->...  dela neco uplne jinyho nez myslis...  schvalne jestli na to prijdes sam

Nahlásit jako SPAM
IP: 2001:af0:ffcf:866:a1f4:8c...–
Program vždy dělá to co naprogramujete, ne to co chcete...
MartinH0
Newbie
25. 2. 2013   #9
-
0
-

to proto, že mi to IDE přepsalo z tečky. Myslel jsem, že je to normální zápis takový definice. takže místo 

pole[i]->x = nahodne;

dám

(*pole)[i].x = nahodne;

... zdá se, že to dělá zhruba to, co chci, tak myslim, že jsem se trefil.

jinak cesta za C/C++ je trnitá, tak jsem si tu rovnou zrobil profil, abyste věděli, že zas prosí vo radu ten lammer, pro příště...

Nahlásit jako SPAM
IP: 193.35.102.–
KIIV
~ Moderátor
+43
God of flame
25. 2. 2013   #10
-
0
-

#9 MartinH
no vidis jak ti to jde :)

to abys na to prisel sam je z jineho duvodu nez ze bys byl "lamer" --  kdyz to zvladnes vyresit s malym nakopnutim, tak je to vetsi pomoc, nez kdyz to nekdo vyresi za tebe...

Nahlásit jako SPAM
IP: 62.216.147.–
Program vždy dělá to co naprogramujete, ne to co chcete...
MartinH0
Newbie
25. 2. 2013   #11
-
0
-

#10 KIIV
Ale vsak ja vim, ze to myslis dobre... tak aby Ti to vydrzelo, az se budu ptat po milion-sesty :) Beztak dik, nepovazuju fundovanou radu za uplnou samozrejmost..

Nahlásit jako SPAM
IP: 193.35.102.–
MartinH0
Newbie
27. 2. 2013   #12
-
0
-

Co je blbý, že mi někde něco uniká... calloc má nulovat alokovanou paměť, nebo ne? Používám netbeans jako IDE, který zobrazí pole jenom, když si růčo přidám watches alá *pole@rozsah. V nultym indexu jsou nuly, v prvnim je nula jenom v proměnný x a y, v dalších indexech už jsou nesmysly... Uvažuju dost stejnej kód, jako doposud:

void vytvorLode(lod*pole[],int pocet,int velikost){
    printf("generuju lode, cekej\n");
        *pole = (lod*) calloc(pocet,sizeof(lod));
        if (pole==0){
            printf("nepodarilo se alokovat pamet!\n");
            exit(1);
        }
        srand ( time(NULL) );
        int nahodne;
        int nahodne2;
        for (int i=0; i<pocet;i++){ //tolikrat, kolik je lodi
                nahodne=rand()%(velikost+1);
                nahodne2=rand()%3%(velikost+1);
                int konflikt=1;
                while (konflikt>0){
                    konflikt=KontrolujSouradnice(pole,i,nahodne,nahodne2); //kontrola duplicit souradnic
                    nahodne=rand()%(velikost+1);
                    nahodne2=rand()%3%(velikost+1);
                }//whend
                (*pole)[i].x = nahodne;
                *(*pole+i).y  = nahodne2;
        }//4
}//vytvorLode


koukám se teda někam jinam? jestli ano, tak jak definuju "watch" na pointer tak, aby to vypadalo jako pole a mohl jsem tak debugovat s aktuálníma hodnotama? Nebo je pudl zakopanej jinde?

Nahlásit jako SPAM
IP: 193.35.102.–
KIIV
~ Moderátor
+43
God of flame
27. 2. 2013   #13
-
0
-

minimalne mi je docela podezrely   *(*pole+i).y  = nahodne2;  

pak mas dost problem s:    nahodne2=rand()%3%(velikost+1);    dostanes maximalne 0,1,2

EDIT: zkompilovat to jde s  (*((*pole)+i)).y  jinak ma prednost tecka pred *

dokonce i ten calloc funguje

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
zlz
~ Anonymní uživatel
634 příspěvků
27. 2. 2013   #14
-
0
-

Nekomplikuj si to, udělej si lokální proměnnou a ty dereference vyházej.

void vytvorLode(lod **ppole, int pocet, int velikost)
{
    lod *pole = calloc...
    pole[i].x = ...
    ...
    *ppole = pole;
}
Nahlásit jako SPAM
IP: 78.156.159.–
MartinH0
Newbie
27. 2. 2013   #15
-
0
-

#13 KIIV
pravda, *(*pole+i).y jsem jen tak testoval, jak se bude chovat, originálně má být stejný přiřazení, jako na předchozím řádku.
nahodne2, to je taky pravda, tam nemá být modulo, ale obyč dělení třema(prozatim, asi to neni nejideálnější:)).
ale moje ide (+ kompilátor gcc/g++) mi ukazuje pořád prapodivný hodnoty v poli, když se ho pokoušim zobrazit tak, jak jsem popsal... Čili bych si tak myslel, že se pokoušim koukat na ten pointer nějak blbě...

Nahlásit jako SPAM
IP: 193.35.102.–
MartinH0
Newbie
27. 2. 2013   #16
-
0
-

#14 zlz
Aasi pro začátek dobrej nápad. Ale jinak je blbý, že se někde zas zakládá proměnná, žere to paměť a je to z principu pomalejší (pro začáteční tréningový projekty nepodstatný)..

jinak ale i s těma dereferencema by to mělo fungovat stejně, ne?

Nahlásit jako SPAM
IP: 193.35.102.–
MartinH0
Newbie
27. 2. 2013   #17
-
0
-

jak to vidim hned po calloc

Nahlásit jako SPAM
IP: 193.35.102.–
zlz
~ Anonymní uživatel
634 příspěvků
27. 2. 2013   #18
-
0
-

Ne pro začátek, to je vždycky dobrej nápad. Nežere to celkem nic, je to jen ukazatel a když tu dereferenci nebudeš muset dělát pořád dokola, tak je to naopak rychlejší. Ale hlavně se v tom kódu pak dá vyznat a nemusíš každý řádek analyzovat. Proto to máš celé blbě ;)

Nahlásit jako SPAM
IP: 78.156.159.–
zlz
~ Anonymní uživatel
634 příspěvků
27. 2. 2013   #19
-
0
-

   

lod *lode = (lod*)0x123;
vytvorLode(&lode, ...);

void vytvorLode(lod*pole[],int pocet,int velikost){
    pole == &lode;
    pole[0] == lode/*0x123*/;
    *pole == lode/*0x123*/;
*pole = (lod*) calloc(pocet,sizeof(lod));  // OK
if (pole==0){ // NESMYSL

Nahlásit jako SPAM
IP: 78.156.159.–
KIIV
~ Moderátor
+43
God of flame
27. 2. 2013   #20
-
0
-

co je to vubec za kompilator? kazdopadne z vypisu to vypada, ze prochazis prvni rozmer ne az druhej...

co zkusit radsi normalni datovy typ.. treba  lod ** pole.... 

a co to zkusit mimo tudle funkci vypsat pomoci printf...  

kazdopadne gcc 4.6 hazelo chyby .. hlavne u ty hnusny konstrukce jak sem zminoval...

Nahlásit jako SPAM
IP: 94.112.35.–
Program vždy dělá to co naprogramujete, ne to co chcete...
MartinH0
Newbie
27. 2. 2013   #21
-
0
-

#18 zlz
hmm, máš pravdu, políčko je teď jako ze škatulky.
 

if (pole==0){ // NESMYSL

timhle jsem myslel situaci, kdy ukazatel na blok paměti bude null, když z nějakýho důvodu calloc selže.. (vrací přeci null při neúspěchu?)
Jinak díky za rady, snad se to vstřebá 

Nahlásit jako SPAM
IP: 193.35.102.–
zlz
~ Anonymní uživatel
634 příspěvků
27. 2. 2013   #22
-
0
-

Výsledek calloc je v *pole!

Nahlásit jako SPAM
IP: 78.156.159.–
MartinH0
Newbie
27. 2. 2013   #23
-
0
-

-gcc i g++ ver. 3.4.4
-myslel jsem, že lod**pole == lod*pole[], páč jsem měl za to, že pole[] je vlastně jenom ukazatel?
-printf bych pro zajímavost vyzkoušet měl...

Nahlásit jako SPAM
IP: 193.35.102.–
MartinH0
Newbie
27. 2. 2013   #24
-
0
-

#22 zlz
bod pro tebe.. opět :)

Nahlásit jako SPAM
IP: 193.35.102.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 13 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý