Массивы и указатели не ведут себя одинаково, потому что они не одинаковы вообще, просто кажется, что так.
Массивы представляют собой группу смежных элементов, в то время как указательis ... well ... указатель на один элемент.
Этот единственный элемент, на который указывает указатель, вполне может быть первым в массиве, так что вы можете получить доступ и к другим элементам., но сам указатель не знает и не заботится об этом.
Причина, по которой массивы и указатели часто кажутся идентичными, заключается в том, что во многих случаях массив будет затухать по отношению к указателю на первый элемент этого массива.
Одно из мест, где это происходит, - вызовы функций.Когда вы передаете массив функции, он превращается в указатель.Вот почему такие вещи, как размер массива, явно не передаются функции.Под этим я подразумеваю:
#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
.
Эти неограниченные массивы могут появляться только в конце структуры, и может быть только один (в противном случае компилятор будетпонятия не имею, где эти секции переменной длины начинаются и заканчиваются), и они специально разрешают массивы произвольного размера в конце структур.