Использование оператора амперсанда в Scanf - PullRequest
0 голосов
/ 09 июля 2019

При использовании scanf для массивов кажется, что функция работает нормально, независимо от того, использую я оператор '&' или нет. Я хочу знать, как компилятор видит оператор '&' в случае массивов символов

Я уже знаю, что scanf передает указатель, когда используется один символ. В случае массивов переменная сама хранит указатель на первый элемент. Мой точный вопрос: когда я использую &ch (в то время как ch это строка) мы создаем двойной указатель? А как работает компилятор то

int main() 
{
    char ch,s[100],sen[100];
    scanf("%c",&ch);
    scanf("%s",s);
    scanf(" %[^\n]%*c",sen);

}

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

При использовании scanf для массивов кажется, что функция работает нормально, использую оператор '&' или нет.

«Кажется», являясь рабочим словом.

За исключением случаев, когда оно является операндом операторов sizeof или унарных & или является строковым литералом, используемым для инициализациимассив символов в объявлении, выражение типа "массив N-элементов T будет преобразован (" распад ") в выражение типа" указатель на T "и значениевыражение будет адресом первого элемента массива.

Если вы вызываете scanf как

scanf( "%s", s );

, выражение s преобразуется извведите «100-элементный массив из char» (char [100]) в «указатель на char» (char *), и его значением является адрес первого элемента массива (&s[0]).

Если вы называете scanf как

scanf( “%s”, &s );

*, 1033 * является операндом унарного &, поэтому преобразование не происходит, и выражение &s имеет тип "указатель на массив из 100 элементов char" (char (*)[100]). Это проблема, поскольку спецификатор преобразования %s ожидает аргумент типа char *.Передача аргумента любого другого типа приводит к неопределенному поведению - операция может работать как ожидалось, или она может аварийно завершиться, или она может повредить данные, или она может оставить программу в плохом состоянии, так что онапозже происходит сбой и т. д.

Оба выражения s и &s разрешаются в одно и то же значение - адрес массива совпадает с адресом его первого элемента - но их типы различны, и в C разные типы указателей могут иметь разные представления (IOW, способ хранения значения адреса для char * может отличаться от способа хранения значения адреса для char (*)[100]).Так что

scanf( "%s", &s );

может произойти сбой на некоторых платформах.

Мой точный вопрос: когда я использую & ch (пока ch - строка), мы создаем двойной указатель?

Нет.Если ch объявлено как char ch, то &ch имеет тип char *.Если ch объявлено как char ch[N], то &ch имеет тип char (*)[N].

0 голосов
/ 09 июля 2019

Ключевое слово в этом случае - array decay.Компилятор автоматически преобразует массив в указатель на первый элемент этого массива.

В вашем случае вы должны передать указатель на scanf.В первой строке вы передаете адрес ch через оператора &.Вы также можете написать &Array[0], чтобы указать на первый элемент вашего массива, или вы напишите Array, и компилятор автоматически разрешит его в &Array[0].

int main()
{
    char Array[1];

    scanf("%c", Array);

    printf("%p\n\r", &Array[0]);
    printf("%p\n\r", Array);

    return 0;
}

Оба аргумента имеют один и тот же адрес.Так, в случае scanf вы используете оператор &, если хотите получить одно целое число или один символ с клавиатуры:

int value;
scanf("%d", &value);

Если вы хотите получить массив символов, вы передаетемассив без оператора &, и пусть компилятор сделает всю работу за вас.

char Array[20];
scanf("%s", Array);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...