Префикс k
происходит от того времени, когда многие разработчики любили использовать Венгерскую нотацию в своем коде. В венгерской нотации каждая переменная имеет префикс, который сообщает вам, какой это тип. pSize
будет указателем с именем "size", тогда как iSize
будет целым числом с именем "size". Просто глядя на имя, вы знаете тип переменной. Это может быть очень полезно в отсутствие современных IDE, которые могут показать вам тип любой переменной в любое время, в противном случае вам всегда придется искать объявление, чтобы узнать его. Следуя тенденциям времени, Apple хотела иметь общий префикс для всех констант.
Хорошо, тогда почему бы не c
, как c
для "константы"? Поскольку c
уже было принято, в венгерской нотации c
означает «счетчик» (cApple
означает «количество яблок»). Есть похожая проблема с class
, который является ключевым словом во многих языках, так как вы называете переменную, которая указывает на класс? Вы найдете тонны кода с именем этой переменной klass
и, таким образом, был выбран k
, k
как в "konstant". Во многих языках это слово действительно начинается с k, см. Здесь .
Относительно вашего второго вопроса: вам не следует вообще использовать #define
для константы, если вы можете избежать этого, так как #define
не содержит текста.
const int x = 10; // Type is int
const short y = 20; // Type is short
const uint64_t z = 30; // Type is for sure UInt64
const double d = 5000; // Type is for sure double
const char * str = "Hello"; // Type is for sure char *
#define FOO 90
Какой тип FOO? Это какое-то число. Но что за номер? Пока что любой тип или вообще никакой тип. Тип будет зависеть от того, как и где вы используете FOO
в вашем коде.
Также, если у вас есть фиксированный набор чисел, используйте enum
, так как тогда компилятор может проверить, что вы используете допустимое значение, и значения перечисления всегда постоянны.
Если вам нужно использовать определение, не имеет значения, где вы его определяете. Заголовочные файлы - это файлы, которыми вы делитесь между несколькими файлами кода, поэтому, если вам нужно одно и то же определение в более чем одном месте, вы записываете его в файл заголовка и включаете этот заголовочный файл везде, где это определение необходимо. То, что вы записываете в файл кода, видно только внутри этого файла кода, за исключением нестатических функций и классов Obj-C, которые по умолчанию видны глобально. Но если функция не объявлена в файле заголовка и этот файл заголовка включен в файл кода, где вы хотите использовать эту функцию, компилятор не будет знать, как выглядит эта функция (какие параметры она ожидает, какое значение результата она возвращает) Таким образом, он не может проверить что-либо из этого и должен полагаться, что вы вызываете его правильно (обычно это заставит его создать предупреждение). Классы Obj-C не могут использоваться вообще, если только вы не скажете текущему файлу кода, по крайней мере, что это имя является именем класса, но если вы действительно хотите что-то сделать с этим классом (не просто передавая его), компилятор должен знать интерфейс класса, поэтому интерфейсы входят в заголовочные файлы (если класс используется только в текущем файле кода, запись интерфейса и реализация в файл допустимы и также будут работать).