• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

nietypowe makro w c++

Fiszki IT
Fiszki IT
0 głosów
359 wizyt
pytanie zadane 13 października 2018 w C i C++ przez tomason Nowicjusz (140 p.)

dzień dobry,

mam otóż taki dylemat, jak napisać w C++ cóś takiego, żeby działało :)

#defiene MAKRO(nazwa[i],zmienna)  {nazwa##zmienna}
 cin>>zmienna1>>zmienna2>>zmienna3; //literowa np a b c

oczekiwany rezultat:

nazwa[i].a; // w kodzie programu gdzie a jest wartością (literą) wczytaną ze strumienia
nazwa[i].b;
nazwa[i].c;

nieoczekiwany rezultat:
 nazwa[i].zmienna;

czy w ogóle da się coś takiego zakodować używając makra # lub sklejacza ## czy lepiej zrobić 6 różnych funkcji dla poszczególnych przypadków

komentarz 13 października 2018 przez Criss Mędrzec (172,660 p.)

nazwa[i].a; // w kodzie programu gdzie a jest wartością (literą) wczytaną ze strumienia

Chwila. Co? Zrozumiałem, że chcesz wczytać runtime (w trakcie wykonania) co się pojawi w kodzie (do jakiego membera chcesz się dostać). Dobrze rozumiem?

komentarz 13 października 2018 przez tomason Nowicjusz (140 p.)
pytam się czy aby takie zamienienie jest w ogóle możliwe? Jeśli tak, to jak coś takiego napisać, np.: przy użyciu makra i symboli ## lub # - wyższa szkoła jazdy

 ewentualnie problem można rozbić na kilka przypadków (korzystając np. z if 'ów) i tworząc kolejne byty (funkcje)
komentarz 13 października 2018 przez Criss Mędrzec (172,660 p.)
#define MACRO(var,mem) var.mem

MACRO(nazwa[i], a); // evaluates to: nazwa[i].a;

Takie coś wystarczy jeśli o to ci chodziło.

komentarz 13 października 2018 przez tomason Nowicjusz (140 p.)
powinno wyjść cóś takiego

MACRO(nazwa[i], kr1); // evaluates to: nazwa[i].a;

gdzie wartosc kr1 jest wczytywana za strumienia (cin). albo inaczej

mam strukture składającą się z 4 pól, jak posortować tablice względem wybranych 3 pól, ale kolejność sortowania wg pól będzie podana w trakcie wczytywania danych

robić kilka przypadków if'ami czy da się jakoś ujednolicić kod

komentarz 14 października 2018 przez Criss Mędrzec (172,660 p.)

No nie możesz runtime podać fragmentów kodu XD

Jeśli te interesujące cie pola są tego samego typu, to możesz skorzystać z `offsetof` i rozwiązać problem bez ifów (jeśli tak jest, to daj znać i ci rozwine jak to zrobić). Jeśli nie są tego samego typu, to bez ifów się nie obejdzie przynajmniej jeśli nie przebudujesz swojego programu.

edit:

Jeśli te interesujące cie pola są tego samego typu, to możesz skorzystać z `offsetof` i rozwiązać problem bez ifów (jeśli tak jest, to daj znać i ci rozwine jak to zrobić).

Rozwiązanie o którym myślałem zaprezentował już mokrowski w odpowiedziach. 

1 odpowiedź

0 głosów
odpowiedź 14 października 2018 przez mokrowski VIP (145,460 p.)
edycja 14 października 2018 przez mokrowski

Wiesz co, pewnie że się da. Ale ani to ładne ani bezpieczne. Myślę że sensowniej przemyśleć sprawę. Tu masz ideowo zaimplementowane. Nie będę silił się na poprawność. Osobiście jeśli przy takim problemie mam robić reinterpret_cast na poziomie logiki, to najczęściej oznacza nieprzemyślany problem. Ale ok... :

#include <iostream>
#include <cassert>
#include <cstddef>
#include <algorithm>

struct Data {
    int a;
    int b;
    int c;
    int d;
};

int main() {
    Data table[] = { {1, 2, 3, 4}, {10, 5, 1, 2}, {12, 3, 4, 3} };
    std::size_t offsets[] = { offsetof(Data, a), offsetof(Data, b), offsetof(Data, c), offsetof(Data, d) };
    char l;
    std::cout << "Podaj nazwę pola wg. którego sortować w postaci litery [a-d]: ";
    std::cin >> l;
    assert(l >= 'a' && l <= 'd');
    std::size_t offset = offsets[l - 'a'];
    std::sort(std::begin(table), std::end(table), [offset](Data d1, Data d2) {
        return static_cast<int>(*(reinterpret_cast<char *>(&d1) + offset))
            < static_cast<int>(*(reinterpret_cast<char *>(&d2) + offset));
    });

    for (auto v: table) {
        std::cout << "a = " << v.a << " b = " << v.b << " c = " << v.c
            << " d = " << v.d << '\n';
    }
}

PS. Jeśli typy dla pól w strukturze były by różne, także się da ale kod byłby jeszcze bardziej usiany dziwnymi rzutowaniami (i było by przejście przez void * co już samo z siebie w C++ na poziomie logiki powinno powodować uruchomienie alarmu we wszystkich samochodach w promieniu 3 km):)

Podobne pytania

0 głosów
0 odpowiedzi 44 wizyt
pytanie zadane 26 listopada 2020 w Visual Basic przez ZenekMarjewka Nowicjusz (120 p.)
+1 głos
1 odpowiedź 81 wizyt
pytanie zadane 25 września 2020 w Visual Basic przez doeg Początkujący (430 p.)
0 głosów
0 odpowiedzi 78 wizyt
pytanie zadane 5 stycznia 2019 w Inne języki przez Dominik Jóźwiakowski Nowicjusz (120 p.)
Porady nie od parady
Nie wiesz jak poprawnie zredagować pytanie lub pragniesz poznać którąś z funkcji forum? Odwiedź podstronę Pomoc (FAQ) dostępną w menu pod ikoną apteczki.FAQ

84,742 zapytań

133,547 odpowiedzi

295,964 komentarzy

56,006 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...