Как "while (* s ++ = * t ++)" копировать строку? - PullRequest
52 голосов
/ 01 мая 2009

У меня вопрос, что делает этот код (с http://www.joelonsoftware.com/articles/CollegeAdvice.html):

while (*s++ = *t++);

на сайте написано, что код выше копирует строку, но я не понимаю, почему ...

это имеет отношение к указателям?

Ответы [ 16 ]

0 голосов
/ 16 мая 2013

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

Фактическое семантическое объяснение цикла while будет выглядеть примерно так:

for (;;) {
    char *olds = s;             // original s in olds
    char *oldt = t;             // original t in oldt
    char c = *oldt;             // original *t in c
    s += 1;                     // complete post increment of s
    t += 1;                     // complete post increment of t
    *olds = c;                  // copy character c into *olds
    if (c) continue;            // continue if c is not 0
    break;                      // otherwise loop ends
}

Порядок сохранения s и t и порядок увеличения s и t могут быть изменены. Сохранение от *oldt до c может произойти в любое время после сохранения oldt и до использования c. Назначение от c до *olds может произойти в любое время после сохранения c и olds. На обратной стороне моего конверта это работает как минимум с 40 различными интерпретациями.

0 голосов
/ 01 мая 2009

запускает цикл while ...

* s = * t идет первым, это назначает то, на что указывает t, на что указывает s. т.е. он копирует символ из строки t в строку s.

то, что присваивается, передается условию while ... любое ненулевое значение равно "true", поэтому оно будет продолжено, а 0 равно false, оно остановится .... и это просто происходит, когда конец строки также ноль.

s ++ и t ++ они увеличивают указатели

и все начинается снова

так что он продолжает назначать циклы, перемещая указатели, пока не достигнет 0, что является концом строки

0 голосов
/ 01 мая 2009

Скажем, у вас есть что-то вроде этого:

char *someString = "Hello, World!";

someString указывает на первый символ в строке - в данном случае 'H'.

Теперь, если вы увеличите указатель на единицу:

someString++

someString теперь будет указывать на 'e'.

while ( *someString++ );

будет зацикливаться, пока все, на что указывает someString , не станет NULL, что означает конец строки ("NULL Termination").

и код:

while (*s++ = *t++);

невероятно похож на:

while ( *t != NULL ) { // While whatever t points to isn't NULL
    *s = *t;           // copy whatever t points to into s
    s++;
    t++;
}
0 голосов
/ 01 мая 2009

Да, здесь используются указатели, а также выполняется вся работа при оценке состояния while. C позволяет условным выражениям иметь побочные эффекты.

Оператор "*" разыменовывает указатели s и t.

Оператор приращения ("++") увеличивает указатели s и t после назначения.

Цикл завершается при условии нулевого символа, который оценивается как ложный в C.

Один дополнительный комментарий .... это не безопасный код, так как он ничего не делает для того, чтобы s имел достаточно памяти

0 голосов
/ 01 мая 2009

копирует строку, потому что массивы всегда передаются по ссылке, а строка это просто массив символов. В основном то, что происходит, - (если я правильно помню термин) арифметика указателя. Вот немного больше информации из википедии о массивах c .

Вы сохраняете значение, которое было разыменовано от t в s, а затем переходите к следующему индексу через ++.

0 голосов
/ 01 мая 2009

Да, это связано с указателями.

Способ чтения кода следующий: «значение, на которое указывает указатель« s »(которое увеличивается после этой операции), получает значение, на которое указывает указатель« t »(который увеличивается после этой операции; все значение этой операции оценивается как значение скопированного символа; итерация по этой операции до тех пор, пока это значение не станет равным нулю. цикл будет повторяться до тех пор, пока строка не будет скопирована из местоположения, на которое указывает t, в местоположение, на которое указывает s.

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