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
Martin Konečný (pavelco1998):6.2.2015 10:55

Ahoj,

kvůli zjednodušení programu jsem si chtěl udělat pointer na funkci.
Problém nastane v případě, že je daná funkce vytvořena až na dalších řádcích.
Pro zjednodušení - potřebuji, aby mi fungoval tento script:

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

Takto mi to hází error, že "jinaFunkce" není deklarována (na řádku page = &jinaFunkce).

V C začínám, takže o tom prakticky nic nevím. Mohl by mi, prosím, někdo poradit?

Edit: pro jistotu doplním, že tyto dvě fce mám v externím .c souboru. Funkci "nejakaFunkce" pak volám v main().

Editováno 6.2.2015 10:57
Odpovědět
6.2.2015 10:55
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):6.2.2015 11:04
void jinaFunkce();
void nejakaFunkce();

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}
Editováno 6.2.2015 11:06
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
6.2.2015 11:04
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):6.2.2015 11:11

Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)

#include "subor.h"

int main(void)
{
  // nějaký kód
}

**Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)

#include "subor.h"

int main(void)
{
  // nějaký kód
}

**Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)

#include "subor.h"

int main(void)
{
  // nějaký kód
}

**Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)

#include "subor.h"

int main(void)
{
  // nějaký kód
}

**Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)

#include "subor.h"

int main(void)
{
  // nějaký kód
}

**Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)

#include "subor.h"

int main(void)
{
  // nějaký kód
}

**Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)

#include "subor.h"

int main(void)
{
  // nějaký kód
}

**Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)

#include "subor.h"

int main(void)
{
  // nějaký kód
}

**Ešte lepšie je to rozdeliť na:

//subor.h
void jinaFunkce();
void nejakaFunkce();

//subor.c
#include "subor.h"

void nejakaFunkce()
{
  void (*page)();
  page = &jinaFunkce;
  page();
}

void jinaFunkce()
{
  // nějaký kód
}

//main.c
#include "subor.h"

int main(void)
{
  // nějaký kód
}
Nahoru Odpovědět
6.2.2015 11:11
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Martin Konečný (pavelco1998):6.2.2015 11:31

Super, díky za pomoc.
Jen ještě menší problém - jde nějak vytvořit referenci na funkci, jejíž název získám jako string z pole?

Pro příklad

// poleFunkci[2] = "jinaFunkce"
page = &poleFunkci[2];
page();
Nahoru Odpovědět
6.2.2015 11:31
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Libor Šimo (libcosenior):6.2.2015 11:57

Nejak mi to zblblo, môže to niekto napraviť?

Nahoru Odpovědět
6.2.2015 11:57
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
David.Landa
Člen
Avatar
Odpovídá na Martin Konečný (pavelco1998)
David.Landa:6.2.2015 12:34

Proč v poli nemít rovnou ukazatele na funkce? V C++ můžeš použít mapu (

std::map

) s názvy funkcí namapovanými na ukazatele na funkce.

Editováno 6.2.2015 12:38
 
Nahoru Odpovědět
6.2.2015 12:34
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):6.2.2015 13:02

Mohlo by to byť nejak takto:

// fce.h
#ifndef FCE_H_INCLUDED
#define FCE_H_INCLUDED
#include <stdio.h>
typedef void (*P_FCE) ();
void fce1();
void fce2();
void fce3();
void fce4();
#endif // FCE_H_INCLUDED

// fce.c
#include "fce.h"
void fce1()
{
    printf("Funkcia 1\n");
}
void fce2()
{
    printf("Funkcia 2\n");
}
void fce3()
{
    printf("Funkcia 3\n");
}
void fce4()
{
    printf("Funkcia 4\n");
}

// main.c
#include "fce.h"

int main(void)
{
    P_FCE p_poleFunkcii[4];
    int opakovat = 1, c;

    p_poleFunkcii[0] = fce1;
    p_poleFunkcii[1] = fce2;
    p_poleFunkcii[2] = fce3;
    p_poleFunkcii[3] = fce4;

    //printf("Zadaj 1 - 4 pre vypis funkcie, 0 pre ukoncenie: ");
    while (opakovat != 0) {
        printf("Zadaj 1 - 4 pre vypis funkcie, 0 pre ukoncenie: ");
        c = getchar();
        fflush(stdin);
        switch (c) {
            case '1':
                p_poleFunkcii[0]();
                break;
            case '2':
                p_poleFunkcii[1]();
                break;
            case '3':
                p_poleFunkcii[2]();
                break;
            case '4':
                p_poleFunkcii[3]();
                break;
            case '0':
                opakovat = 0;
                break;
            default:
                printf("Mino rozsah!\n");
        }
    }

    return 0;
}
Editováno 6.2.2015 13:03
Nahoru Odpovědět
6.2.2015 13:02
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na David.Landa
Martin Konečný (pavelco1998):6.2.2015 13:09

Hmm, zdá se, že to funguje a je to jednodušší. Díky za tip!
Rád bych ti za to dal nějaké body, ale další rozdat nemůžu :(

Nahoru Odpovědět
6.2.2015 13:09
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Libor Šimo (libcosenior)
Martin Konečný (pavelco1998):6.2.2015 13:13

To vypadá zajímavě. Potřebuji si to zjednodušit, abych nemusel pořád psát podmínky, ale stačilo mi jen něco jako

c = getchar();
poleFunkci[c]();

V PHP bych si s tím poradil během pár sekund, ale C je hrůza :D

Nahoru Odpovědět
6.2.2015 13:13
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):6.2.2015 13:15

To je len ukážka ako by to mohlo byť. Prispôsobíš si to na svoje podmienky.

Nahoru Odpovědět
6.2.2015 13:15
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
David.Landa
Člen
Avatar
Odpovídá na Martin Konečný (pavelco1998)
David.Landa:6.2.2015 13:20

Díky, to je život no .) Jinak je důležité, jestli problém řešíš v C nebo C++. V C++ je většinou v knihovně nějaká datová struktura, kterou si jinak musíš v C implementovat sám.

 
Nahoru Odpovědět
6.2.2015 13:20
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):6.2.2015 13:23

getchar() nebude pracovať, pretože berie znak. Treba použiť:

scanf("%d", &c);
p_poleFunkcii[c]();
Nahoru Odpovědět
6.2.2015 13:23
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
David.Landa
Člen
Avatar
David.Landa:6.2.2015 15:34

Pokud použiješ mapu, můžeš volat funkci pomocí názvu (C++).

#include <iostream>
#include <string>
#include <map>

using namespace std;

typedef void (*fun_p)(void);
typedef map<string, fun_p> fun_map;

void fun1(void){ cout << "--1--" << endl; }
void fun2(void){ cout << "--2--" << endl; }

int main()
{
    fun_map fm;
    fm["f1"] = &fun1;
    fm["f2"] = &fun2;
    //-------------------
    fun_p fp1 = fm["f1"];
    fun_p fp2 = fm["f2"];
    //-------------------
    fp1();
    fp2();

    //nebo

    fm["f1"]();
    fm["f2"]();

    return 0;
}
Editováno 6.2.2015 15:36
 
Nahoru Odpovědět
6.2.2015 15:34
Avatar
Odpovídá na Libor Šimo (libcosenior)
Martin Konečný (pavelco1998):6.2.2015 16:58

Jo jo, upravil jsem si to podle potřeb, díky!

Nahoru Odpovědět
6.2.2015 16:58
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na David.Landa
Martin Konečný (pavelco1998):6.2.2015 17:00

V C++ bych to dělal mnohem radši, ale bohužel musím čisté C :(
Každopádně také díky za radu, aspoň vím něco navíc.

Nahoru Odpovědět
6.2.2015 17:00
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):7.2.2015 7:39

Ešte pre zjednodušenie v jednom súbore s 2 funkciami:

#include <stdio.h>

typedef void (*P_FCE) ();

void fce1() { printf("Funkcia 1\n"); }
void fce2() { printf("Funkcia 2\n"); }

int main(void)
{
    P_FCE fun[] = { &fce1, &fce2 };
    int i;

    scanf("%d", &i);
    fun[i - 1]();

    return 0;
}

Ale normálny program by mal byť zložený z vlastnej knižnice a spúšťacieho súboru.

Editováno 7.2.2015 7:41
Nahoru Odpovědět
7.2.2015 7:39
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 16 zpráv z 16.