podstawy języka - makra i definicje

podstawy języka - makra i definicje
Adamos19
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 293
0

Witam

Dlaczego tak zdefiniowane definicje:

Kopiuj
#define SPI_PORT (B)
#define SPI_SCK (PB5)
#define SPI_SCK_OUT (DDR##SPI_PORT |= (1 << SPI_SCK))

wołane tak:

Kopiuj
SPI_SCK_OUT;

nie rozwijają się do:

Kopiuj
DDRB |= (1 << PB5);

?

Oraz dlaczego taki kod:

Kopiuj
#define SPI_PORT (B)
#define SPI_SCK (PB5)
#define DDR(x) (SDDR(x))
#define SDDR(x) (DDR##x)
#define SPI_SCK_OUT (DDR(SPI_PORT) |= (1 << SPI_SCK))

wołane tak:

Kopiuj
SPI_SCK_OUT;

nie rozwija się do tego samego co poprzednio?
Dodam tylko że w tym ostatnim przypadku wyskakuje błąd : "lvalue required as left operand of assignment"...

Pomożecie?

KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 192
0

Bo powinny być zadeklarowane chyba tak:

Kopiuj
#define SPI_SCK_OUT(port,sck)  DDR##port |= (1 << (sck))

Wtedy używasz tego tak:

Kopiuj
SPI_SCK_OUT(B,PB5);
Adamos19
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 293
0

To wiem, ale nie bardzo podoba mi się tworzyć z tego makro.
Może postawię pytanie inaczej:

Dlaczego preprocesor mając taką definicję:

Kopiuj
#define X (B)

i instrukcję:

Kopiuj
DDR(X) |= (1 << 1);

nie rozwija tego do:

Kopiuj
DDRB |= (1 << 1);

tylko do:

Kopiuj
DDRX |= (1 << 1);

Jak zmusić preprocesor do wywołania makra z argumentem podmienianym na etapie preprocesingu definicją?

KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 192
0

No nie do końca, rozwija to raczej tak:

Kopiuj
DDR((B)) |= 1;

Doczytaj jak działa preprocesor.

Sparrow-hawk
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Katowice
  • Postów: 189
1

Działanie preprocesora możesz przetestować używając np. -E w gcc.

Twój ostatni kod u mnie rozwijany jest do:

Kopiuj
DDR((B)) |= (1 << 1)
several
  • Rejestracja: dni
  • Ostatnio: dni
2

Jeżeli jesteś początkującym i zaczynasz od makr, zmień książkę/kurs. Dalsza część na temat.

Adamos19 napisał(a):

Witam

Dlaczego tak zdefiniowane definicje:

Kopiuj
#define SPI_PORT (B)
#define SPI_SCK (PB5)
#define SPI_SCK_OUT (DDR##SPI_PORT |= (1 << SPI_SCK))

wołane tak:

Kopiuj
SPI_SCK_OUT;

nie rozwijają się do:

Kopiuj
DDRB |= (1 << PB5);

?

Bo makra tak nie działają, bo tak naprawdę nic nie wołasz. Makro to po prostu zamiana jednego tekstu na drugi, jak zapiszesz nawiasy po prawej stronie to one też zostaną wklejone. Twoje przykładowe marko rozwinie się do (DDR(B) |= (1 << (PB5))); (to na oko, nie sprawdzałem kompilatorem). Usuń nawiasy to powinno rozwinąć się tak jak chcesz. Nawiasów używasz jeśli chcesz, żeby Twoje makro zachowywało się jak funkcja - przykład.

Doradzałbym jednak skasowanie tego kodu i rozwiązanie Twojego problemu inaczej, obecnie w C++ problemów do których makra są najlepszym rozwiązaniem jest bardzo mało, założę się o spodnie, że nie natknąłeś się na żaden z nich.
EDIT Nie zauważyłem, że temat jest otagowany jako C, a nie C++.

Adamos19
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 293
0

Dzięki za odpowiedzi. Poradziłem sobie już.
Zrobiłem tak:

Kopiuj
#define DDR(x) (SDDR(x))
#define SDDR(x) (DDR##x)
#define SPI_PORT B
#define SPI_SCK (PB5)
#define SPI_PIN_OUT(x) (PIN_OUT(SPI_PORT, x))
#define PIN_OUT(x, y)  (DDR(x) |= (1 << y))

i piszę sobie potem tak:

Kopiuj
SPI_PIN_OUT(SPI_SCK);

Działa to tak jak chcę żeby działało.
W odpowiedzi do kolegi @several : nie, nie natknąłem się na żaden z tych problemów o których piszesz to racja, jednak nie piszę w C++ tylko w C na mikrokontrolery.
Potrzebuję takich cyrków do tego żeby mi się ładnie sam komentował kod. Nie jestem jakimś urodzonym programistą ale pragnę aby mój kod wyglądał dokładnie tak jak wygląda teraz.
Także dzięki za pomoc. Pozdrawiam.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.