Подтвердить что ты не робот

Объясните двусмысленность указателей в C?

#include<stdio.h>
main()
{ int x[3][5]={{1,2,10,4,5},{6,7,1,9,10},{11,12,13,14,15}};


printf("%d\n",x); 
printf("%d\n",*x); }

Здесь первый printf напечатает адрес первого элемента. Так почему бы не второй printf напечатать значение по адресу x i.e первое значение. Чтобы напечатать значение, мне нужно написать ** x.

4b9b3361

Ответ 1

Для указателей x[0] совпадает с *x. Из этого следует, что *x[0] совпадает с **x.

В *x[0]:

x является int[3][5], который преобразуется в int(*)[5] при использовании в выражении. Таким образом, x [0] является lvalue типа int[5] (первая 5-элементная "строка" ), которая снова преобразуется в int* и разыменовывается ее первым элементом.

*x оценивается по тем же строкам, за исключением того, что первое разыменование выполняется со звездочкой (в отличие от индексации), и нет второго разыменования, поэтому мы заканчиваем lvalue типа int[5], который передан в printf как указатель на его первый элемент.

Ответ 2

Массивы, используемые в качестве аргументов для функций, распадаются на указатели на первый элемент массива. При этом тип объекта, который x распадается, является указателем на первый подматрица, который является указателем на массив из int или в основном int (*)[5]. Когда вы вызываете printf("%d\n",*x), вы не подаете целочисленное значение в printf, а скорее указатель на первый под-массив x. Поскольку этот субмассив также распадается на указатель на первый элемент под-массива, вы можете сделать **x для разыменования этого последующего указателя и получить в первом элементе первого подматрица x. Это фактически то же самое, что и *x[0], которое по приоритету оператора будет индексироваться в первый под-массив x, а затем разыменовать указатель на первый элемент подматрицы, в который будет впадать первый подматрица.

Ответ 3

Из-за типа *x есть указатель на массив из 5 ints. Итак, вам нужно еще одно разыменование, чтобы получить первый элемент

PS:

#include <typeinfo>
#include <iostream>

typedef int arr[5]; // can't compile if put arr[4] here
void foo(arr& x)
{
}

int main()
{
  int x[3][5]={{1,2,10,4,5},{6,7,1,9,10},{11,12,13,14,15}};

  std::cout << typeid(*x).name() << std::endl;// output: int [5]

  foo(x[0]);
  return 0;
}

Ответ 4

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