и ret
и n
являются указателями на один и тот же блок памяти. их «значения» являются просто адресами памяти - при изменении *n
вы изменяете *ret
, даже если n
и ret
сохраняют свои исходные значения.
//make n point to the beginning of the block of memory pointed
//to by ret
n = ret;
//iterate through the string which was passed to
//the function
for ( ;*s != 0; s++)
//if the current character is a letter:
if (isLetter(*s))
//set the character pointed to by n to
//the current character in the string, and then
//make n point to the next one.
*n++ = *s;
обратите внимание, что цикл увеличивается n
, а затем после цикла устанавливает последний символ равным 0 (чтобы завершить строку нулем). Теперь n
указывает на конец строки - но поскольку ret
никогда не изменялся, он по-прежнему указывает на начало памяти, которую вы malloc
редактировали перед циклом. Когда вы его возвращаете, вы возвращаете указатель на новую строку, то есть строку, которую вы передали функции, за вычетом всех не-букв.
Обратите внимание, что после возврата этой функции вызывающая сторона несет ответственность за free()
память, выделенную функцией, чтобы вы не бродили по утечкам памяти.