Используя Void указатель на массив
Я просто пытался использовать указатель void на целочисленный массив, я пытался увидеть, могу ли я распечатать массив обратно, приведя его обратно в int. Но это дает мне некоторую случайную ценность. Можете ли вы сказать мне, где я ошибаюсь?
#include<stdio.h>
#include<stdlib.h>
int main(){
int a[5];
int x;
int j;
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
void *arr=a;
for(j=0;j<4;j++){
x = *(int *)(arr+j);
printf("%d",x);
}
return 0;
}
Вывод такой:
133554432131072512
Почему он не закрепляет элементы массива a [], то есть 1,2,3,4 ?
4 ответа:
Вам нужно бросить
arr
Перед добавлениемj
. Вот минимальное исправление:x = *(((int *)arr)+j);
Но я думаю, что яснее написать:
x = ((int *)arr)[j];
Вы выполняете арифметику указателя на
void *
, которая недопустима в C.В GNU C (C с расширениями gcc) это действительно разрешено, и
sizeof (void)
считается 1.Http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
" операции сложения и вычитания поддерживаются указателями на void и по указателям на функции. Это делается путем обработки размера a void или функции как 1."
Не следует добавлять числа к пустым указателям. брось его раньше. (
x = *((int *)arr+j);
)Когда вы добавляете число к указателю, компилятор умножает это число на размер указываемого типа, поэтому, если вы добавляете число к указателю неправильного типа, вы получите неправильный результат.
Если я правильно помню, add to void * является незаконным, но некоторые компиляторы добавляют точное число в байтах (например, char*). '
Стандарт C не определяет поведение для арифметики
void *
, поэтому вам нужно сначала привести вашvoid *
к другому типу указателя , прежде чем делать арифметику с ним.Некоторые компиляторы[в качестве расширения] обрабатывают арифметику указателя
void *
так же, как иchar *
, поэтому каждый ‘+1’ будет только увеличивать адрес на 1, а не на размер объекта, на который указывают. Однако это не стандартизировано, поэтому вы не можете полагаться на это поведение.