цикл while(*p ) не печатает первый элемент строки

#c #pointers

#c #указатели

Вопрос:

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

Пример: если char *p="hello" при печати посимвольного использования while(*p ) цикл 'h' пропускается, а вывод — "ello" пожалуйста, кто-нибудь может это объяснить?

   #include <stdio.h>
  #include <stdlib.h>
  int main() 
  {
    char *p=(char*)malloc(sizeof(char)*20);
    printf("enter stringn");
    scanf("%s",p);
    while(*p  )// value is assign and address is increased
    {
      printf("%c",*p);//why first character is skipped??
    }
    return 0;
  }
  

Комментарии:

1. Ваш код усложняет его использование free

Ответ №1:

Чтобы увидеть первую букву, измените *p на p[-1] , потому p что она уже увеличилась p , поэтому к моменту первого использования *p p уже указывает на 2-ю букву (с индексом 1).

Есть много других способов решить эту проблему, например

 for (; *p;   p) {
  putchar(*p);
}
  

Ответ №2:

Потому while(*p ) что увеличивает значение, как только начинается цикл. К моменту достижения инструкции printf p он уже увеличен.

 p = 0
while(p  ) {   // p = p   1
   printf('%d', p);  // p = 1 when this executes
}
  

Комментарии:

1. @marx B Спасибо, но как я могу сделать, я должен использовать цикл while, а мой код должен состоять только из двух строк?

2. do { ... } while () вместо этого используйте a. это поместит ваше приращение в КОНЕЦ цикла: do { printf(...) } while(p );

3. или while(*p) и иметь приращение в printf.

4. @SeriousBusiness: да, это тоже сработало бы, но позже кто-нибудь попробует это и слепо скопирует p через несколько других операторов и задастся вопросом, почему значение прыгает на 5 или 6.

5. @MarcB проклятие копирования макаронных изделий

Ответ №3:

while(*p ) после этого оператор p увеличивается и перемещается вперед. Таким образом, at printf() p уже указывает на 2-й символ.

Ответ №4:

Строка while(*p ) проверит значение *p и затем увеличит p его, прежде чем войти в тело цикла. Вы можете улучшить код, используя for цикл

 for ( ; *p; p   )
    printf( "%c", *p );
  

или путем увеличения указателя после его использования в теле цикла

 while(*p)
    printf( "%c", *p   );