В чем разница в int * p и (int *) p в C

#arrays #c #pointers #casting #incompatibility

#массивы #c #указатели #Кастинг #несовместимость

Вопрос:

Я не мог понять использование (int *) p в следующей программе для указателя на массив

 #include<stdio.h>    
void main()     
{    
 int s[4][2];    
 int (*p)[2];    
 int i,j,*pint;    
    
 for(i=0;i<=3;i  )     
 {    
  p=amp;s[i];    
  pint=(int*)p; /*here*/    
  printf("n");    
  for(j=0;j<=1;j  )    
  printf("%d",*(pint j));    
 }    
}    
  

могу ли я использовать *p вместо (int*) p здесь. заранее спасибо

Комментарии:

1. @haccks Это в основном опечатка.

2. @SouravGhosh Я бы предложил откатить редактирование и позволить оператору объяснить, что он / она действительно намеревается делать.

3. @haccks и почему именно? OP упомянул вопрос в последней строке, который мне кажется довольно понятным.

Ответ №1:

В вашем коде,

  pint=(int*)p;
  

p имеет тип int (*)[2] , то есть указатель на массив из 2 int s, и pint является a int * . Они не являются совместимыми типами, поэтому вам нужно приведение.

Комментарии:

1. Но даже если я не приведу и не использую pint= * p, это дает тот же результат, что и так

2. @UV0 В этом случае *p эффективное использование делает то же самое. Он разыменовывает указатель, в результате int [2] чего значение, которое уменьшается int * при присвоении pint . Обратите внимание, что разыменование фактически не выполняет ссылку на память в этом случае. Это просто изменяет тип. Второе разыменование приведет к выполнению ссылки на память.

Ответ №2:

Если у вас есть объявление массива, подобное этому

 int s[4][2];
  

тогда эти три указателя имеют одинаковое значение

 int ( *p1 )[4][2] = amp;s;
int ( *p2 )[2] = amp;s[0];
int *p3 = amp;s[0][0]; 
  

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

Однако указатели имеют разные типы, потому что они указывают на объекты разных типов.

Первый указатель указывает на массив в целом как на единый объект. второй указатель указывает на элемент массива, который, в свою очередь, имеет тип массива int[2] . И третий массив указывает на скалярный объект типа int .

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

Вам нужно явно преобразовать один тип указателя в другой тип указателя.

Это назначение в исходной программе

 p=amp;s[i];
  

присваивает адрес каждого элемента (массива типа int[2] ) указателю. На самом деле это адрес первого элемента массива, которому он равен amp;s[i][0] . Однако первое выражение и последнее выражение имеют разные типы указателей.

Итак, вам нужно использовать приведение в этом назначении

 pint=(int*)p;
  

Теперь, используя арифметику указателя в этом выражении

 *(pint j)
  

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

Обратите внимание на то, что это объявление main

 void main() 
  

является ли nit стандартным объявлением.

Вы должны объявить функцию main как

 int main( void )