Давайте go рассмотрим каждый из ваших вопросов один за другим.
Печать
В первом фрагменте кода вы показываете, что printf
может печатать строки. Конечно, он напечатал строку. Вы дали ему %s
, что означает строку. Но сначала, что такое строка? Чтобы объяснить это, нам нужно понять массивы и символы.
Что такое строка?
Во-первых, что такое char
? char
- это особый символ (или 8-битное число, но для наших целей это символ). Символом может быть буква (a
, b
, c
) m или любой другой символ (?
, !
, .
, цифры, также есть некоторые управляющие символы). Обычно, если вам нужен только один символ, вы объявляете его так:
char letter_a = 'a';
Итак, что такое массив? Массив - это группа значений, расположенных рядом друг с другом. Рассмотрим следующий код:
int int_array[] = int[50];
int_array[0] = 1;
int_array[1] = 2;
...
В этом примере что такое int_array
? Ответ кажется очевидным. Это массив. Но это еще не все. Что, если мы сделаем это?
printf("%d\n", *int_array);
Он напечатает 1
. Зачем? Потому что int_array на самом деле просто указатель на первый элемент массива.
Так почему я говорю о массивах? Потому что строка - это просто массив символов. Когда вы запускаете char* string = "Hello!"
, вы просто создаете массив, который выглядит так: ['H', 'e', 'l', 'l', 'o', '!', '\0']
. C знает, что строка закончилась, как только достигнет нулевого символа ('\0'
).
В вашем первом фрагменте var является указателем на букву 'H', а оператор печати продолжает печатать символы пока он не достигнет нуля.
А как насчет второго фрагмента?
%d
не разыменовывает переменную, как %s
. Он просто печатает число как целое число со знаком. Целое число в данном случае - это адрес памяти вашего целого числа.
Почему вы не можете назначать указатели?
Можно. Вы получите предупреждение, которое, вероятно, вызовет ошибку сегментации, но вы можете попробовать. Я скомпилировал ваш пример кода, используя clang, и вот что у меня получилось:
test.c:1:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]
void main() {
^
test.c:1:1: note: change return type to 'int'
void main() {
^~~~
int
test.c:2:7: warning: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int' [-Wint-conversion]
int* var = 5;
^ ~
2 warnings generated.
Я не осмелюсь попытаться запустить его. По сути, вы только что попытались получить доступ к пятому месту в памяти, которое, скорее всего, является частью операционной системы. У вас нет доступа к этому
Почему это сработало для строки?
Потому что оно не указывает на конкретное c местоположение. Он указывает на расположение строки, которую C сделал для вас. Ваш код примерно эквивалентен этому:
char h = 'H';
char e = 'e';
...
char* var = &h;