2014-01-31 3 views
0

У меня есть загадка здесь:Почему указателю может быть присвоено значение?

int *a=*b; 
a[1]=3; 
a[2]=5 

а является массив указателей и присваивается значение, б. В моем понимании, [] должен быть адресом, поэтому почему на практике мы можем присвоить значение указателю (в данном случае a [])? Все объясняют?

+1

'a [1]' точно так же, как писать '* (a + 1)'. Очевидно, вы можете написать '* a = 3', так как' a' является 'int *', поэтому вы также можете написать '* (a + 1) = 3', поэтому вы также можете написать' a [1] = 3'. – Jon

+1

'a' не является массивом указателей. 'a' является указателем. – musicmatze

+0

Что такое * (a + 1)? вы имеете в виду * a [1]? – Wei

ответ

2

Я предполагаю, что это C или подмножество C Objective C/C++, поскольку C +, Java, PHP и другие языки C-типа не используют указатели.

Используйте теги кода и один оператор в строке.

Заявление

int *a = *b; 

Создает как указатель на Int. Не указатель на указатель на int, указатель на int.

Затем он устанавливает текущий адрес в a как разыменование b, независимо от того, что b. Вы не указали объявление b. Если b не имеет тип int **, вы должны получить предупреждение о компиляторе.

a не является указательным массивом. a - указатель на int. Он может указывать на один int, или его можно указать на массив из int. Компилятор не может отличить разницу.

Если b имеет тип int ** или указатель на указатель на int, то ваше заявление разделяет один из этих указателей и делает точку в первом подматрице внутри b.

Код

a[1] = 3; 

предполагает, что указатель на массив целых чисел, так как компилятор не может делать какие-либо проверки диапазона, он пытается индексировать в массив и сохранить значение в второй int в блоке памяти, на который указывает точка. Если a не указывает на блок памяти, достаточно большой, чтобы содержать как минимум 2 целых числа, этот оператор может сбой на современном компьютере с использованием защищенной памяти, он также может просто перезаписать последующую память.

As @EdS. отмечает в комментарии ниже, это, как известно, в бизнесе, как

«неопределенное поведение»

Если вы собираетесь использовать указатель C, как это бремя лежит на вас, чтобы убедиться, что это на самом деле указывает на действительную память, и если вы собираетесь использовать указатель, как если бы он был массивом, вы должны быть на вас, чтобы убедиться, что вы не превышаете границы памяти, на которые указывает указатель.

+0

Это все хорошо, но на самом деле должно быть хотя бы одно упоминание термина * неопределенное поведение *. –

1

Но давайте ответим на ваш вопрос:

Вот я иду шаг за шагом через код (хотя я изменил его немного с целью примера), и показать, что она делает в подделке памяти, так что вы получите идею:

int b[4]; 

здесь выделить 4 ячейки памяти и сделать b метку для ячейки памяти, содержащей адрес первой ячейки памяти:

variable  b      
address  0x1 0x2 0x3 0x4 0x5 
memory  [0x2] [ | | | ] 

затем:

int* a = b; 

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

variable  b      a 
address  0x1 0x2 0x3 0x4 0x5 0x6 
memory  [0x2] [ | | | ] [0x2] 

затем:

a[1]=3; 
a[2]=5; 

вы устанавливаете значение для a[1], который переводит к *(a+1) с использованием указателей арифметика, которые представляет собой адрес адреса 0x2 + 1, то есть содержание 0x3. То же самое с a[2]. Память сейчас:

variable  b      a 
address  0x1 0x2 0x3 0x4 0x5 0x6 
memory  [0x2] [ | 3| 5| ] [0x2] 

Надеюсь, что этот ASCII станет более понятным, как работают массивы! И вы обязательно должны прочитать Kernighan and Ritchie book, а также this documentation, которые оба очень хорошо объясняют, как управляется вся память, и арифметика указателей и массивы.

+0

NB: это то, что происходит с ответами при ответе только после чтения таких вещей, как [это] (http://www.theatlantic.com/technology/archive/2014/01/the-lost-ancestors-of-ascii-art/ 283445 /) – zmo

+0

Спасибо.Это действительно помогает. – Wei

+0

и действительно, прочитайте книгу и онлайн-документацию, они должны действительно помочь вам! – zmo

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