Мои комментарии о том, почему void *ptr
, нельзя выполнить адресную арифметику. Предупреждение, длинные бессвязные :).
В общем когда вы сделать PTR арифметическая как
ptr = ptr + N ;
Интерпретация с помощью C является выполнение следующих эквивалентных целочисленной арифметики (Infact компилятор будет производить сборку кода, эквивалентный ниже целочисленной арифметики)
ptr = ptr + N * sizeof (typeof (* N));
Следовательно, для получения кода компилятор должен знать тип (* N). typeof (* N) здесь означает, что тип переменной «ptr» указывает на. (typeof не является стандартной конструкцией c, она покупается здесь для простого объяснения).
Возьмите, например,
int x ; // Assume x is at addesss 1000
int *ptr = &x ; // ptr has a value of 1000
Тогда PTR = PTR + 1;
бы PTR в 1004 во время выполнения (предполагается, что размер Int составляет 4 байта)
Пояснение-1: Приведенные выше утверждение означает, что PTR должен содержать адрес следующей переменной целочисленного после PTR. Поскольку ptr указывает на x, который находится по адресу 1000, следующая целочисленная переменная после 1000 будет равна 1004. Таким образом, ptr будет равен 1004.
Пояснение-2 Это также синхронизируется с интерпретацией ptr = ptr + N эквивалентно целому числу arithmeitc
ptr = ptr + N* sizeof (typeof(*N)) ; // typeof (*N)->int
// => 1000 + 1 *sizeof (typeof (int))
// => 1004
Резюмируя для операции PTR Arith
ptr = ptr + N ;
компилятор выдает эквивалентный код сборки как
р тр = PTR + N * SizeOf (TypeOf (* N)) // компилятор должен TYPEOF (* N)
Поэтому компилятор должен знать, что это тип данных, который PTR указывает на.
Теперь рассмотрим
void foo (int type, void *ptr) {
ptr = ptr + 2 ;
}
f2() {
int x ;
char c ;
f1(&x) ;
f1(&c);
}
Пустота * PTR является родовым PTR, указывающий на addresss.Когда вызывается с f1 (x), ptr указывает на адрес целого числа, при вызове с f1 (& c) он указывает на адрес символа. Поэтому во время компиляции компилятор не может определить, что такое typeof (* ptr). (в одном случае это целое число, а другое - символ). Следовательно, компилятор не может сгенерировать код для ptr = ptr + n;
Таким образом, вам нужно будет отличить ptr от определенного типа, а затем выполнить арифметическую операцию.
Надеюсь, это поможет.
Атрибут указателя на тип 'void *' определяется его недопустимым стандартом (поскольку размер типа 'void' (например,' sizeof (void) ') не определен). Это расширение, позволяющее ему НКА. (Расширение установлено на 1 размер 'void') – BLUEPIXY
« У человека есть код »- извините, но никто не может помочь –