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

nietypowe makro w c++

VPS Starter Arubacloud
0 głosów
920 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,590 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,590 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,590 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 Mędrzec (155,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

+1 głos
1 odpowiedź 312 wizyt
pytanie zadane 16 stycznia 2022 w SQL, bazy danych przez danehcan Obywatel (1,170 p.)
+1 głos
1 odpowiedź 188 wizyt
pytanie zadane 27 września 2021 w Algorytmy przez msth32 Nowicjusz (130 p.)
0 głosów
0 odpowiedzi 199 wizyt
pytanie zadane 26 listopada 2020 w Visual Basic przez ZenekMarjewka Nowicjusz (120 p.)

92,452 zapytań

141,262 odpowiedzi

319,078 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...