Препроцессоры "глупые" и пихают весь код из подключенных заголовочных файлов, или только тот, что нужен программе после вставляет компоновщик?
Да.
Т.е. препроцессоры глупые и пихают весь код из подключенных заголовочных файлов. Но дело в том, что в заголовочных файлах C кода как такового почти нет. Обычно там определения типов и объявления функций. Определения функций скомпилированы и находятся в библиотеках. И компоновщик достаёт из библиотек и линкует только те функции, которые реально используются.
P.S. Т.е. если перефразировать вопрос, то он бы звучал так: можно ли выборочно подключать только необходимые функции из подключаемых библиотек?
Это происходит по умолчанию.
Если первой строчкой кода записать #include <stdio.h>
Загляни ради интереса в stdio.h и попробуй найти там определение (не объявление) функции printf.