В этом объявлении функции
const char* f() {
const char* hello = "hello";
return hello;
}
указатель hello указывает на строковый литерал "hello", который имеет длительность хранения c. То есть не указатель имеет длительность хранения c, а указанный литерал имеет длительность хранения c. При каждом вызове функции указатель инициализируется заново.
Если вы объявите функцию наподобие
const char* f( ) {
static const char* hello = "hello";
return hello;
}
, то в этом случае сам указатель имеет длительность хранения c. Он инициализируется один раз, прежде чем программа получает управление, и его значение сохраняется между вызовами функций.
Например, рассмотрим эту демонстрационную программу.
#include <stdio.h>
const char* f( int i )
{
static const char* hello = "hello";
if ( i == 1 ) hello = "bye";
else if ( i == -1 ) hello = "hello";
return hello;
}
int main(void)
{
puts( f( 0 ) );
puts( f( 1 ) );
puts( f( 0 ) );
return 0;
}
Ее вывод
hello
bye
bye
То есть изначально указатель hello был инициализирован строковым литералом «hello».
Затем из-за этого вызова
puts( f( 1 ) );
его значение было изменено. Теперь он указывает на строковый литерал "пока".
И для третьего вызова
puts( f( 0 ) );
указатель сохраняет значение, которое было ему присвоено при предыдущем вызове функции.
Это связано с тем, что указатель имеет длительность хранения c.