C Academy · Oppitunti

Funktio-osoitintaulukot

Välitysmallit.

Oppitunti 4/413 vaihetta

Funktio-osoitintaulukot on ilmainen C Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C Academy-kurssilla on yhteensä 4 oppituntia.

Funktiotaulukot

Funktio-osoittimia voi tallentaa taulukkoon ja muodostaa näin jakotaulukon. Indeksi tai koodi valitsee suoritettavan funktion ja korvaa pitkät if-else- tai switch-ketjut.

#include <stdio.h>

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }

int main(void) {
    int (*ops[2])(int,int) = { add, sub };
    printf("%d\n", ops[0](5, 3));
    printf("%d\n", ops[1](5, 3));
    return 0;
}

Taulukon indeksointi

Valitkaa operaatio ajon aikana indeksoimalla taulukkoa. Indeksi voi tulla käyttäjän syötteestä tai ohjelman tilasta.

#include <stdio.h>

int mul(int a, int b) { return a * b; }
int add(int a, int b) { return a + b; }

int main(void) {
    int (*ops[2])(int,int) = { add, mul };
    int choice = 1;
    printf("%d\n", ops[choice](6, 7));
    return 0;
}

switch-rakenteen korvaaminen

Jakotaulukko on usein selkeämpi kuin switch, kun jokainen tapaus vain kutsuu funktiota.

#include <stdio.h>

void start(void) { printf("start\n"); }
void stop(void)  { printf("stop\n"); }
void pause(void) { printf("pause\n"); }

int main(void) {
    void (*table[3])(void) = { start, stop, pause };
    for (int i = 0; i < 3; i++) table[i]();
    return 0;
}

typedef selkeyttää taulukkoa

Funktio-osoitintyypin määrittäminen typedef-määreellä tekee taulukon määrityksestä lyhyen ja luettavan.

#include <stdio.h>

typedef int (*BinOp)(int,int);

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }

int main(void) {
    BinOp ops[] = { add, sub };
    printf("%d\n", ops[0](10, 4));
    return 0;
}

Symbolien yhdistäminen funktioihin

Yhdistäkää kukin operaattorisymboli vastaavaan funktioon rinnakkaisissa taulukoissa tai rakenteista koostuvassa taulukossa, josta haku tehdään nimen perusteella.

#include <stdio.h>

typedef int (*BinOp)(int,int);

int add(int a, int b){return a+b;}
int sub(int a, int b){return a-b;}

int main(void) {
    char syms[] = {'+', '-'};
    BinOp ops[] = { add, sub };
    char want = '-';
    for (int i = 0; i < 2; i++)
        if (syms[i] == want) printf("%d\n", ops[i](9, 2));
    return 0;
}

Rakenteisiin perustuva komentotaulukko

Yhdistäkää nimi ja käsittelijä rakenteeseen ja muodostakaa niistä taulukko. Tämä on perinteinen komentotaulukkomalli.

#include <stdio.h>
#include <string.h>

typedef struct {
    const char *name;
    void (*run)(void);
} Command;

void hello(void){printf("hi\n");}
void bye(void){printf("bye\n");}

int main(void) {
    Command cmds[] = {{"hello", hello}, {"bye", bye}};
    const char *input = "bye";
    for (int i = 0; i < 2; i++)
        if (strcmp(cmds[i].name, input) == 0) cmds[i].run();
    return 0;
}

Rajojen tarkistaminen

Vahvistakaa aina indeksi ennen taulukon kautta kutsumista, jotta taulukon lopun yli ei lueta.

#include <stdio.h>

typedef int (*Fn)(int);
int sq(int x){return x*x;}
int neg(int x){return -x;}

int main(void) {
    Fn table[] = { sq, neg };
    int n = 2;
    int idx = 5;
    if (idx >= 0 && idx < n) printf("%d\n", table[idx](3));
    else printf("index out of range\n");
    return 0;
}

Tilakoneet

Jakotaulukot ohjaavat tilakoneita: kukin tila on funktio-osoitin, ja käsittelijät palauttavat seuraavan tilan indeksin.

#include <stdio.h>

int state_a(void){ printf("A\n"); return 1; }
int state_b(void){ printf("B\n"); return -1; }

int main(void) {
    int (*states[2])(void) = { state_a, state_b };
    int s = 0;
    while (s >= 0) s = states[s]();
    return 0;
}

Laajennusosamainen jakaminen

Kun käsittelijät rekisteröidään taulukkoon, uutta toimintaa voi lisätä liittämällä uuden alkion sen sijaan, että muokattaisiin suurta switch-rakennetta.

#include <stdio.h>

typedef void (*Handler)(int);
void log_low(int v){printf("low %d\n", v);}
void log_high(int v){printf("high %d\n", v);}

int main(void) {
    Handler handlers[] = { log_low, log_high };
    int level = 1;
    handlers[level](7);
    return 0;
}

Oletuskäsittelijä

Varatkaa tuntemattomille koodeille yksi paikka tai varaosoitin, jotta jakaminen ei epäonnistu huomaamatta.

#include <stdio.h>

typedef void (*Fn)(void);
void known(void){printf("known\n");}
void fallback(void){printf("unknown command\n");}

int main(void) {
    Fn table[] = { known };
    int n = 1, code = 9;
    Fn f = (code >= 0 && code < n) ? table[code] : fallback;
    f();
    return 0;
}

Miksi taulukot skaalautuvat

Jakotaulukot muuttavat haarautuvan logiikan tietohaoksi. Tapausten lisääminen tarkoittaa tietojen lisäämistä, mikä pitää koodin suoraviivaisena ja nopeana.

#include <stdio.h>

typedef int (*Fn)(int);
int a(int x){return x+1;}
int b(int x){return x*2;}
int c(int x){return x*x;}

int main(void) {
    Fn t[] = { a, b, c };
    for (int i = 0; i < 3; i++) printf("%d ", t[i](4));
    printf("\n");
    return 0;
}

Pikatesti

Testatkaa ymmärrystänne funktio-osoitintaulukoista.

Kertaus

Opitte funktio-osoitintaulukoihin perustuvia jakamismalleja:

  • Tallentakaa funktio-osoittimia taulukkoon ja valitkaa osoitin indeksin perusteella.
  • Ne korvaavat pitkät switch-ketjut ja skaalautuvat tietoja lisäämällä.
  • Käyttäkää typedef-määrettä ja rakenteisiin perustuvia komentotaulukoita selkeyden vuoksi.
  • Tarkistakaa aina indeksin rajat ja määrittäkää oletuskäsittelijä.
Aloita maksutta

Opi C tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
39
Oppitunnit
144

Usein kysytyt kysymykset

Onko oppitunti ”Funktio-osoitintaulukot” ilmainen?

Kyllä – oppitunnin ”Funktio-osoitintaulukot” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C Academy-kurssin, päivitä CoddyKit PROhon. C Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Funktio-osoitintaulukot”?

Välitysmallit. Harjoittelet C Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Funktio-osoitintaulukot”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C Academy-oppitunnilla?

Kyllä. Jokainen C Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Funktio-osoittimien määrittely
  2. Funktioiden välittäminen
  3. qsort vertailufunktioilla
  4. Funktio-osoitintaulukot
← Takaisin: C Academy