c В то время как цикл обрабатывает локальную переменную в цикле как глобальную, почему? - PullRequest
0 голосов
/ 22 февраля 2012

ниже - небольшое приложение C.Он попросит вас ввести слово.Он перестает спрашивать, когда достиг четырех уникальных слов.Но в показанной ниже форме он не будет работать должным образом, пока вы не раскомментируете соответствующие строки.

#include <stdio.h>
#include <string.h>

#define WORDS_COUNT 4

int main()
{
    char* words[WORDS_COUNT];

    int words_added = 0;
    while (words_added<WORDS_COUNT)
    {

        puts ("\n-------enter a word-------");

        char response[250];

        scanf("%s", response);

        int i;
        int duplicate_flag = 0;
        for (i=0; i < words_added; i++)
        {
            if (strcmp(words[i], response) == 0)
            {
                duplicate_flag = 1;
                break;
            };
        };

        if (duplicate_flag == 0)
        {
            //char tmp[250];
            //strcpy(tmp, response);
            words[words_added] = response; //words[words_added] = tmp;
            puts("that's new!");
            words_added ++;
        } else {
            puts("you've said that already...");
        };

    };
    return 0;
};

Основное различие, как вы можете видеть, находится между words[words_added] = response и words[words_added] = tmp.

Почему переменная tmp будет работать, а не response?

Я предполагаю, что response будет иметь одинаковый адрес на каждой итерации, а tmp будет получать новый адрес на каждой итерации,но почему?тем не менее они оба были объявлены в одном и том же цикле while ???

Ответы [ 2 ]

2 голосов
/ 22 февраля 2012

Когда вы присваиваете words[words_added] = response, вы копируете адрес (не содержимое) response в массив. Таким образом, в исходном виде ваш код должен видеть второе слово и каждое последующее слово как дубликаты. Когда вы используете tmp, код сравнивает каждый новый response с предыдущим tmp, который был сохранен в (каждом месте) words[], а затем копирует его в tmp, если он не является дубликатом.

Поэтому я подозреваю, что ваш код обнаружит дубликат, который немедленно следует за оригиналом, но не тот, который встречается через 2 или более слов.

Массив words содержит 4 указателя, но памяти для этих указателей не выделено. Вам необходимо выделить память для каждого элемента массива words, а затем скопировать в него каждую строку:

if (duplicate_flag == 0)
{
  words[words_added++] = strdup(response); // allocates mem and copies the string
  puts("that's new!");
} else {
  ...
}

Тогда обязательно free память в конце вашей программы:

for (i = 0; i < words_added; ++i) {
  free(words[i]);
}
1 голос
/ 22 февраля 2012

Вы делаете это неправильно - вы указываете массив указателей - words[words_added] - на переменную, которая меняется на каждой итерации - response

Вам необходимо выделить память дляwords[words_added] на каждой итерации перед вводом strcpy:
strcpy(words[words_added], response);

PS Не ставьте точки с запятой после закрывающих скобок }

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