Макроси в C
Макросите могат да се извикват един друг и за разлика от функциите, макросът може да извиква макрос, който е описан след него. Но макросите не са приятели на рекурсията - нито директна, нито индиректна.Превеждане на име на променлива в низМожете да получите името на променливата като низ.Пример 6.#define id(x) #x Тук говорих малко за това. Единственото, което мога да кажа е, че е наистина вълшебно.Свързване на низ към име на променлива. Нека да преминем направо към примера.Пример 7.#define get(name) (get_##name()) Много полезно в един и същ ООП, когато има много методи за получаване. Въпреки че по същество животът е наред и без него. В C++ има многостандартни макроси. Не мисля, че си заслужава да му се обръща твърде много внимание. Който иска - чете тук.Предефиниранеиизтриване на макроси. Предефинирането се извършва чрез ново извикване на директивата #define name, където name е името на вече използвания макрос. Макросът може да бъде предефиниран до нормален или функционален макрос, независимо от това какъв е бил преди. Изтриването на макрос се използва с директивата за име #undef, където name е името на макроса.Пример 8.#define func 2 е нормален макрос, който връща 2 #undef func вече е редовно име на променлива #define func 5 отново е нормален макрос #define func(x) ((x)+5) се предефинира към функция нейното време за използване.Пример 9.
Такъв код тихо ще върне 6. Компилаторът ще мълчи.Различни макроси.Принципът на работа е приблизително същият като при функции и/или шаблони с променлив брой аргументи. Примери тук. От себе си, за съжаление, няма да добавя нищо.Предупреждение 2.Нежелателно е макро аргументите да се предават на функцията. По-добре е да преминете резултата му. Защото, ако тази променлива се използва повече от веднъж в макроса, тогава функцията ще бъде извикана много пъти.Пример 10.Нека си припомним макроса max и се опитаме да изпълним следния код max(x, func(y)). Този код след окончателната замяна ще изглежда така: ((x)>(func(y))?(x):(func(y)) .Както можете да видите, func(y) се извиква два пъти.В най-лошия случай това може значително да повлияе на времето за изпълнение.Linefeedв макроса.Ако трябва да запишете макрос на няколко реда, можете да използвате linefeed \ .Мисля, че това може да се направи без пример .Борба с нежелана точка и запетая.Пример 11.Да кажем, че имаме този код:
Този код открива колко цифри има в x и записва резултата в y (между другото, в този пример скобите не са необходими, защото ако изпратим непроменлива към този макрос, кодът няма да се компилира). След това, ако го вмъкнете преди else, компилаторът ще се оплаче от синтактична грешка. Този проблем се решава по следния начин:
И сега винаги можете да поставите точка и запетая след него.И още няколко примера.Пример 12.#define forn(i,a,b) for(int i = (a); i Най-честият макрос, за опростяване на цикъла при писане.Пример 13.#define sum(a,b) ( (a)+(b)) Безполезен, но готин макрос за намиране на оператора + на две променливи. Сума за числа, конкатенация за низове и т.н.Надявам сетози запис да ви бъде полезен.UPD.Предупреждение 3.Благодаря на hellman1908 за примера с нарастване. Дори скобите не винаги могат да запазят всичко.S o можете или да следвате всички променливи, или по-реална опция е да използвате този или подобен макрос: #define max(a,b) ((___x = (a)) > (___y = (b)) ? x : y) Но тогава променливите ___x и ___y ще трябва да бъдат описани веднага. И тогава излизат проблеми, защото ___x и ___y имаме статистически тип и т.н. Следователно не знам пълноценна опция с помощта на макрос. Но в повечето случаи първият работи много добре. Мога да посъветвам просто да не хвърляте никакви изрази там.