Является ли оператор & важным для использования в качестве оператора адреса?

#include<stdio.h>
int main()
{
    int a[5] = {5,10,15,20,25};
    int *p;
    int i;
    p=a;
    for (i=0;i<=5;i++)
    {
        printf("the address of the %d is = %d\n",*p,p);
        p++;    
    }
return 0;
}

В моей программе я даже не знаю, что там происходило, потому что, если поместить адрес оператора в седьмую строку кода, который =(p=&a) иначе я не помещаю = (p=a) адрес оператора, ответ о времени работы обоих случаев такие же.

Я ожидал, что ответ может быть разным в обоих случаях, но в обоих случаях ответ один и тот же.

Массивы распадаются на указатель

Daniel A. White 17.07.2024 16:52
&a — адрес всего массива (из 5 целых чисел); a all сам по себе является (в большинстве контекстов автоматически преобразуется) адресом первого элемента (одно целое число). Это немного похоже на указание на весь поезд, а не на первый вагон. Разница очевидна, когда думаешь о «следующем»… это «следующий поезд» или «следующий вагон»?
pmg 17.07.2024 17:00
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
2
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Для начала это цикл for

for (i=0;i<=5;i++)
{
    printf("the address of the %d is = %d\n",*p,p);
    p++;    
}

вызывает неопределенное поведение, поскольку допустимым диапазоном элементов массива a является [0, 5 ) вместо [0, 5]. То есть, когда i равно 5, выражение *p пытается получить доступ к памяти вне массива a, что приводит к неопределенному поведению. А для вывода указателя следует использовать спецификатор преобразования p вместо d. В противном случае ваш код снова будет иметь неопределенное поведение.

По крайней мере, вы должны написать цикл for, например

for ( size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++ )
{
    //...
}

Что касается вашего вопроса, то адрес массива и адрес его первого элемента совпадают. Хотя относительно выражений вашего кода a и &a, используемых в качестве инициализаторов в этом выражении, например

p=a;

или

p=&a;

имеют разные типы. Выражение a имеет тип int *, а выражение &a имеет тип int ( * )[5]. Итак, для этого утверждения

p=&a;

компилятор должен выдать сообщение об ошибке или предупреждение о том, что используются несовместимые типы указателей.

Обратите внимание, что массивы, используемые в выражениях, за редкими исключениями (например, используемые с оператором sizeof), неявно преобразуются в указатели на их первые элементы.

Ответ принят как подходящий

я даже не знаю, что там происходило, потому что если поставить адрес оператора в седьмой строке кода =(p=&a) else Не ставлю =(p=a) адрес оператора ответ бегущего время обоих случаев одинаково.

Это потому, что массивы распадаются до ссылки на свой первый элемент. Когда вы используете &, вы получаете ту же ссылку, но другого типа.

int main(void)
{
    int array[5];

    int *pointer_to_int = array;
    int *pointer_to_int1 = &array[0];

    int (*pointer_to_array)[5] = &array;

    printf("%p %p %p %p %zu\n", (void *)pointer_to_int, (void *)pointer_to_int1, (void *)(pointer_to_int + 1), (void *)(pointer_to_int1 + 1), sizeof(*pointer_to_int));
    printf("%p %p %zu\n", (void *)pointer_to_array, (void *)(pointer_to_array + 1), sizeof(*pointer_to_array));
}
  • pointer_to_int и pointer_to_int1 имеют тип указателя на int и ссылаются на первый элемент array
  • pointer_to_array имеет тип указателя на массив из 5 int элементов.

При запуске выложенной программы вы получите результат (реальные адреса могут быть разными):

0x7ffef9ea1320 0x7ffef9ea1320 0x7ffef9ea1324 0x7ffef9ea1324 4
0x7ffef9ea1320 0x7ffef9ea1334 20

как вы можете видеть, арифметика указателей ведет себя по-другому.

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