И макросы используются для простых замен, когда нужно, например, вставить кусок кода в нескольких местах, но на функцию он не тянет. Именно так их и нужно рассматривать - в качестве автоматизированной вставки, не более.
Это какой-то быдлокод.
Либо пиши на C, используя scanf() и printf() для ввода/вывода, либо пиши на C++, используя cin и cout для ввода/вывода.
А вперемешку нельзя.
Там в 8-ой главе описывается принцип работы функций выделения памяти, а потом ещё пишешь свой менеджер памяти.
Память представлена связным списком блоков, от которых нарезаются кусочки при выделении и которые склеиваются в большие блоки при высвобождении. (Есть и другие менеджеры памяти типа питоновского.)
*w++ работает так же, как *(w++) .
Сначала происходит инкремент указателя, операция пост-инкремента возвращает значение операнда до инкремента, а затем это значение разыменовывается и результат присваивается переменной n.
После этого в n находится 5, а указатель w указывает за край массива.