2015-10-15 2 views
1

В моем заголовке я объявил несколько переменных как @property (nonatomic) NSInteger *soldWindows; и использовал их для отслеживания отсчетов, увеличиваясь с _soldWindows++;. Результат последовательно выходил в 8 раз больше, чем должен быть. Я выяснил, что моя проблема заключалась в объявлении его как указателя, поэтому я изменил его на @property (nonatomic) NSInteger soldWindows;, который решил мою проблему.Почему указатель на NSInteger умножает значение на 8?

Мой вопрос: если он просто хранит адрес памяти, почему целочисленное значение масштабируется на 8 вместо произвольного адреса?

+1

Помимо правильного ответа ChrisCM, похоже, нет особой причины, почему вы используете NSInteger. Поэтому просто используйте int intead. – fishinear

+1

@fishinear В зависимости от цели 'NSInteger' является typedef для' int' или 'long'. Итак, в чем преимущество перехода на «int»? –

+3

@fishinear Плохой совет. – rmaddy

ответ

5

Указатель указывает на место в памяти. Когда вы увеличиваете указатель таким образом, вы увеличиваете значение указателя, указывая на новое место в памяти. Учитывая это, вы можете использовать арифметику указателя для итерации через последовательные элементы в массиве, путем разыменования инкрементного указателя. Таким образом, вы не увеличиваете на 1, а скорее на размер вашего указателя. NSInteger - это не более 64 или 32 бит int, в зависимости от платформы. В этом случае это, по-видимому, 64 бита, что составляет 8 байтов. Это то, откуда вышло 8-битное «масштабирование».

Заключение: исправление исправлено!

+0

Ваши правильные объяснения. Пример довольно запутанный (и - если подразумевается как действительный код - неправильный). –

+1

«Когда [...] вы увеличиваете место в памяти, которое указывает на« звучит так, как указатель увеличивается, а не указатель. Это было бы неправильно. Адрес в указателе увеличивается, а не место в памяти. –

0

Я объявил несколько переменных как [...] NSInteger * soldWindows; и использовали их для отслеживания подсчетов.

Вы неправильно используете понятие указателя. В C указатель - это адрес объекта в памяти. В вашем случае использования нет объекта, на который указывает - только адрес, который указывает на никуда.

Хотя это не проблема, если вы не разыгрываете указатель, это все еще запутывает (и никоим образом не помогает). Простое целое число (например, int или NSInteger) - лучший выбор.

Почему значение целочисленного значения составляет 8?

Причина этого называется указатель арифметический. Каждый указатель C имеет тип. Тип описывает объект в памяти, где указатель содержит адрес. Когда вы увеличиваете указатель, компилятор фактически добавляет размер объекта к указателю, так что он указывает на объект сразу после предыдущего.

Размер NSInteger (в 64 бит iOS) равен 64 бит = 8 байт. Вот почему приращение NSInteger * фактически добавляет к нему 8.

+1

@ChrisCM Я предполагаю, что OP использует указатель для своего значения (возможно, инициализируется значением 'NULL' или около того). Он видит значение приращения с шагом 8, поэтому он использует значение указателя как интегральное скалярное значение. Я не думаю, что он когда-либо на самом деле указывает на что-то (кроме случайного адреса в виртуальной памяти, вот что я имел в виду «ничего»). Выделение указателя было бы неопределенным поведением. –