Если вы попробуете этот фрагмент кода
#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]
, но оба имеют одинаковое значение.