2014-11-25 11 views
5

Mam funkcję, która zwraca wartość całkowitą. Teraz chcę napisać makro, które wywołuje tę funkcję, pobiera wartość zwracaną i dodaje do niej ciąg znaków i zwraca wynikowy ciąg znaków.Makro w C wywołanie funkcji zwracającej liczbę całkowitą, a następnie zwrócenie ciągu znaków

Próbowałem to:

#define TEST(x)  is_enabled(x) 

nazywam tego makra w głównej funkcji jak:

int ret = 0; 
ret = TEST(2); 
printf("PORT-%d\n", ret); 

Działa to doskonale. Jednak chcę, aby makro zwróciło ciąg PORT-x, gdzie x jest zwracaną wartością wywołanej funkcji. Jak mogę to zrobić?

EDIT:

Próbowałem też pisząc go na wiele linii jak:

#define TEST(x)\ 
{\ 
    is_enabled(x);\ 
} 

i nazwał go w głównej funkcji jak:

printf("PORT-%d\n", TEST(2)); 

Ale to daje kompilacji błąd czasu:

error: expected expression before â{â token 
+0

Można to zrobić, pisząc makro, które "wywołuje" 'sprintf', ale musisz przydzielić bufor i przekazać go do tego makra. Pytanie brzmi: dlaczego chcesz to zacząć? Ponieważ czujesz, że próbujesz rozwiązać coś w niewłaściwy sposób. –

+0

Dlaczego nie możesz użyć 'strcat'? Dlaczego wymagane jest makro? – Gopi

+0

Powinieneś zdecydowanie napisać funkcję dla tego ... – Antzi

Odpowiedz

5

Użyj funkcji, a nie makra. Nie ma żadnego powodu, aby używać makro tutaj.

Można go rozwiązać, używając sprintf(3), w połączeniu z malloc lub buforem. Szczegółowe informacje można znaleźć na stronie Creating C formatted strings (not printing them) lub na stronach podręcznika systemowego.

O swojej EDIT: Nie trzeba używać nawiasów {} w makro, a one są przyczyną błędu jak przerób by przełożyć je na coś jak

printf("format%d", { 
    is_enabled(x); 
}); 

Aby lepiej zrozumieć makra, należy uruchomić gcc lub clang z flagą -E lub spróbuj przeczytać ten artykuł: http://en.wikipedia.org/wiki/C_preprocessor

+0

Wreszcie, zaimplementowałem to w funkcji, zamiast pisać makro. – iqstatic

2

To trochę uciążliwe, ponieważ musisz się upewnić, że jest miejsce na ciąg znaków. Szczerze mówiąc, makra mogą być obecnie zarezerwowane tylko do kompilacji warunkowej.

Stałe są lepiej zrobione z wymienionych typów i funkcji makro są na ogół lepiej jako funkcje inline (ze świadomością, że inline jest sugestia do kompilatora, a nie popytu).

Jeśli nalegasz na użycie makra, pamięć może być przechowywana w pamięci statycznej, ale ma problemy z wątkami, jeśli używasz ich, oraz opóźnione/wielokrotne użycie zwróconego ciągu.

Można również dynamicznie przydzielić ciąg znaków, ale trzeba go zwolnić po zakończeniu pracy i obsługiwać warunki braku pamięci.

Może najprostszy sposobem jest żądać makro użytkownik dostarczyć swój własny magazyn, wzdłuż linii:

#include <stdio.h> 

#define TEST2_STR(b,p) (sprintf(b,"PORT-%d",p),b) 

int main (void) { 
    char buff[20]; 
    puts (TEST2_STR(buff, 42)); 

    return 0; 
} 

które wyjścia:

PORT-42 

W przypadku makro wydaje się mało mylące, korzysta z operatora przecinka, w którym wyrażenie (a, b) ocenia zarówno a i b i ma wynik b.

W tym przypadku ocenia on sprintf (który zapełnia bufor), a następnie "zwraca" bufor. I nawet jeśli myślisz ty nigdy nie widziałem czegoś takiego, jesteś prawdopodobnie źle:

for (i = 0, j = 9; i < 10; i++, j--) 
    xyzzy[i] = plugh[j]; 

Chociaż większość ludzi myśli, że to cecha for, to bardzo dużo inny konstrukt, który może być używany w wiele różnych miejsc:

int i, j, k; 
i = 7, j = 4, k = 42; 

while (puts("Hello, world"),sleep(1),1); 

(i tak dalej).

Powiązane problemy