Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Tayson
Člen
Avatar
Tayson:12.2.2015 13:20

Zdravim. Mal by som nejaky otazky ohladom pointrov.

  1. Ak mam funciu ktora prijima pointre teda napriklad void Add(int *a, int *b) tak ked ju vola tak pouzijem takyto zapis add(&a,&b)... rozumiem ze predavam adresy tychto premennych ale ked predavam adresy tak preco su vo fukkcii parametre s hviezdickou ???
  2. Kedy alebo naco pouzivat ukazovatel na funkciu ... ked si vlastne mozem hoci kedy zavolat funkciu naco na nu vytvarat ukazovatel

3)Ked si vlastne vytvorim pointer int *A; a potom pouzijem funkciu malloc:
A = (int *)malloc(n * sizeof (int));
Tak dalej ked chcem naplnat to pole preco sa nepouziva zapis takyto :
for(i=0;i<=n;i++)
{
*A[i]=i;
}
Ale takyto:
for(i=0;i<=n;i++)
{
A[i]=i;
}
Dakujem za odpovede.

 
Odpovědět
12.2.2015 13:20
Avatar
David Novák
Tvůrce
Avatar
Odpovídá na Tayson
David Novák:12.2.2015 13:55
  1. hvězdička v deklaraci parametrů říká překladači, že se jedná o pointer na uvedený typ
  2. já to jednou použil, když jsem měl funkci na ověření, zda se jedná o platná data a jednou se ověřovalo, jestli tam jsou písmena, podruhé jestli čísla
int is_param(const char *argv, int (*p_function)())
{
   for (int i = 0; argv[i] != '\0'; i++)
   {
      if (!p_function(argv[i]))
         return 0;
   }
   return 1;
}

Volání pak probíhalo nějak takhle: is_param(argv[1], isalpha) nebo is_param(argv[1], isdigit)

Proč? Jen tak... :D Vypadalo to hezky. Vím, že se dá ověřit i jednodušeji, jestli je řetězec číslo/slovo, ale cílem bylo procvičit si základní věci bez použití pokročilých funkcí..
Zkráceně - ukazatel na funkci můžeš použít třeba, když máš jeden kód provádějící jednu věc - třeba průchod polem - a chceš tam používat více různých funkcí a nechceš psát pro každý případ funkci (při větším množství už by to bylo značně nepraktické)

3)
protože A[i] je ukazatel na i. prvek pole A.. Proměnná A je ukazatel (na svůj první prvek) a A[i] rovná se *(A+1)

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
12.2.2015 13:55
Chyba je mezi klávesnicí a židlí.
Avatar
Tayson
Člen
Avatar
Odpovídá na David Novák
Tayson:12.2.2015 14:19

Takze volanie druhej funkcie vo nejakej funkcii nebude fungovat ? Treba na nu spravit ukazovatel a vtedy mozem v inej funkcii volat funkciu ? To je ten druhy bod. A kto mu tretiemu este sa chcem vratit ze ked je A ukazovatel na svoj prvy prvok tak preco ho potom inicializujem ako int *A; ???? A skusal som naplnat v cykle for sposobom *(A+i)=i; Ale nefungovalo mi to

 
Nahoru Odpovědět
12.2.2015 14:19
Avatar
David Novák
Tvůrce
Avatar
Odpovídá na Tayson
David Novák:12.2.2015 14:30

Nevím, jestli tě správně chápu..

Samozřejmě, že můžeš ve funkci volat jakoukoliv funkci.. ale představ si, že máš nějakou složitou strukturu, kterou procházíš svou funkcí a něco tam děláš.. taková funkce může mýt třeba 100 řádků.

No a ty tam chceš dělat pokaždé něco jiného.. Dejme tomu, že máš dvacet funkcí, která tam chceš za určitých podmínek použít.. Buď to uděláš tak, že pro každou tu možnost napíšeš samostatnou možnost, tj.

for (int i = 0; argv[i] != '\0'; i++)
{
   if (!isdigit(argv[i]))
      return 0;
}

Pak další funkce:

for (int i = 0; argv[i] != '\0'; i++)
   {
      if (!moje_fce(argv[i]))
         return 0;
   }

a tak dál.. všímej, že pokaždé musíš znovu napsat ten cyklus.. pokud by to byla složitější struktura, budeš mít komplikovanější kód.. a obzvlášť, když tam budeš provádět x věcí.. a bude se ti měnit jen ta jedna funkce..

s pomocí ukazatele na fci ti zůstane jedna jediná funkce.. kterou si vždycky zavoláš a jen jí upřesníš, kterou tu funkci má použít.. :)

to *(A+i) vyzkouším.. nerad bych nějak mystifikoval.. :D

Nahoru Odpovědět
12.2.2015 14:30
Chyba je mezi klávesnicí a židlí.
Avatar
David Novák
Tvůrce
Avatar
Odpovídá na Tayson
David Novák:12.2.2015 14:37

To *(A+i) funguje.. :D

Tu máš ukázku obou přístupů:

int main()
{
    int n = 10;
    int *A = (int *)malloc(n * sizeof (int));
    for(int i = 0; i < n; i++)
    {
        *(A+i) = i;
    }

    for (int i = 0; i < n; i++)
        printf("%i \n", A[i]);
}

Chybu máš v i <= n... V C začíná pole nulou.. tzn. když budeš mít n = 10, tak poslední prvek je i==9..

Nahoru Odpovědět
12.2.2015 14:37
Chyba je mezi klávesnicí a židlí.
Avatar
David Novák
Tvůrce
Avatar
Odpovídá na Tayson
David Novák:12.2.2015 14:49

ještě k té deklaraci..

int *A; můžeš slovy říct jako: "A je ukazatel na int"

Kdybys tam tu hvězdičku nedal, byl by A normální int.. ;) A je ukazatel protože jsi ho tak deklaroval. Chtěl jsem tím říct, že každé pole je vlastně ukazatel na první prvek.. Zároveň ale taky musíš překladači říct, jaký datový typ.. aby věděl, kolik zabírá bytů v paměti a jak s ním pracovat.. :)

takže třeba int pole[10]; je pole deseti intů.. a proměnná pole je ukazatel na int, která ukazuje na první prvek..
mohl bys udělat třeba toto:

int *ukazatel2;
ukazatel2 = pole + 1;

ukazatel2 ti ukáže na stejný prvek jako pole[1].. :)

Nahoru Odpovědět
12.2.2015 14:49
Chyba je mezi klávesnicí a židlí.
Avatar
Tayson
Člen
Avatar
Odpovídá na David Novák
Tayson:12.2.2015 15:02

printf("%i \n", A[i]);
Pozeram na tento vypis a nebude mozne to vypisat takto ?
printf("%i \n", *(A+i)); kde to bude v cykle for tak isto ako ty. Bude to aj takto fungovat ?
A este k tomu polu tak ja si urobim toto int *A = (int *)malloc(n * sizeof (int));
kde malloc vracia adresu a ulozim si ju do *A ale tak ked vracia adresu tak mi to dava ze by tam malo byt A iba nie ? vies mi toto vysvetllit ?

 
Nahoru Odpovědět
12.2.2015 15:02
Avatar
David Novák
Tvůrce
Avatar
Odpovídá na Tayson
David Novák:12.2.2015 15:10

Jo.. jsou to ekvivalentní zápisy :)

to *A je tam protože je to deklarace a zároveň přiřazení..

můžeš to taky napsat takhle:

int *A;
A = (int *)malloc(n * sizeof (int));
Nahoru Odpovědět
12.2.2015 15:10
Chyba je mezi klávesnicí a židlí.
Avatar
Odpovídá na Tayson
Libor Šimo (libcosenior):12.2.2015 15:23

Najhlavnejší rozdiel v
int A[10];
a
int *A = (int *) malloc(10 * sizeof(int));
je v tom, že prvý spôsob vytvorí pole v zásobníku a druhý v halde(hromade). Ešte pre doplnenie.
Zásobník sa uvoľňuje sám, pamäť vyčlenená v halde sa musí uvoľniť príkazom.

Editováno 12.2.2015 15:25
Nahoru Odpovědět
12.2.2015 15:23
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.