Проблема с массивом указателей - PullRequest
3 голосов
/ 14 февраля 2009

Я попробовал этот пример массива указателей. Я получаю сообщение об ошибке "Неверная инициализация в основной функции"

int main()
{
    int a[]={1,2,3,4,5};
    int b[]={1,2,3,4,5};
    int c[]={1,2,3,4,5};
    int *p[3]={a,b,c};
    int i;
    clrscr();
    for(i=0;i<3;i++)
        printf("%d - %u\n",*p[i],p[i]);
    getch();
}

Если я использую static int вместо int в объявлениях массива, он работает нормально Может ли кто-нибудь сказать мне эффект статики здесь. Большое спасибо.

Ответы [ 4 ]

5 голосов
/ 14 февраля 2009

В gcc вы увидите предупреждения об этом, если вы используете -педантичный флаг .

Но это, по-видимому, то, что изменилось в стандарте, в C90 говорится:

Все выражения в инициализаторе для объекта, который имеет статический продолжительность хранения или в списке инициализатора для объекта, который имеет Тип агрегата или объединения должен быть константным выражением

и это было запрещено, поскольку массив p является агрегатным типом, но в C99 мы имеем:

Все выражения в инициализаторе для объекта, который имеет статический продолжительность хранения должна быть константными выражениями или строковыми литералами.

4 голосов
/ 14 февраля 2009

Это прекрасно компилируется с gcc и gcc -ansi. Однако gcc -ansi -pedantic выдает следующее предупреждение:

blackjack.c: In function ‘main’:
blackjack.c:8: warning: initializer element is not computable at load time
blackjack.c:8: warning: initializer element is not computable at load time
blackjack.c:8: warning: initializer element is not computable at load time

Принимая во внимание, что строка 8:

int *p[3]={a,b,c};

На мой взгляд, проблема в том, что в то время, когда a, b и c будут храниться в p, они еще не существуют. Это потому, что они будут помещены в стек, а положение в стеке зависит от того, что находится за пределами функции. Чтобы пояснить это, «время загрузки» означает время загрузки программы в память, а не время, когда она уже выполняется. (Не спрашивайте меня, почему / как это все равно работает)

0 голосов
/ 25 ноября 2011

Правила довольно просты. Для статических объектов список инициализации должен быть постоянным. Нет таких ограничений для элементов, которым будет выделено место в стеке. Это также кажется логичным, поскольку статические объекты должны быть записаны в разделе данных, а компилятор должен иметь возможность заранее разрешать их значения. В стеке выделяется память, когда вызывается рассматриваемая функция (основная). Никаких проблем нет. Я не знаю, почему на turbo-c происходит противоположное поведение. на gcc это происходит: (при компиляции с gcc -Wall prog.c

        int *p[]={a,b,c} //works fine
        static int *p[]={a,b,c} //oops blunder
0 голосов
/ 14 февраля 2009

попробовать: printf ("% d -% u \ n", * (p [i]), p [i]);

хотя у меня такое ощущение, что вы пытаетесь сделать что-то более похожее на:

int a[]={1,2,3,4,5};
int b[]={1,2,3,4,5};
int c[]={1,2,3,4,5};
int *p[3]={a,b,c};
int i;
clrscr();
for(i=0;i<sizeof(p)/sizeof(int*);i++) {
    for (int j =0; j < sizeof(a)/sizeof(int); j++) {
        printf("%d - %u\n",(p[i])[j],p[i]);
    }
}
getch();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...