Это
char s[]="TvNnFs",*p;
, где s
- это массив символов, а p
- это указатель на символ, он выглядит ниже
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
------------------------------------------
| T | v | N | n | F | s | \0 |
------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106.. (assume 0x100 is base address of s)
Далее цикл for
for(p=&s[5];p>=s;p--)
--*p;
Здесь p=&s[5]
указатель p
указывает на адрес s[5]
, т.е. 0x105
. Далее следует p>=s
т.е. 0x105 >= 0x100
, что верно, затем --*p
выполняется, т. Е. Сначала *p
, что означает значение в 0x105
ячейке памяти, равное s
, и уменьшение на которое будет s[5]
как r
,
Теперь массив символов s
выглядит как
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
---------------------------------------------
| T | v | N | n | F | r(new)| \0 |
---------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
Примечание: вам может быть интересно узнать, что, если сделать --*p
, как это повлияет на s
? Это потому, что p
указывает или удерживает адрес s
, т. Е. Любые изменения, сделанные на *p
, косвенно влияют на s
.
После этого p--
происходит, т. Е. p
теперь указывает на одну позицию, предшествующую ранее, т. Е. 0x104
. Та же операция будет происходить, пока p
не достигнет s
, т.е. 0x100 >= 0x100
Наконец, массив символов s
выглядит как
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
-------------------------------------------
| S | u | M | m | E | r | \0 |
-------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
Следовательно печатает SuMmEr
.
Дело 2:
char s[]="TvNnFs",*p;
for(p=&s[5]; p>=s; p--)
((--*p)<'a')?(*p+=('a'-'A')):(*p);
puts(s);
Здесь
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
------------------------------------------
| T | v | N | n | F | s | \0 |
------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
|
p points here
Для 0x105 >= 0x100
: это
((--*p)<'a')?(*p+=('a'-'A')):(*p);
является троичным оператором, т. Е. Сначала выполняется ((--*p)<'a')
, если это приводит к истине, тогда (*p+=('a'-'A'))
будет выводом, в противном случае (*p)
. Так вот, это выглядит как ((--*p)<'a')
, т.е. 'r' < 'a'
, что является ложным, поэтому просто (*p)
, но s[5]
изменилось после этого из-за --*p
.
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
------------------------------------------
| T | v | N | n | F | r | \0 |
------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
|
p points here due to p--
Далее, для 0x104 >= 0x100
: это
((--*p)<'a')?(*p+=('a'-'A')):(*p);
'E' < 'a'
то есть 70 < 97
, что верно, поэтому (*p+=('a'-'A'))
исполняется, т.е.
*p = *p + ('a' - 'A')
= 'E' + (97 - 65)
= 'E' + 32
*p = 'e' /* now s[4] overwritten by e(previously F) */
Теперь массив выглядит как
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
------------------------------------------
| T | v | N | n | e | r | \0 |
------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
|
p points here due to p--
Та же операция работает до 0x100 >= 0x100
.