С чем ты еще не сталкивался?
strng create_string(); это объявление функции, не имеющей параметров и возвращающей значение типа
strng. Кода функции нет, программа должна искать его в другом месте, например ниже в тексте этого файла, в других cpp файлах, в lib файлах и т.д.
В общем случае функции объявляются следующим образом:
[тип_возвращаемого_значения] имя_функции (список_параметров)
Объявление функции возможно:
1. непосредственно в файле с кодом, т.е в файлах .c/.cpp
2. в заголовочных файлах т.е в файлах .h
strng create_string(); Это один из вариантов перегружаемой функции.
Перегрузкой называется объявление функций с одним и тем же именем, но разным списком аргументов.
В своих программах я придерживаюсь следующего порядка:
Код:

заголовочные файлы и макросы
список функций
глобальные переменные
main() или WinMain()
код функций
При таком порядке заголовочные файлы, макросы и список функций можно безболезненно перенести в .h файл, а сам код функций вынести в отдельный .c/.cpp файл.
Можно создать свое имя для какого-то типа данных, отражающее его сущность с помощью ключевого слова typedef
typedef char* strng
typedef базовый_тип_данных пользовательский_тип_данных
strng create_string(); эквивалентно
char* create_string();
Это нужно, чтобы функция продолжала оставаться рабочей даже если мы переопределили тип по другому, т.е например написали
typedef int* strng
В моей программе переопределить так тип не получится, нужна проверка в функциях на соответствие данных. В общем случае лучше в каждой функции проверять соответствие параметров нужным - это сильно упрощает последующее использование кода в каких-либо других проектах.