Ответ 1
/* token.c */
struct token id_tokens[MAX_TOKENS];
/*
id_tokens
+-----+-----+-----+-----+...+-----+
| | | | | | |
+-----+-----+-----+-----+...+-----+
[0] [1] [2] [3] ... [MAX_TOKEN-1]
To access id_tokens[i], add offset of ith element
i.e. i * sizeof(struct token) to the **address**
of array token
*/
Итак, в вашем analyse.c
с этим объявлением будут созданы следующие инструкции.
extern struct token id_tokens[];
id_tokens [i]
a. Адрес id_tokens, который может быть связан с другим модулем компиляции взято
b. смещение я добавляется
c. Значение ссылается
/* analyse.c (v1) */
extern struct token *id_tokens;
/*
id_tokens
+------+ +-----+...
| addr |---------->| |
+------+ +-----+...
To access id_tokens[i], fetch **contetnts** of pointer
token, add offset of ith element i.e. i * sizeof(struct token)
is added to this.
*/
Итак, в вашем analyse.c
следующие инструкции будут сгенерированы с этим объявлением:
extern struct token *id_tokens;
id_tokens [i]
a. Содержание с адреса id_tokens, связанного с другим блок компиляции принят.
(Приведет к ошибке компиляции, если она присутствует в том же компиляторе из-за несоответствия типа)
b. смещение я добавляется
c. Значение ссылается
Предположим, что sizeof id_token[0]
- это 2
байт, а sizeof указатель на id_token[0]
- это 4
байт.
Ваше более позднее объявление может (неверно) интерпретировать id_tokens[0]
и id_tokens[1]
как адрес и добавлять к нему некоторое смещение (которое может быть уже существующим или несуществующим адресом, выровненным или неприсоединившимся адресом, который знает).
Если это ваш хороший день, программа может сразу же произойти сбой или segfault, и вы получите возможность исправить ошибку. Если это ваш плохой день, программа может просто испортить какую-то другую память или сообщить неправильное состояние в какой-либо модуль, что может привести к затруднению отслеживания ошибок и вызвать кошмар.
Теперь, я думаю, вы понимаете, почему вы получили (nil)
как вывод в Mr. 32 ответ.