Разница между адресом переменной, указывающей на массив, и значением самой переменной

У меня есть массив

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]).

Другие вопросы по тегам