Когда вы используете спецификатор формата %s
, он ожидает значение, которое является указателем на начало строки. В Си этот тип char *
.
Используя вашу main
функцию, ваша переменная s1
имеет тип char *
. Следовательно, s1
является допустимым параметром для printf
, поэтому эта строка действительна:
printf("%s\n", s1);
Обратите внимание на отсутствие &
перед s1
. В вашем коде вы использовали &
, который принимает адрес s1
, результат которого будет иметь тип char **
. Это неправильный тип, поэтому не используйте &
.
Дело в том, что printf
на самом деле не может сказать, к какому типу относятся его аргументы, поскольку это функция с переменным числом. Он просто использует все имеющиеся аргументы в соответствии с типами, указанными в строке формата.
То же самое относится и к scanf
, но есть подводный камень: вы должны убедиться, что выделено достаточно памяти для учета ввода пользователя, иначе вы столкнетесь с переполнением буфера с непредсказуемыми результатами. Помимо этого, printf
и scanf
идеально дополняют друг друга.
В любом случае, это заботится о предупреждениях компилятора, кроме неиспользуемой переменной cmds
(в предоставленном коде это не нужно). Также есть часть args
- это действительно должна быть переменная, объявленная внутри shell
, и не передаваемая как параметр, поскольку ее значение даже не используется внутри shell
.
Не знаю, что случилось с остальным кодом. Это излишне, учитывая, что ваша main
функция вызывает только на shell
.