Важность «&» при обращении значения к определенной переменной? - PullRequest
0 голосов
/ 13 января 2019

Мой учитель сказал нам использовать «&» для сохранения значений в желаемых нами переменных, однако я попытался использовать scanf () и попытался сохранить значения для некоторых переменных без «&», и я заметил, что это все еще работает просто отлично? Влияет ли это на мой код, несмотря на то, что я думаю, что это не так?

Вот коды, которые я пробовал. Код является частью для проверки того, является ли второй вход подстрокой. Оригинальная форма, которую преподает мой учитель:

int main(){
    char word1[100], word2[100];
    int length1, length2;

    printf("Enter the a word: \n");
    scanf("%s", &word1);
    printf("Enter the potetial substring: \n");
    scanf("%s", &word2);

    for(length1=0; word1[length1]!='\0'; length1++);
    for(length2=0; word2[length2]!='\0'; length2++);

    if (length1<length2)
    {
        printf("Second input is not a substring.\n");
    }

Затем я настроил часть, где программа запрашивает входные данные для этого:

printf("Enter the a word: \n");
scanf("%s", word1);
printf("Enter the potetial substring: \n");
scanf("%s", word2);

Я все еще получил тот же вывод, даже если я удалил "&". Надеюсь, кто-то может объяснить, влияет ли это изменение на мои коды каким-то образом, о котором я могу не знать, спасибо.

Ответы [ 5 ]

0 голосов
/ 13 января 2019

Знак & используется для ссылки на указатель. Представим, что у вас есть следующая переменная:

int i = 1234;

Если вы хотите получить значение переменной i, просто введите имя переменной i:

int j = i * 2;

Но иногда вы не хотите получать значение, но вы хотите получить ссылку. С помощью ссылки вы можете позже изменить значение этой переменной. Таким образом, вам понадобится указатель (адрес переменной). Поэтому используется знак &:

int* ptrToI = &i;

Теперь вы можете задерживать переменную (для изменения значения) с помощью знака *:

*ptrToI = 5678;

Если бы вы сейчас проверили значение переменной i, вы получили бы значение 5678, потому что переменная i была изменена, и указатель ptrToI.

Причина, по которой ваш код работает со знаком &, заключается в том, что word1 и word2 являются массивами. И массивы всегда передаются как ссылки. Для простого теста вы могли бы следующее:

char word1[100];
printf("%08X\r\n", word1);
printf("%08X", &word1);

printf должен выводить адрес переменной word1. Но, как вы можете видеть, два выхода одинаковы. Вот почему ваш scanf звонок работает со знаком & и без него.

0 голосов
/ 13 января 2019

В частности, при использовании scanf для чтения строки в char [N] (или char *) нельзя использовать &.

Таким образом, правильный путь:

char word1[100]
scanf("%s", word1);

Если ваш учитель говорит, что вам нужно & в этом случае, они ошибаются.


%s ожидает аргумент типа char *.

Когда вы передаете ему массив char (char [N]) без использования &, он неявно преобразуется в указатель на свой первый элемент - char *.

Но если вы используете &, вы в конечном итоге передаете char (*)[N] (указатель на массив char размером N).
Это меняет тип указателя, но не его числовое значение 1032 *. Из-за этого добавление & обычно не имеет никакого эффекта в этом случае. Но формально, поскольку тип аргумента неверен, поведение не зависит.

0 голосов
/ 13 января 2019

scanf необходимо знать место в памяти, куда поместить считанное и, возможно, преобразованное значение.

Для элементарного типа, такого как int, double, char, это означает передачу ему адреса переменной.

Это также верно для массива символов, однако компилятор по умолчанию использует адрес первого элемента массива при передаче имени массива. Итак:

int i;
char word[100];

scanf("%d", &i);
scanf("%s", word);
0 голосов
/ 13 января 2019

Массивы C выражаются в контексте оценки (например, ваш аргумент передается в scanf) как указатель на тип, где тип является базовым типом элемента массива. Поэтому word выражается как char*. Результатом адреса является результат первого элемента.

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

Ваш компилятор должен был выдвинуть предупреждение о том, что ожидаемый тип аргумента был char*, а вы даете char(*)[100]. Если это не так, включите ваши предупреждения.

Резюме; Правильный синтаксис для %s - передать char*. В этом случае это получается word1 (промыть / повторить для word2). Он может работать с использованием оператора адресации, но нет причин использовать его в этом контексте, и нет причин для этого.

0 голосов
/ 13 января 2019

Если вы перейдете на страницу Википедии для сканирования, вы можете прочитать:

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

https://en.m.wikipedia.org/wiki/Scanf_format_string

Я не знаю, из какой вы страны, но стараюсь всегда смотреть на Википедию как на родном языке, так и на английском. Часто на английских страницах больше информации (но не всегда)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...