Преинкремент в указателях персонажа

Я играл с концепцией указателей массива. Я написал эту простую программу:

#include <stdio.h>

int main (int argc, char **argv){
    char s[] = "Hello world!\n";
    char *i;
    for (i = s; *i; ++i){
        printf(i);
    }
    return 0;
}

что дает очень забавный вывод:

Hello world!
ello world!
llo world!
lo world!
o world!
 world!
world!
orld!
rld!
ld!
d!
!

Однако когда я написал это, у меня сложилось впечатление, что вывод начнется со второго ряда. Причина в том, что в цикле я использую нотацию перед приращением. i установлен в начале s, булево условие проверяется и выполняется i увеличивается, и блок выполняется.

Это было мое впечатление, но, очевидно, оно ошибочно, поскольку блок выполняется раньше i увеличивается Я переписал программу, используя постинкрементную запись, и получил точно такой же результат, который подтверждает мою гипотезу. Если это так, то как они воспринимаются по-разному в этой программе?

6 ответов

Решение
for (initialization; condition; increase) statement;

это for работает следующим образом:

  1. initialization выполнен. Обычно это объявляет переменную-счетчик и устанавливает для нее начальное значение. Это выполняется один раз, в начале цикла.

  2. condition проверено. Если это trueцикл продолжается; в противном случае цикл заканчивается, и statement пропускается, переходя непосредственно к шагу 5.

  3. statement выполнен. Как обычно, это может быть либо отдельный оператор, либо блок, заключенный в фигурные скобки { }.

  4. increase выполняется, и цикл возвращается к шагу 2.

  5. цикл заканчивается: выполнение продолжается после следующего оператора.

Нет разницы между постинкрементом и преинкрементом, потому что increase в любом случае выполняется отдельно.

Выражение приращения for цикл выполняется после тела. Для вашего случая

for (i = s; *i; ++i){
  printf(i);
}

похож на

i = s;       // loop init
while (*i)   // loop condition
{
  printf(i);
  ++i;       // loop increment
}

Для i задано начало s, проверяется логическое условие, и оно сохраняется, затем увеличивается и блок выполняется.

Не совсем. Фактический синтаксис

  1. i установлен в начале s

  2. логическое условие проверяется

    2.1. если это верно, блок выполняется,

    2.2. выйти из цикла в противном случае.

  3. затем i увеличивается и переходите к шагу 2.

Примечание. В этом конкретном сценарии до и после увеличения i не будут иметь никакого значения.

Эквивалент

for( a ; b ; c )
{
  statements
}

является

a ;
while( b ) 
{
  statement
  c ;
}

а также

++i ;
i++ ;

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

Причина в том, что в цикле я использую нотацию перед приращением. Для i задано начало s, проверяется логическое условие, и оно сохраняется, затем увеличивается и блок выполняется.

Нет. i увеличивается после выполнения блока.

Я переписал программу, используя постинкрементную запись, и получил точно такой же результат, который подтверждает мою гипотезу. Если это так, то как они воспринимаются по-разному в этой программе?

Они не. Постинкремент или преинкремент не будет иметь большого значения. Разница между этими двумя заключается в выражении i++, ++i (а именно, будет ли оно соответствовать предыдущему или новому значению?). Он волшебным образом не изменяет весь поток инкапсулирующей структуры управления. Оцененный результат выражения приращения просто отбрасывается, поэтому не имеет значения, что вы делаете, пока вы предоставляете выражение, которое приводит к приращению i,

Это как, как это:

int main()
{
    int x = 5;
    int y = 5;

    int a = x++;
    int b = ++y;
}

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

int main()
{
   int x = 5;
   x++;
}

int main()
{
   int x = 5;
   ++x;
}

идентичны

Я увеличивается после того, как блок выполняется.

Попробуй это:

for(int i = 0; i < 5; ++i )
{
  printf("\n %d",i);
}
Другие вопросы по тегам