Когда делают я должен вставить/, вставляют &
для scanf()
в C?Спасибо.
int main()
{
char s1[81], s2[81], s3[81];
scanf("%s%s%s", s1, s2, s3);
// If replace scanf() with the expression below, it works too.
// scanf("%s%s%s", &s1, &s2, &s3);
printf("\ns1 = %s\ns2 = %s\ns3 = %s", s1, s2, s3);
return 0;
}
//programming is fun
//
//s1 = programming
//s2 = is
//s3 = fun
scanf помещает отсканированные значения в адрес, на который указывают его аргументы. & - это оператор адреса, и он используется для получения адреса переменной.
Но вы используете массивы, а массивы понижаются до указателей, когда используются в качестве аргументов функций. Поэтому в случае с массивами оператор & использовать не нужно.
Пример:
char s[81];
int n;
int* nptr;
//Initialize nptr to some meaningful value
scanf("%s %d %d",s,&n,nptr);
В данном случае нам нужно использовать оператор &, чтобы получить адрес, по которому хранится n. Нам не нужно использовать его с nptr, потому что он уже является указателем на какое-то место в памяти, ни с s, потому что массив понижается до указателя, когда он передается в функцию.
Если a
является массивом, оба a
и и
приводят к указателю в этом контексте:
a
делает из-за массив, распадающийся на указатель (C99, §6.3.2.1 / 3 ):
За исключением случаев, когда это операнд оператора sizeof или унарный оператор & , или используется строковый литерал для инициализации массива выражение с типом «массив типа» преобразуется в выражение с типом «указатель на тип», которое указывает на начальный элемент объекта массива и не является lvalue.
... курсив добавлен
& a
делает это в результате оператора &
- он возвращает указатель на объект.
Аргументы после спецификатора формата должны быть указателями. . Когда имя массива передается функции, передается местоположение начального элемента , поэтому вам вообще не нужно использовать и
в вашем примере. Однако вы можете сделать это (из K&R ):
int day, year;
char monthname[20];
scanf("%d %s %d", &day, monthname, &year);
Поскольку день и год равны int
, вы должны использовать &
, чтобы получить адрес этих переменных. Поскольку monthname
является массивом, никаких &
не требуется.
Из часто задаваемых вопросов о comp.lang.c: Я думал, что вам всегда нужны &
для каждой переменной, передаваемой в scanf
.
Я настоятельно рекомендую прочитать оставшуюся часть FAQ по comp.lang.c .
В Си, когда вы имеете дело с массивами:
int c_array[24];
c_array == &c_array == &c_array[0]
Да, забавно - они выглядят одинаково (разница в типах). Прочитайте это.
s1
возвращает адрес первого элемента массива, а & s1
возвращает адрес самого массива. Адрес первого элемента и адрес самого массива идентичны, поэтому оба представления работают.
Scanf принимает переменное количество параметров. Первый аргумент scanf - это формат, а затем n адресов, где значения должны быть сохранены, а n - это номер формата, указанный в строке формата. поскольку вы используете массив, для хранения значений вам необходимо указать базовый адрес массива.
//If int int i; scanf("%d",&i); // store int value at address &i float f; scanf("%f",&f); //store float value at address &f int a[10]; scanf("%s",a); //store string or array value at a
если использование a в последней строке вас смущает, вы можете попробовать то же самое с адресом первого элемента, которым является & a [0].
Надеюсь, это поможет,
GG
Просто предположение, но я предполагаю, что это потому, что s1
, s2
и s3
являются массивами .
Вообще, вы должны использовать scanf так, как это сделано в вашей некомментированной строке. Массивы в Си работают так, что имя массивов, таких как s1, s2 и s3, на самом деле является адресом первого элемента массива. Однако для любых примитивов вам придется использовать синтаксис &variable. Например:
float f;
scanf("%f", &f);