2016-03-07 11 views
36

To jest mój kod:Dlaczego m [1] - m [0] zwraca 3, gdzie m jest macierzą 3x3?

int m[][3] = { 
       { 0 , 1 , 2 }, 
       { 10, 11, 12 }, 
       { 20, 21, 22 } 
      }; 
printf("%d %d\n", m[1] - m[0], m[1][0] - m[0][0]); 

I dlaczego

m[1] - m[0] 

powrotną 3? Wiem, dlaczego drugie wyrażenie powróciłoby 10, ale jedno nie wydaje mi się logiczne.

+2

'm [1]' to 'i m [1] [0]' i tak dalej. – immibis

+0

Technicznie "m" nie jest macierzą 3x3, ale tablicą tablic. – HelloGoodbye

+0

Nie ma na to odpowiedzi, ale 'm [0]' i 'm [1]' to * tablice * (nie wskaźniki). Wartość wskaźnika jest tworzona, gdy tablica jest używana jako operand operatora '-', który wskazuje na pierwszy element odpowiedniej tablicy. –

Odpowiedz

55

W kodzie:

m[1] - m[0] 

oznacza odejmowanie wskaźnik, który daje różnicę dwóch wskaźników opartych na typu. W tym przypadku oba wskaźniki są zróżnicowane od 3 elementów, więc wynik jest 3.

Cytując standardu C11, rozdział §6.5.6

Gdy dwa wskaźniki są odejmowane, oba elementy powinny wskazywać tego samego obiektu tablicowego, lub jeden za ostatnim elementem obiektu tablicy; wynikiem jest różnica dolnych indeksów dwóch elementów tablicy. [...]

i

[...] Innymi słowy, jeśli wyrażenia P i Q punkt do, odpowiednio, i ji -tego -tego elementy się obiekt tablicy, wyrażenie (P)-(Q) ma wartość i−j pod warunkiem, że wartość mieści się w obiekcie typu ptrdiff_t. [....]

Aby lepiej uzmysłowić, proszę zobaczyć na poniższym obrazie

enter image description here

Tutaj s jest dwuwymiarowa tablica, zdefiniowane jako s[4][2]. Biorąc pod uwagę typ danych dla użytkowników macierzy 2-bajtowych, należy postępować zgodnie z elementami (indeks) i odpowiednią lokalizacją pamięci (arbitralna). Pozwoli to lepiej zrozumieć, jak faktycznie w pamięci elementy tablicy są ciągłe.

Tak, jak na reprezentację, s[0] i s[1] są zróżnicowane przez dwóch elementów, s[0][0] i s[0][1]. W związku z tym, s[1] - s[0] da wynik 2.

+0

Dziękuję! Pomogło mi to zrozumieć. Zdecydowanie przejdę ten test teraz :) – Martacus

+0

@Martacus To jest pewność !! Powodzenia :) –

+1

Zauważ, że 'm [1]' i 'm [0]' są tablicami. Wskaźniki, które opisujesz, są wynikiem "rozpadu". –

35

Ponieważ "różnica" między m[1] i m[0] jest trzy elementy.

To może być łatwiejszy do zrozumienia, jeśli spojrzeć na to w ten sposób

 
m[0]       m[1]       m[2] 
|        |        | 
v        v        v 
+---------+---------+---------+---------+---------+---------+---------+---------+---------+ 
| m[0][0] | m[0][1] | m[0][2] | m[1][0] | m[1][1] | m[1][2] | m[2][0] | m[2][1] | m[2][2] | 
+---------+---------+---------+---------+---------+---------+---------+---------+---------+

różnica między m[1] i m[0] jest trzy elementy m[0][0], m[0][1] i m[0][2].

+0

Ach tak, to również wyjaśnia to, dzięki! Rozumiem to teraz haha. – Martacus

+0

W rzeczywistości, 'm [0]' będzie technicznie wskazywać to samo miejsce co 'm [0] [0]' jeśli spojrzysz na to pod względem technicznym. Użycie '& m [0]' i '& m [0] [0]' udowodni to; tablice mają podstawę i przesunięcie, więc zarówno 'm [0]' jak i 'm [0] [0]' mają zero przesunięcia i adres równy adresowi podstawowemu matixa. – cst1992

+0

Próbuję powiedzieć, że powinieneś wskazać 'm [0]' na środek komórki zawierającej 'm [0] [0]', a nie początek. To samo dotyczy 'm [1]' i 'm [2]'. – cst1992