c - язык инициализации глобальной переменной внутри main (), вне main () - PullRequest
0 голосов
/ 22 января 2020
  1. внутри main () - без ошибок

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 4
    
    typedef struct
    {
        int vertex;
        int **matrix;
    }graph;
    graph ygraph={.vertex=MAX};
    
    int main()
    {
        ygraph.matrix=(int**)malloc(sizeof(int)*MAX*MAX);
        return 0;
    }
    
  2. снаружи main () - ошибка //

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 4
    
    typedef struct
    {
        int vertex;
        int **matrix;
    }graph;
    graph ygraph={.vertex=MAX};
    ygraph.matrix=(int**)malloc(sizeof(int)*MAX*MAX);
    
    int main()
    {
        return 0;
    }    
    

в чем разница ...? Я не могу инициализировать глобальную переменную вне main ()? Я думаю, что оба не имеют ошибки ...

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Цитирование отрывка из ссылки C на cppreference.com:

При инициализации объекта stati c или продолжительности локального хранилища потока каждое выражение в инициализаторе должно быть константное выражение или строковый литерал.

Инициализаторы для объектов stati c (например, graph) должны быть известны во время компиляции, поскольку инициализированная память для этих переменных находится в объектном файле, сгенерированном компилятором. Как таковые, они не могут содержать вызовы функций.

$ cat a.c
int a = 7;
int b = 8;
int c = 9;

$ gcc -c a.c

$ objdump -t -s -j .data a.o

a.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 g     O .data  0000000000000004 a
0000000000000004 g     O .data  0000000000000004 b
0000000000000008 g     O .data  0000000000000004 c


Contents of section .data:
 0000 07000000 08000000 09000000           ............

Назначения в функциях оцениваются во время вызова функции (если вообще) и, следовательно, могут содержать вызовы функций.

1 голос
/ 22 января 2020

Stati c объекты Инициализаторы должны быть константными выражениями . Вызов функции не один, если они

Ваш mallo c также неверен. Если вы используете двойной указатель, вам нужно чтобы mallo c указатели на int, а затем для каждого выделенного указателя пространство для целых чисел

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

int *foo(size_t size)
{
    int *x = malloc(size * sizeof(*x));
    // some ops
    return x;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...