Нет, это не так.Массивы и указатели - это разные животные.Массив представляет количество последовательных элементов одного и того же типа и имеет размер размер , который представляет собой размер отдельного элемента, умноженный на количество его элементов.Он всегда будет представлять одну и ту же зону памяти на протяжении всего своего времени жизни.
С другой стороны, указатель является указателем или ссылкой на первый элемент массива - одну переменнуюассимилируется с массивом размера 1 для этой точки.Он не имеет представления о размере своего остроконечного массива, а размер указателя - это именно то, что нужно реализации для представления адреса памяти.Если T является типом и если int_ptr
является допустимым в реализации, то верно следующее равенство:
sizeof(T *) == sizeof(int_ptr)
Указатель обычно может указывать на разные переменные или зоны памяти на протяжении всего своегопродолжительность жизни.Конечно, это может быть сделано const, и в этом случае изменение его значения вызовет неопределенное поведение, но может быть разрешено компилятором, в то время как вы никогда не сможете изменить положение массива.
Теперь для ваших примеров:
const char arr[2] = {0, 0};
arr
- это истинный массив: arr = x;
вызовет ошибку компиляции, а sizeof(arr)
- это 2
const char *const arr = "\0\0";
arr
- это константный указатель на const char.arr = x;
будет отклонено, но (const char *) arr = x;
будет принято во время компиляции (и вызовет UB во время выполнения).Но за исключением 16-битной среды sizeof(arr)
- это не 2, а размер указателя (4 в 32-битной среде, 8 в 64-битной)
const char *arr = "\0\0";
arr
- это указатель на constголец.arr = "abcd";
допустимо и будет arr
указывать на другой строковый литерал другого размера.Его размер по-прежнему равен размеру указателя.
Не имеет отношения к вопросу, но есть другое важное различие между массивами и указателями в неконстантном случае использования:
char arr[2] = "a";
здесь arr
- массив , инициализированный символами 'a' и '\ 0'.arr[0] = 'b';
допустимо
char *arr = "a";
здесь arr
- указатель на литеральную строку.Поскольку буквенные строки являются константными, arr[0] = 'b';
вызывает UB.(современные компиляторы должны выдавать предупреждение для char *arr = "a";
, но по причинам совместимости они не обязаны это делать)
Кстати, путаница между массивами и указателями заключается в том, что массив может автоматически преобразовываться в указатели при использованииих значение:
char arr[] = "abc"; // array of size 4
f(arr); // the f function receives a pointer to the first element of arr