О приведении массива к указателям - PullRequest
3 голосов
/ 21 сентября 2019

Я хочу понять, где именно в коде массив преобразуется в указатель.Например:

void foo( int* pData, int len){}

int main(void){
    char data[] = "Hello world";

    foo( (int*)data, sizeof(data));

    return 0;
}

Я знаю, что массив распадается на указатель на первый элемент, если он назначен указателю.Однако в приведенном выше примере я сначала приведу данные массива к типу int *, прежде чем передать их в функцию и присвоить указателю.Происходит ли преобразование / затухание указателя в точке приведения типов?Если это так, то не правда ли сказать, что операция приведения типов имеет тот же эффект, что и использование оператора присваивания в отношении преобразования / затухания массива?Также будет ли sizeof (data) равным длине адреса или длине массива?

Спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 22 сентября 2019

Преобразование массивов в указатели в C прописано в разделе 6.3.2.1p3 стандарта C :

За исключением случаев, когда он является операндом sizeof оператор, оператор _Alignof или унарный оператор &, или строковый литерал, используемый для инициализации массива, выражение с типом «массив типа» преобразуется в выражение с типом «указатель на тип»это указывает на начальный элемент объекта массива и не является lvalue.Если объект массива имеет класс хранения регистров, поведение не определено.

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

Таким образом, применение выше к (int*)data, data является операндом оператора typecast.Поскольку этот оператор не является одним из перечисленных выше, data в этом выражении преобразуется из char [12] в char *, затем приведение преобразует char * в int *.

.как упоминалось выше, массив не преобразуется при передаче в sizeof.Это означает, что sizeof(data) соответствует размеру char [12], равному 12.

0 голосов
/ 22 сентября 2019

Вне объявления вы можете считать data эквивалентным указателю на начало массива, но со следующими исключениями:

  • sizeof(data) даст вам размермассив в байтах.
  • _Alignof(data) будет таким же, как _Alignof(*data) (и оба дают выравнивание типа элементов массива)
  • &data имеет то же значениекак просто data, но имеет тип char (*)[sizeof(data], поэтому арифметика будет использовать полный размер массива.Например, &data+1 даст вам адрес после всего массива, а не адрес второго элемента.См. Почему адрес массива равен его значению в C?
  • Вы не можете изменить его значение (т. Е. В этом смысле он эквивалентен char *const).

Когда вы вызываете свою функцию, вы берете значение data (т.е. адрес начала массива) и типизируете значение int *.Результирующий int * ведет себя как любой другой int *, и исключения не применяются, это «распад».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...