主要利用可变参数相关宏:
...: 定义函数可接受不定个数参数(只能出现在参数末尾)
va_list: 声明 va_list 变量
va_start: 初始化刚才声明的 va_list 变量
va_arg: 获取 va_list 中下一个变量
va_end: 清理 va_list
参考: 《C Primer Plus》

简单代码如下:
printf.c:

#include <stdio.h>
#include <stdarg.h>
#include <string.h>

int pf(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);

    int i = 0;
    int length = strlen(fmt);
    char placeholder;

    while(i < length) {
        if (fmt[i] == '%') {
            placeholder = fmt[++i];

            switch(placeholder) {
                case 'd': {
                    int var_d = va_arg(ap, int);
                    printf("%d", var_d);
                    break;
                }
                case 's': {
                    char *var_s = va_arg(ap, char*);
                    printf("%s", var_s);
                    break;
                }
                case 'c': {
                    int var_c = va_arg(ap, int);
                    putchar(var_c);
                    break;
                }
            }
        }
        else {
            putchar(fmt[i]);
        }

        ++i;
    }

    va_end(ap);

    return 0;
}

int main(int argc, char const *argv[]) {
    pf("%c%s\n", 'z', "ssss");
    return 0;
}

makefile:

make:
    @gcc printf.c -o printf
    @chmod 777 printf
    @./printf

run:
    @./printf
2018-01-25 22:37103