Ответ 1
Соответствующая часть спецификации POSIX printf()
определяет это поведение:
Конверсии могут применяться к аргументу n после формата в списке аргументов, а не к следующему неиспользуемому аргументу. В этом случае символ спецификатора преобразования% (см. Ниже) заменяется последовательностью "% n $", где n является десятичным целым в диапазоне [1, {NL_ARGMAX}], что дает положение аргумента в аргументе список. Эта функция обеспечивает определение строк формата, которые выбирают аргументы в порядке, соответствующем определенным языкам (см. Раздел ПРИМЕРЫ).
Формат может содержать либо спецификацию преобразования нумерованных аргументов (то есть "% n $" и "* m $" ), либо ненумерованные параметры преобразования аргументов (то есть% и *), но не оба. Единственным исключением из этого является то, что %% можно смешать с формой "% n $". Результаты смешивания нумерованных и ненумерованных параметров аргумента в строке формата undefined. При использовании спецификаций с нумерованными аргументами, для указания аргумента N th требуется, чтобы все ведущие аргументы от первого до (N-1) -го были указаны в строке формата.
В строках формата, содержащих форму преобразования "% n $", пронумерованные аргументы в списке аргументов можно указать из строки формата столько раз, сколько требуется.
%n$
идентифицирует аргумент, значение которого должно быть напечатано - аргумент 2 в вашем примере.
*n$
идентифицирует аргумент, значение которого должно рассматриваться как формат width - аргумент 1 в вашем примере.
Итак, те, кто писал руководство, следуют стандарту.
Вы утверждаете в комментарии:
2$*
должен соответствовать второму параметру, тогда как1$d
должен соответствовать первому, но оказывается, что это неверно в случаеprintf("%2$*1$d", width, num);
.
Как уже отмечалось, стандарт явно прикрепляет части n$
как модификаторы постфикса %
и *
, а не как модификаторы префикса спецификатора преобразования формата (d
в этом примере) и *
, Возможно, ваш предполагаемый дизайн можно было бы сработать, но дизайн не был выбран.