scanf () (язык C) смутил меня

Когда делают я должен вставить/, вставляют & для 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
6
задан Nano HE 17 June 2010 в 01:41
поделиться

9 ответов

scanf помещает отсканированные значения в адрес, на который указывают его аргументы. & - это оператор адреса, и он используется для получения адреса переменной.

Но вы используете массивы, а массивы понижаются до указателей, когда используются в качестве аргументов функций. Поэтому в случае с массивами оператор & использовать не нужно.

Пример:

char s[81];
int n;
int* nptr;
//Initialize nptr to some meaningful value
scanf("%s %d %d",s,&n,nptr);

В данном случае нам нужно использовать оператор &, чтобы получить адрес, по которому хранится n. Нам не нужно использовать его с nptr, потому что он уже является указателем на какое-то место в памяти, ни с s, потому что массив понижается до указателя, когда он передается в функцию.

9
ответ дан 8 December 2019 в 03:52
поделиться

Если a является массивом, оба a и и приводят к указателю в этом контексте:

  • a делает из-за массив, распадающийся на указатель (C99, §6.3.2.1 / 3 ):

    За исключением случаев, когда это операнд оператора sizeof или унарный оператор & , или используется строковый литерал для инициализации массива выражение с типом «массив типа» преобразуется в выражение с типом «указатель на тип», которое указывает на начальный элемент объекта массива и не является lvalue.

    ... курсив добавлен

  • & a делает это в результате оператора & - он возвращает указатель на объект.

1
ответ дан 8 December 2019 в 03:52
поделиться

Аргументы после спецификатора формата должны быть указателями. . Когда имя массива передается функции, передается местоположение начального элемента , поэтому вам вообще не нужно использовать и в вашем примере. Однако вы можете сделать это (из K&R ):

int day, year;
char monthname[20];

scanf("%d %s %d", &day, monthname, &year);

Поскольку день и год равны int , вы должны использовать & , чтобы получить адрес этих переменных. Поскольку monthname является массивом, никаких & не требуется.

6
ответ дан 8 December 2019 в 03:52
поделиться

Из часто задаваемых вопросов о comp.lang.c: Я думал, что вам всегда нужны & для каждой переменной, передаваемой в scanf .

Я настоятельно рекомендую прочитать оставшуюся часть FAQ по comp.lang.c .

3
ответ дан 8 December 2019 в 03:52
поделиться

В Си, когда вы имеете дело с массивами:

int c_array[24];
c_array == &c_array == &c_array[0]

Да, забавно - они выглядят одинаково (разница в типах). Прочитайте это.

4
ответ дан 8 December 2019 в 03:52
поделиться

s1 возвращает адрес первого элемента массива, а & s1 возвращает адрес самого массива. Адрес первого элемента и адрес самого массива идентичны, поэтому оба представления работают.

2
ответ дан 8 December 2019 в 03:52
поделиться

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

1
ответ дан 8 December 2019 в 03:52
поделиться

Просто предположение, но я предполагаю, что это потому, что s1 , s2 и s3 являются массивами .

1
ответ дан 8 December 2019 в 03:52
поделиться

Вообще, вы должны использовать scanf так, как это сделано в вашей некомментированной строке. Массивы в Си работают так, что имя массивов, таких как s1, s2 и s3, на самом деле является адресом первого элемента массива. Однако для любых примитивов вам придется использовать синтаксис &variable. Например:

float f;
scanf("%f", &f);
0
ответ дан 8 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: