какая разница между while (* p) {p ++;}, while (* ++ p) {;} и while (* p ++) {;}?

Речь идет о функции strcat .

 while (*p) p++; 

а также

 while (*++p) ; 

обе работы, но

 while (*p++) ; 

не работает. Я думаю, что первая и третья должны быть одинаковыми, но это не так.

И то и другое

 while (*p) p++; 

а также

 while (*++p) ; 

будет продвигать p чтобы указать на терминатор 0 в строке, тогда как

 while (*p++) ; 

будет продвигать p чтобы указать один символ за 0 терминатором.

Чтобы понять, почему, предположим следующие символы в памяти:

 Address 0x00 0x01 0x02 0x03 ------- ---- ---- ---- ---- 0x8000 'a' 'b' 'c' 0 0x8004 ... 

Предположим, что p начинается с адреса 0x8000. Вот как выглядит первый цикл:

 1. *p = 'a' 2. p = 0x8001 3. *p = 'b' 4. p = 0x8002 5. *p = 'c' 6. p = 0x8003 7. *p = 0 8. end loop 

Вот как выглядит второй цикл:

 1. p = 0x8001 2. *p = 'b' 3. p = 0x8002 4. *p = 'c' 5. p = 0x8003 6. *p = 0 7. end loop 

И вот последний:

 1. *p = 'a' 2. p = 0x8001 3. *p = 'b' 4. p = 0x8002 5. *p = 'c' 6. p = 0x8003 7. *p = 0; 8. p = 0x8004 9. end loop 

В последней версии оценка *p++ продвигает указатель, даже если значение *p равно 0.

Предположим, что p – строка.

 while (*p) p++; /* (1) */ while (*++p) ; /* (2) */ while (*p++) ; /* (3) */ 
  • (1) отличается от (2), если p – пустая строка.
  • (1) отличается от (3), потому что с (3) , даже если текущее значение *p является символом '\0' , p увеличивается.
 // move p forward as long as it points to a non-0 character, // leave it pointing to a 0 character. while (*p) p++; // move p forward until it points to a 0 character, skipping the first // character before you start while (*++p); // move p forward until it points one past a 0 character while (*p++); 

Поэтому, учитывая, что (1) «работает»: (2) также работает, если p первоначально указывает на непустую строку. (3) не работает вообще, потому что p заканчивается, указывая на другое место.

*++p увеличивает p а затем оценивает то, на что указывает p . *p++ оценивает то, что изначально указывает на p , но также увеличивает p . Следовательно, (2) и (3) различны.

(1) и (3) различны, потому что (3) выполняет p++ , тогда он решает, остановить ли. (1) сначала смотрит на *p чтобы решить, стоит ли останавливаться, а если не останавливать, он выполняет p++ .

* ++ p означает увеличение этой переменной, а затем ее использование
* p ++ означает использование переменной, затем увеличивайте ее