C/C++: разница в использовании имени массива и имени указателя |
![]() |
Добавил(а) microsin | ||||||||||
Если Вы не первый год программируете на языке C, то наверное давно заметили, что имена массивов и имена указателей можно использовать примерно одинаково. Например, у нас есть массив char Array[10] и указатель char *ptr, и для обоих имен Array и ptr допустимы одинаковые операции: char Array[10]; char *ptr1; char *ptr2; ptr = Array;
//Обнуление блока памяти через имя массива
// и имя указателя работает одинаково: memset(Array,0,sizeof(Array)); memset(ptr,0,10); Array[0] = 'A'; // и так можно... ptr1[1] = 'B'; // и так тоже можно, теперь в массиве // Array содержится строка "AB"... //Указателю можно присвоить как адрес массива,
// так и значение указателя: ptr2 = Array+1; ptr2 = ptr+2; Возникает логичный вопрос: может быть, и массив, и указатель это одно и то же? Но почему тогда нельзя объявить массив, а потом в заголовочном файле объявить это же имя через extern как указатель? char Array[10]; ... extern char *Array; //так нельзя, компилятор выдаст ошибку, extern char Array[]; //а так можно, проблем нет. Очевидно, указатель и массив все-таки чем-то отличаются друг от друга. Ниже в таблице приведены эти отличия.
[Явные отличия указателя и массива] Ниже несколько примеров, которые демонстрируют отличия указателя и массива. #include < stdio.h >
int main() { int arr[] = {10, 20, 30, 40, 50, 60}; int *ptr = arr; // будет выведено sizof(int) * (количество элементов в массиве arr[]) printf("Размер arr[] равен %d\n", sizeof(arr)); // выведенный размер указателя будет одинаковым для всех типов // указателей (char *, void *, и т. д.) printf("Размер ptr равен %d", sizeof(ptr)); return 0; } Этот пример выведет следующее: Размер arr[] равен 24 Размер ptr равен 4 Также нельзя назначить любой адрес переменной массива: #include < stdio.h >
int main() { int arr[] = {10, 20}, x = 10; int *ptr = &x; // эта строка скомпилируется нормально arr = &x; // в этом месте компилятор выдаст ошибку return 0; } Компилятор выведет примерно следующее: Compiler Error: incompatible types when assigning to type 'int[2]' from type 'int *' Таким образом, можно сделать вывод, что массив определяется как постоянный указатель, у которого не может быть изменен адрес (char const *Array). [Чем похожи указатель и массив] Хотя массив и указатель - разные сущности языка C, некоторые их свойства выглядят одинаково. 1. Имя массива дает адрес первого элемента массива. Этот адрес можно присваивать указателю. Пример: #include < stdio.h >
int main() { int arr[] = {10, 20, 30, 40, 50, 60}; int *ptr = arr; // Значению указателя будет присвоен адрес массива printf("Значение первого элемента равно %d", *ptr); return 0; } Если пример запустить, то он выведет следующее: Значение первого элемента равно 10 2. К элементам массива можно получить доступ с помощью арифметики указателей. Компилятор использует эту арифметику для доступа к элементу массива. Например, выражение наподобие "arr[i]" обрабатывается компилятором как *(arr + i). Так что выражения наподобие *(arr + i) работают для массива так же, как и выражения наподобие ptr[i] для указателя. #include < stdio.h >
int main() { int arr[] = {10, 20, 30, 40, 50, 60}; int *ptr = arr; printf("arr[2] = %d\n", arr[2]); printf("*(ptr + 2) = %d\n", *(arr + 2)); printf("ptr[2] = %d\n", ptr[2]); printf("*(ptr + 2) = %d\n", *(ptr + 2)); return 0; } Этот код выведет: arr[2] = 30 *(ptr + 2) = 30 ptr[2] = 30 *(ptr + 2) = 30 3. Если массив передается в параметре функции, то он всегда передается как указатель, даже если указать имя массива с квадратными скобками. Пример: #include < stdio.h > int fun(int ptr[]) { int x = 10; // Будет выведен размер указателя printf("sizeof(ptr) = %d\n", sizeof(ptr)); // Это возможно, потому что ptr это указатель, а не массив. ptr = &x; printf("*ptr = %d ", *ptr); return 0; }int main() { int arr[] = {10, 20, 30, 40, 50, 60}; fun(arr); return 0; } Код выведет: sizeof(ptr) = 4 *ptr = 10 [Ссылки] 1. Difference between pointer and array in C? site:geeksforgeeks.org. |