Использование пустого указателя на массив - PullRequest
5 голосов
/ 11 января 2012

Я просто пытался использовать пустой указатель на массив целых чисел, я пытался посмотреть, смогу ли я напечатать массив обратно, приведя его обратно в 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

Почему это не pinting элементы массива a [] т.е. 1,2,3,4?

Ответы [ 4 ]

12 голосов
/ 11 января 2012

Вам нужно разыграть arr перед добавлением j.Вот минимальное исправление:

x = *(((int *)arr)+j);

, но я думаю, что будет понятнее написать:

x = ((int *)arr)[j];
5 голосов
/ 11 января 2012

Вы делаете арифметику указателя на void *, что недопустимо в C.

В GNU C (C с расширениями gcc) это действительно разрешено, и sizeof (void) считается равным 1.

http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html

"Операции сложения и вычитания поддерживаются в указателях на void и на указатели на функции. Это делается путем обработки размера void или функции как 1. "

1 голос
/ 11 января 2012

Стандарт C не определяет поведение для арифметики void *, поэтому вам нужно привести void * к другому типу указателя first , прежде чем выполнять арифметику с ним.

Некоторые компиляторы [как расширение] обрабатывают арифметику указателей void * так же, как char *, поэтому каждый & lsquo; + 1 & rsquo; увеличит адрес только на 1, а не на размер указанного объекта. Это не стандартизировано, поэтому вы не можете полагаться на это поведение.

1 голос
/ 11 января 2012

Вы не должны добавлять числа в указатели void. брось это раньше. (x = *((int *)arr+j);)

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

если я правильно помню, добавление в void * недопустимо, но некоторые компиляторы добавляют точное число в байтах (например, это char *). `

...