2014-01-31 2 views
3

в следующем коде:Пытаясь понять нотации массива

int main() 
{ 

    int i = 15, j = 1; 
    int *a[] = {&i, &j}; 
    printf("%d", (*a)[0]); 
    return 0; 

} 

выход (*a)[0] является 15 (значение I), однако, когда я попытался проверить (*a)[1] это дает значение мусора. Я ожидал бы, что одно и то же выражение должно работать для всех записей в массиве, однако оно работает только для первого элемента в массиве.

+2

'* a 'is' & i', '(* a) [0]' is '* (& i + 0)', '(* a) [1]' is '* (& i + 1)' это UB. – BLUEPIXY

+1

(* a) дает вам первый элемент массива (тот же, что и [0]), следующий [0] дает int по этому адресу. Хотя (* a) [1] является int по адресу после адреса i – Micka

ответ

8

Здесь вы объявили массив указателей. Сначала вы должны знать различное представление массива. Как вычисляется [i]? a дает вам базовый адрес массива.

a[ i ] = *(a+i) 
(*a)[0] = *(*a+0) 
(*a)[1] = *(*a+1) 

Thus the value of (*a)[0] = *(address of i + 0) = Value of i 
And the value of (*a)[1] = *(address of i + 1) = value at the location of (add of i + 2) i.e. a garbage value. 

В вышеуказанных проблемах вы можете получить правильное значение, если вы используете * (а [0]) и * (а [1]).

+1

+ 1.хорошее объяснение –

+0

Как вы видите '* (адрес i + 1)' это значение в месте (добавление i + 2) "? Откуда взялись эти 2? Вы предполагаете, что размер 'int' равен 2, поэтому вы имеете в виду 2 байта? –

+0

@EricPostpischil, да я принимаю sizeof (int) = 2. Вот почему я добавил 2. – Rahul

3

Вы не должны использовать (*a)[0] и (*a)[1] в первую очередь. Вы должны попробовать *(a[0]) и *(a[1]).

У вас есть массив int * 's a. a имеет два элемента, a[0] и a[1]. a[0] является &i и a[1] является &j. Поэтому *(a[0]) - i и *(a[1]) - j.

+2

Это не объясняет, почему, что является основным вопросом. –

+0

Не нужно использовать сложный синтаксис. '* a [0]' достаточно. – user694733

+0

Да, потому что * (a [0]) настолько сложна и нечитаема. –

2

Я думаю, что вы смущены над семантикой указателей здесь (много людей)

int x[2]; // an array of two ints 
int *y[2]; // an array of two int pointers. 

typeof(x[0]) == int // this isn't really valid C code 
typeof(*x) == int // arrays are (pretty much) pointers 

typeof(y[0]) == int* 
typeof(*y) == int* 
typeof(**y) == int 
+0

Массивы - это * не * указатели. В некоторых случаях они будут распадаться на указатели. – user694733

+0

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

+0

... и способ 'sizeof' работает на них и способ распределения памяти для них. Указатели всегда хранятся в адресе памяти, массив всегда хранит данные. С ними нет ничего общего, кроме синтаксического сахара. – user694733

1

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

упс, вы должны присвоить имя массива в указатель, вы не разрешается увеличивать имя массива этим ++, так как его не переменной,

int **s = a; 
(*++s)[0] this will print 1. 

, так как точки имени массива в первый элемент, это увеличит его на 1 (теперь он укажет на второй элемент), затем разыграет его и возьмет элемент [0] в памяти, на которую указывает (* ++ a)

Смежные вопросы