Разница между адресом переменной, указывающей на массив, и значением самой переменной
У меня есть массив
int ar[5] = {1,2,3,4,5};
printf("%d",(ar==&ar));
Оператор печати возвращает true. Но что если я сделаю ar+1
а также &ar+1
, На что это указывает?
Также если у меня есть
char *c[] = {"GeksQuiz", "MCQ", "TEST", "QUIZ"};
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;
куда указывает cpp+1? Это после cp
т.е. cp[4]
или это указывает на cp[1]
?
2 ответа
Адрес массива соответствует расположению объекта массива в памяти и имеет тип "указатель на массив". Это местоположение имеет то же значение, что и адрес первого элемента массива. Адрес первого элемента массива - это то, во что будет уменьшаться имя массива при использовании в выражении. Это объясняет почему ar == &ar
,
Теперь, как ar
распадается на адрес первого элемента, ar + 1
это адрес второго элемента массива. Тем не менее, значение &ar
имеет указатель типа на массив, и так &ar + 1
на самом деле указывает после ar
сам массив, который будет адресом объекта после его последнего элемента (или &ar[5]
).
Ваш c
, cp
, а также cpp
массивы могут быть наглядно представлены следующим образом:
"GeksQuiz" "MCQ" "TEST" "QUIZ"
^ ^ ^ ^
c: | | | |
+---+ | | | |
+-------->| *----+ | | |
| +---+ | | |
| +------>| *--------------------+ | |
| | +---+ | |
| | +---->| *-----------------------------+ |
| | | +---+ |
| | | +-->| *------------------------------------------+
| | | | +---+
| | | |
| | | | cp:
| | | | +---+
| | | +-----* |<--+
| | | +---+ |
| | +-------* | |
| | +---+ |
| +---------* | |
| +---+ |
+-----------* | |
+---+ |
|
|
+---+ |
cpp:| *-----+
+---+
поскольку cpp
переменная указателя, cpp+1
на 1 больше, чем значение этой переменной. cpp
переменная содержит затухшее значение cp
(адрес его первого элемента). Так cpp+1
такой же как cp+1
, что будет соответствовать &cp[1]
или адрес второго элемента cp
,
За исключением случаев, когда это операнд sizeof
или одинарный &
оператор или строковый литерал, используемый для инициализации массива в объявлении, выражение типа "N-элемент T
"будет преобразован (" распад ") в выражение типа" указатель на T
", и его значением будет адрес первого элемента массива.
Выражение ar
имеет тип "5-элементный массив int
"; если это не операнд &
оператор, он будет преобразован в тип "указатель на int
", и его значением будет адрес первого элемента массива.
В выражении &ar
, ar
это операнд унарного &
оператор, поэтому преобразование не происходит; в этом случае тип выражения "указатель на 5-элементный массив int
".
И то и другое ar
а также &ar
имеют одинаковое значение (адрес первого элемента массива совпадает с адресом всего массива), но типы разные:
Expression Type Decays to
---------- ---- ---------
ar int [5] int *
&ar int (*)[5] n/a
ar + 1
укажет на следующее int
значение (это эквивалентно написанию &ar[1]
). &ar + 1
будет указывать на следующий 5-элементный массивint
(то есть он будет указывать на int
значение, следующее сразу за последним элементом массива).
cpp + 1
укажет на следующее char **
элемент (эквивалентно написанию &cp[1]
).