#include<stdio.h>
void main()
{
int a[] = { 1, 2, 3, 4 };
int b[] = { 5, 6, 7 };
int *p[2];
p[0] = a;
p[1] = &b + 1;
printf("%d\n%d", &p[1][0], p[0][1]);
}
Здесь p
представляет собой 1d массив указателей, то почему массив 2d используется в инструкции printf
. Также выход равен 1 2
.
Индексный оператор []
определен для выражений указателя, а также выражений массива (которые неявно преобразуются в выражения указателя до применения индекса).
Выражение a[i]
оценивается как *(a + i)
; a
- указатель, a + i
- адрес i
-го элемента массива (арифметика указателя основана на указанном типе; если a
указывает на int
, то a + i
задает адрес i
'th int
следуя указанию a
).
Поэтому, учитывая ваш массив указателей:
int *p[2];
выражение p[0]
имеет тип указателя, поэтому вы можете добавить смещение и разыменовать результат: *(p[0] + 1)
, что совпадает с записью p[0][1]
.
Здесь p является 1darray указателей
Да, и вы можете использовать ptr[index]
оператор ptr[index]
с указателями, который эквивалентен *(ptr + index)
Таким образом, p[1][0]
совпадает с *(p[1] + 0)
который совпадает с *(p[1])
Также ваш код не компилируется по нескольким причинам, включая void main()
Простой пример для иллюстрации:
int main()
{
const char *hello = "hello";
const char *world = "world";
const char *array[2] = {hello, world};
char e = hello[1]; // char e now contains 'e'
e = array[0][1]; // same thing as previous line
char r = world[2]; // char r now contains 'r'
r = array[1][2]; // same thing as previous line
}
operator[]
к указателю. Это не значит, что указатель является массивом.