LINUX.ORG.RU

Смещение указателя по массиву интов

 


0

1
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
void *pointer = &a;

for(int i=0; i<10; i++)
	std::cout << *((int *)pointer + i) << std::endl;

Есть такой код, который пробегается по массиву интов через указатель типа void. Код работает.

Вопрос такой - почему достаточно увеличивать pointer на 1, чтобы перейти к следующему элементу?

Старший товарищ предлагал увеличивать на i * sizeof(int) и это выглядит разумным, но не работает.

Старший товарищ предлагал увеличивать на i * sizeof(int) и это выглядит разумным, но не работает.

Старший товарищ по детскому саду?

*((int *)pointer + i) это то же самое что ((int *)pointer)[i]

vvvvvvvv ()
Последнее исправление: vvvvvvvv (всего исправлений: 1)

Потому что ptr + i прибавляет к указателю i * sizeof(decltype(*ptr)). Домножать вручную на sizeof(int) имело бы смысл, если бы оперировали массивом int’ов как массивом байт, например, приводя указатель к char*.

Siborgium ★★ ()

Допустим есть указатель A его sizeof(A) равен 4 а адрес на который ссылается указатель равен 12 мы делаем A++ теперь этот адрес равен 16. Иди почитай что такое адрессная арифметика вней один это не число один, а один раз размером с sizeof(type). То есть (далее просто абстракция для примера что-бы понятно было) A=A+4 это A+=sizeof(A)+sizeof(A)+sizeof(A)+sizeof(A) или A+=4+4+4+4 или A+=32. То есть если размер типа четыре то минус один это минус четыре, плюс один это плюс четыре, минус два это минус восемь. Сечёшь?

anonymous ()
Ответ на: комментарий от lvmuser

Я тебе помог выше комментом понять. Но этот анон прав. Сейчас ты тупишь и ты явно не читал про адрессную арифметику, без это нельзя трогать указатели. Это всё равно что сеть в машину и рулить коробкой передач. А газ выкручивать рулём ну тапа как вентилем. Вот твой пост так воспринимается. Понимаешь? Так что не обижайся. Что есть то есть. Поди загугли про адресную арифметику, кофейку ведро налей с печеньем и вникай, чтобы таких факапов не было, а то так и будут над тобой прикалываться. Просто если трогать указатели то как бы надо знать как они работают. Всё удачи.

anonymous ()

Не ради стеба, а серьезно: c/c++ с наскока не выучить, почему ты не хочешь прочитать хотя бы книгу по основам? Если хочешь в профессию c++ (или c) программиста, как ты собираешься работать, когда тебе лень книгу прочесть. А чтобы знать на нормальном уровне (скажем миддл), нужно постоянно книги читать и документацию и стандарт и читать код разных либ, чтобы смотреть как принято делать.

rumgot ★★★★★ ()
Ответ на: комментарий от rumgot

Да какой тут с++ тут просто пока что фундоментальные вещи надо подтянуть. А то указатели мимо ушей пропустят и сразу начинают лямбды, монады, исключения, инкапсуляции и в прочее прочее вникать. Ничё. Ему сказали что не так, будет желание разберётся, не будет ну знает это не его.

anonymous ()
Ответ на: комментарий от AntonI

Просто он скромно задал вопрос. Без ПАМАГИТИ! чУВО ЗА бред! Пачамууу. Срочна покажите как надо! И т.п. Если первый раз касаться указателей то они и в правду не очевидны. Можно войти в положение, вот я и вошёл.

P.S.

вот я и вошёл.

Я вот за ранее говорю, Владимир молчи нафиг! Даже не думай! Всё :D

anonymous ()

Потому что *((int *)pointer + i) = (((int *)pointer) + i), а не *((int *)pointer + i) = *((int *)(pointer + i))

Если расставить скобки как во втором варианте, то действительно нужно будет увеличивать на i * sizeof(int).

// не понимаю, откуда столько токсичности в обсуждении

Kuzy ★★★ ()
Ответ на: комментарий от Kuzy

Если расставить скобки как во втором варианте, то действительно нужно будет увеличивать на i * sizeof(int).

Конечно нет. Для void* не определена адресная арифметика:

error: arithmetic on a pointer to void

https://gcc.godbolt.org/z/avTdr7

fsb4000 ★★★★ ()
Ответ на: комментарий от Kuzy

Если расставить скобки как во втором варианте, то действительно нужно будет увеличивать на i * sizeof(int).

Если расставить скобки как во втором варианте, то не скомпилируется.

anonymous ()
Ответ на: комментарий от anonymous

i * sizeof(int) это оправданно только если ты почему то int массив скастовал как char, но перемещаться по нему хочешь как по int.

Если ты скастовал к char*, то «перемещаться» и использованием такого указателя это UB.

anonymous ()

в c++ давно уже все по другому... почему старший товарищ не знает про initializer_list?!

auto a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(auto v : a)
   std::cout << v << std::endl;

зачем какие то смещения?

anonymous2 ★★★★ ()
Последнее исправление: anonymous2 (всего исправлений: 1)
Ответ на: комментарий от BackDoorLover

Любишь писать на perl?

То я специально для тебя отсылку сделал, объединил (хотя, в данном случае скорее разъединил), так сказать, два твоих увлечения в одно.

anonymous ()
Ответ на: комментарий от anonymous

Вот он, истинный уровень ненавистников C, дамы и господа.

А что не так? Запятая перед «на подобии Си» пропущена? И почему ненавистников? Человек же требует писать только на Си, а не «на мусорных говноязычках, являющихся подобием Си»?

monk ★★★★★ ()
Ответ на: комментарий от anonymous

ТСу. Тебе по английски уже зацитировали, но ты мог бы почитать и по-русски. Керниган и Ричи, глава 5.4 «Адресная арифметика»:

Если P является указателем, то каков бы ни был сорт объекта, на который он указывает, операция P++ увеличивает P так, что он указывает на следующий элемент набора этих объектов, а операция P +=I увеличивает P так, чтобы он указывал на элемент, отстоящий на I элементов от текущего элемента. Эти и аналогичные конструкции представляют собой самые простые и самые распространенные формы арифметики указателей или адресной арифметики.

Дальше сам.

Да, это книжка по C, но на таком уровне C++ — надмножество C, поэтому написанное справедливо и для него. Вообще, настоятельно советую K&R читать ДО Страуструпа.

hobbit ★★★★★ ()
Последнее исправление: hobbit (всего исправлений: 1)