2016-11-14 2 views
5

Я нашел интересный факт, и я не понял, как это работает.
Следующий фрагмент кода просто отлично работает.Размер массива с константой в C

#include <stdio.h> 
int main(){ 
    const int size = 10; 
    int sampleArray[size]; 
    typedef char String [size]; 
    return 0; 
} 

Затем я попытался использовать только и только постоянную переменную с глобальным охватом, и все равно прекрасно.

#include <stdio.h> 
const int size = 10; 
int main(){ 
    int sampleArray[size]; 
    typedef char String [size]; 
    return 0; 
} 


Но, если я меняю масштаб массивов на глобальные, а также, я получил следующее:

error: variably modified ‘sampleArray’ at file scope

#include <stdio.h> 
const int size = 10; 
int sampleArray[size]; 
typedef char String [size]; 
int main(){ 
    return 0; 
} 

И я не понимаю! Если бы я заменил переменную const для ex. до #define все будет хорошо.
Я знаю, что переменная #define предварительно обработана, и насколько я знаю, константная переменная доступна только для чтения. Но что делает глобальный охват в конце концов?

Я не понимаю, в чем проблема с третьим куском кода, если второй - все в порядке.

+3

Некоторые детали: C имеет объекты 'const', но не _constant_. Хотя 'const', кажется, подразумевает _constant_, объект' const' не _constant_, но скорее как «этот объект не должен меняться, но если попытка изменения - кто знает, что может произойти?» В C истинным _constant_ является код типа '42', который является константой _integer_ с типом' int'. Таким образом, 'const int size = 10;' не является переменной _constant_. – chux

+0

Массив не имеет постоянного размера, но является массивом переменной длины. – Olaf

+1

Как они сказали, C имеет объекты 'const', которые на самом деле являются переменными * только для чтения *. Ср C++, который имеет истинные объекты 'const', которые на самом деле являются константами компиляции *. –

ответ

6

Массивы переменной длины могут иметь только время автоматического хранения. VLA были введены на C99.

Не допускается объявлять VLA с длительностью статической памяти, так как размер VLA будет определено во время выполнения (см ниже)

До этого стандарта вы можете использовать либо макрос как

#define SIZE 10 

//... 

int a[SIZE]; 

или нумератор перечисления как

enum { SIZE = 10; } 

//... 

int a[SIZE]; 

Кстати, вы можете удалить константный спецификатор и просто написать

int size = 10; 

вместо

const int size = 10; 

(В C++ вы должны использовать константный спецификатор, хотя в C++ нет Власа кроме того, что некоторые компиляторы могут иметь свои собственные расширения языка)

Примите во внимание, что оператор sizeof для VLA вычисляется во время выполнения вместо времени компиляции.

+0

Спасибо, я только начал понимать немного больше! Однако, если я пытаюсь без const, у меня такая же ошибка с глобальной областью. Но с #define SIZE 10 он работает. –

+0

@ BálintPap Как я писал, VLA может не иметь статической продолжительности хранения, которую имеют все глобальные массивы. –

+0

A, вот идем, хорошо! Ну, никогда об этом не думал. Спасибо за ваше объяснение! Я ценю это! –

Смежные вопросы