Diskuze: pointer na funkci, která je vytvořena až dále

C++ C a C++ pointer na funkci, která je vytvořena až dále

Avatar
Martin Konečný (pavelco1998):

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
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):
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í
+1 bodů
Ř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):

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):

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
Avatar
Libor Šimo (libcosenior):

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:

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):

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):

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
Avatar
Odpovídá na Libor Šimo (libcosenior)
Martin Konečný (pavelco1998):

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
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):

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:

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):

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:

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 David.Landa
Martin Konečný (pavelco1998):

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
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Libor Šimo (libcosenior):

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.