Давайте возьмем два следующих указателя:
char poBuffChar[100];
Case 1:
(void *)&poBuffChar[10];
Case 2:
(void*)(&poBuffChar)[10];
Если я правильно понял, в первом случае я выбираю член моего буфера символов, выбираю указатель на этот член и конвертирую этот указатель (который является char*
) в указатель на void. Во втором случае, ну, на самом деле я не уверен, что это делает xD. Но имеет значение то, что первая ситуация дает мне "предупреждение: разыменование void *" (или что-то подобное), в то время как второй случай не дает мне никаких предупреждений.
Проблема в том, что, перейдя от случая 1 к 2, я имею дело с теми же результатами? То есть, делает ли второй код доступ к тем же данным, что и первый?
РЕДАКТИРОВАТЬ
Ну, похоже, есть разница: запуск кода со вторым случаем просто вызвал ошибку сегментации. Но некоторые разъяснения по-прежнему требуются (а также некоторое предложение о том, как избавиться от предупреждения теперь, когда я знаю, что первое доступное решение не работает)
&poBuffChar[10]
имеет pointer to char
и указывает на 11-й элемент массива poBuffChar
.
(&poBuffChar)[10]
- это 11th element of an array of (arrays of chars of size 100)
, первым элементом которого является poBuffChar
(весь массив). Этот тип элемента представляет собой array of char of size 100
, как poBuffChar
сам poBuffChar
. Он указывает 10 * 100 = 1000
байт за начало массива.
(&poBuffChar)[10]
имеет тип «массив символов размером 100» (а именно 10-й элемент массива массивов, на который указывает &poBuffChar
); который в большинстве случаев распадается на указатель на свой первый элемент, так что он становится указателем на символ, во многом как голый poBuffChar. Думайте о &
и []
как об обратных операциях.
poBuffChar
,&poBuffChar
,&poBuffChar[10]
и(&poBuffChar)[10]
чтобы увидеть разницу