Почему адрес указателя массива совпадает с адресом, хранящимся в этом указателе?

Если вы попробуете этот фрагмент кода

#include<stdio.h> int main() { 


// Pointer to an integer 
int *p;  

// Pointer to an array of 5 integers 
int (*ptr)[5];  
int arr[] = { 3, 5, 6, 7, 9 };

// Points to 0th element of the arr. 


// Points to the whole array arr. 
ptr = &arr;  

printf("p = %p, address of P = %p
", p, &p); 
return 0; }

Вы получите что-то вроде p = 0x7fff8e9b4370, P address = 0x7fff8e9b4340 что означает, что адрес указателя P является чем-то, а данные внутри него являются другим

но если вы попробуете то же самое с указателем массива, как это

#include<stdio.h> int main() { 


// Pointer to an integer 
int *p;  

// Pointer to an array of 5 integers 
int (*ptr)[5];  
int arr[] = { 3, 5, 6, 7, 9 };

// Points to 0th element of the arr. 
p = arr; 

// Points to the whole array arr. 
ptr = &arr;  

printf("arr  = %p, arr address = %p
", arr, &arr); 
return 0; } 

Вы получите что-то вроде arr = 0x7ffda0a04310, arr address = 0x7ffda0a04310

Итак, как получилось, что данные указателя совпадают с указателем Address в памяти? !! когда мы разыскиваем адрес указателя arr, мы должны получить номер 3, но, как я понимаю, это адресное местоположение 0x7ffda0a04310 в памяти имеет 0x7ffda0a04310 в качестве данных

так где я ошибаюсь?

Всего 3 ответа


печать p означает значение print p , а значение p - адрес целочисленного числа или адреса целочисленного массива.

print &p означает, что вы печатаете местоположение p в памяти.

print arr покажет адрес первого элемента массива, это &arr[0] .

print &arr покажет местоположение arr на память, это также адрес первого элемента массива

Таким образом, печать p будет отличаться при печати &p . arr и &arr - разные типы, но это даст вам тот же результат.


Это происходит потому, что когда вы используете символ массива, он фактически оценивает &arr (адрес для первого элемента). Поэтому из-за этого arr и &arr - это тот же адрес (но не тот же тип!).

arr имеет тип int*

&arr имеет тип int(*)[5]

Разница заключается в том, что вы выполняете рисование арифметики. Приращение arr будет идти по адресу следующего элемента. Итак, *(arr+1) по существу совпадает с arr[1] . Incrementing &arr перескакивает по всему массиву (приращение указателя всегда перескакивает на весь размер)


Вы обнаружили, что адрес массива совпадает с адресом его первого члена.

Когда вы используете массив arr в выражении, в большинстве случаев он распадается на указатель на его первый элемент. Таким образом, выражение в выражении эквивалентно &arr[0] . Так как члены arr имеют тип int , выражение &arr[0] (и расширением arr ) имеет тип int * .

Однако в некоторых случаях этого распада не бывает. Один из них - когда массив является операндом оператора & . Таким образом, выражение &arr имеет тип int (*)[5] , то есть указатель на массив int размера 5.

Что касается того, почему значения этих двух адресов одинаковы, имеет смысл, если вы посмотрите на это:

                  arr 
                -------
0x7ffda0a04310  |  0  |
                -------
                |  0  |
                -------
                |  0  |
                -------
                |  0  |
                -------
0x7ffda0a04314  |  1  |
                -------
                |  1  |
                -------
                |  1  |
                -------
                |  1  |
                -------
                ...

Посмотрев на это, вы увидите, что сам массив и первый элемент массива начинаются с одного и того же адреса.

Таким образом, arr (как выражение) имеет тип int * while &arr имеет тип int(*)[5] , но оба имеют одинаковое значение.


Есть идеи?

10000