Ответ 1
Массивы и указатели не ведут себя одинаково, потому что они не то же самое, это просто так.
Массивы - это группа смежных элементов, в то время как указатель... ну... указатель на один элемент.
Этот выделенный элемент может быть первым в массиве, так что вы также можете получить доступ к другим, но сам указатель не знает и не заботится об этом.
Причина, по которой массивы и указатели часто кажутся одинаковыми, заключается в том, что во многих случаях массив будет распадаться на указатель на первый элемент этого массива.
Одно из мест, которое это происходит, - в вызовах функций. Когда вы передаете массив функции, она распадается на указатель. Вот почему такие вещи, как размер массива, явно не передаются функции. Под этим я подразумеваю:
#include <stdio.h>
static void fn (char plugh[]) {
printf ("size = %d\n", sizeof(plugh)); // will give char* size (4 for me).
}
int main (void) {
char xyzzy[10];
printf ("size = %d\n", sizeof(xyzzy)); // will give 10.
fn (xyzzy);
return 0;
}
Другое, что вы обнаружите, состоит в том, что, хотя вы можете plugh++
и plugh--
в своем содержании (до тех пор, пока вы не будете разыменовываться за пределами массива), вы не сможете сделать это с помощью массив xyzzy
.
В ваших двух структурах есть большая разница. В версии указателя у вас есть указатель фиксированного размера внутри структуры, который указывает на элемент вне структуры.
Вот почему он занимает пространство - ваш 8-байтовый указатель выравнивается по 8-байтовой границе следующим образом:
+----------------+
| 1 char variable|
+----------------+
| 7 char padding |
+----------------+
| 8 char pointer |
+----------------+
С "неограниченным" массивом у вас есть это внутри структуры, и вы можете сделать его таким большим, как вы хотите - вам просто нужно выделить достаточно памяти при создании переменной. По умолчанию (т.е. Согласно sizeof
) размер равен нулю:
+----------------+
| 1 char variable|
+----------------+
| 0 char array |
+----------------+
Но вы можете выделить больше места, например:
typedef struct {
char whatever;
char my_array_square[];
} my_struct_square;
my_struct_square twisty = malloc (sizeof (my_struct_square) + 10);
дает вам переменную twisty
, которая имеет символ whatever
и массив из десяти символов с именем my_array_square
.
Эти неограниченные массивы могут появляться только в конце структуры, и может быть только один (иначе компилятор понятия не имел, где эта секция переменной длины начиналась и заканчивалась), и они специально разрешают массивы произвольного размера на конец структур.