Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.95/19: Рейтинг темы: голосов - 19, средняя оценка - 4.95
Bers
Заблокирован
#1

хитрая константа не даёт создать обычный массив

25.11.2011, 18:47. Просмотров 3428. Ответов 64
Метки нет (Все метки)

Почему я не могу создать обычный массив, указав константу в качестве количества элементов?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int n=10;
const int N(n); //N вроде как константа 
                     //действительно получает значение 10
 
 
int A[N]; //error C2057: требуется константное выражение
             //error C2466: невозможно выделить память 
             //для массива постоянного нулевого размера
 
int main()
{
   int b= N; //b получает корректное значение 10
   const int c=N; //с получает корректное значение
   return 0;
};
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.11.2011, 18:47
Ответы с готовыми решениями:

Можно ли создать проект не managed c++, а обычный c++, но с формами в VS2008?
Можно ли создать проект не managed c++, а обычный c++, но с формами в VS2008?

Перевести обычный массив в векторный
#include <iostream> #include <stdlib.h> #include <math.h> #include <time.h>...

Как из массива значений цветов создать обычный PNG файл?
Подскажите, знающие люди, как из массива значений цветов (для каждого пикселя)...

Скопировать элементы Vector в обычный массив
Вобщем есть поля класса * arr // массив size // размер массива max_size...

Как создать обычный файл exe, который могут открывать друзья.
Всем доброе утро! Вопрос о том как сделать программу, которая запускалась бы...

64
ForEveR
В астрале
Эксперт С++
7995 / 4754 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
25.11.2011, 18:51 #2
Bers, Ибо нех такое творить.

C++
1
2
3
int n = some_long_func();
const int N = n;
int array[N];
И отлично что так не создается.
1
prazuber
110 / 110 / 13
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 18:56 #3
Потому что n не const. В новом стандарте, если не ошибаюсь, лечится constexpr.
0
Bers
Заблокирован
25.11.2011, 18:56  [ТС] #4
Цитата Сообщение от PraZuBeR Посмотреть сообщение
Потому что n не const
При чем здесь вообще n?
0
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
25.11.2011, 18:59 #5
Bers, ну логично должно быть
C++
1
2
3
const int n=10;
const int N(n); //N вроде как константа 
                     //действительно получает значение 1
0
prazuber
110 / 110 / 13
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 18:59 #6
Хорошо, выражусь по-другому. Так как n не const, то ее значение неизвестно на этапе компиляции, пускай даже вы присваиваете константу.
0
Bers
Заблокирован
25.11.2011, 19:01  [ТС] #7
Цитата Сообщение от PraZuBeR Посмотреть сообщение
Хорошо, выражусь по-другому. Так как n не const, то ее значение неизвестно на этапе компиляции, пускай даже вы присваиваете константу.
Ну и что? Константа инициализируется значением, не известным на этапе компиляции. Что здесь такого противозаконного?

Если бы это было нельзя - компилятор ругался бы в принципе на саму попытку таким образом инициализировать константу.

Но он не ругается. Убери массив, и работай с константой, как обычно.

Очень многие константы создаются в рантайме, и почему то на них компилятор никак не буксует.
0
go
Эксперт С++
3636 / 1368 / 243
Регистрация: 16.04.2009
Сообщений: 4,527
25.11.2011, 19:01 #8
Цитата Сообщение от Bers Посмотреть сообщение
При чем здесь вообще n?
Да при том!
C++
1
2
int n=6;
const int N=n; //как видите это не эквивалентно const int N=6
0
prazuber
110 / 110 / 13
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 19:03 #9
Цитата Сообщение от Bers Посмотреть сообщение
Ну и что? Константа инициализируется значением, не известным на этапе компиляции. Что здесь такого противозаконного?

Если бы это было нельзя - компилятор ругался бы в принципе на саму попытку таким образом инициализировать константу.

Но он не ругается. Убери массив, и работай с константой, как обычно.

Очень многие константы создаются в рантайме, и почему то на них компилятор никак не буксует.
Тут ничего противозаконного. А вот создание массива с помощью такой константы - вот это противозаконно.
0
Bers
Заблокирован
25.11.2011, 19:03  [ТС] #10
Цитата Сообщение от go Посмотреть сообщение
Да при том!
Что значит не эквивалентно?

Константа инициализируется один раз при создании. Все. Дальше есть только значение константы.
Никого не волнует, откуда она его получила.
0
go
Эксперт С++
3636 / 1368 / 243
Регистрация: 16.04.2009
Сообщений: 4,527
25.11.2011, 19:03 #11
C++
1
2
const int n=6;
const int N=n;
0
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
25.11.2011, 19:03 #12
Цитата Сообщение от Bers Посмотреть сообщение
Ну и что? Константа инициализируется значением, не известным на этапе компиляции. Что здесь такого противозаконного?
значение константы может зависеть только от других констант
rtfm же
0
Bers
Заблокирован
25.11.2011, 19:04  [ТС] #13
Цитата Сообщение от alex_x_x Посмотреть сообщение
значение константы может зависеть только от других констант
почему тогда при попытке инициализировать константу не_константой компилятор молчит?

Он ругается только при попытке создать с её помощью массив. А как он вообще определяет, что она палёная? И почему тогда вообще позволяет такие константы делать?
0
Сыроежка
Заблокирован
25.11.2011, 19:16 #14
Цитата Сообщение от Bers Посмотреть сообщение
почему тогда при попытке инициализировать константу не_константой компилятор молчит?

Он ругается только при попытке создать с её помощью массив. А как он вообще определяет, что она палёная? И почему тогда вообще позволяет такие константы делать?
Размер массива компилятор должен знать на этапе компиляции, а ваша константа инициализируется на этапе выполнения. То есть для вашей константы компилятор генерирует некоторый код, который будет пересылать значение из переменной в константу.

Я вам приведу похожий пример. Допустим есть единица компиляции, в которой объявлено

C++
1
const int N = 10;
а в другой единице компиляции объявлено

C++
1
2
3
extern const int N;
 
int a[N];
Компилятор не будет компилировать второй модуль, не смотря на то, что N объявлена как константа, так как компилятору неисзвестно ее значение на этапе компиляции второго модуля.
1
prazuber
110 / 110 / 13
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 19:21 #15
Bers, есть два типа констант. Первые - те, что известны на этапе компиляции. Стандарт про это пишет так:
An integral constant-expression can involve only literals (2.13), enumerators, const variables or static
data members of integral or enumeration types initialized with constant expressions (8.5), non-type template
parameters of integral or enumeration types, and sizeof expressions.
Второй тип - все остальные. Ваше const int N является вторым типом, потому что не попадает в описание первого.
N инициализируется вначале работы программы, но уже в рантайме. Поэтому массив с помощью нее инициализировать нельзя. Зато можно написать такое
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
 
int f()
{
    int a;
    cin>>a;
    return a;
}
 
const int N(f());
 
int main()
{
    cout<<N<<endl;
};
Upd. Ошибся немного с цитатами, поправил.
2
go
Эксперт С++
3636 / 1368 / 243
Регистрация: 16.04.2009
Сообщений: 4,527
25.11.2011, 19:23 #16
Сыроежка, каждый компилятор по разному
C
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
void main ()
{
   int size = 5 ;
   int arr [size] ;
 
printf ("Ok");
 
}
http://codepad.org/8W1Udtgr
0
prazuber
110 / 110 / 13
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 19:24 #17
go, это проблемы компилятора.
0
fasked
Эксперт С++
4978 / 2557 / 241
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
25.11.2011, 19:25 #18
go, то, что Вы показываете, называется variable-length array и никакого отношения к сабжу не имеет.
0
go
Эксперт С++
3636 / 1368 / 243
Регистрация: 16.04.2009
Сообщений: 4,527
25.11.2011, 19:32 #19
Цитата Сообщение от PraZuBeR Посмотреть сообщение
go, это проблемы компилятора.
Нет, вот цитата
Массивы переменной длины

В С89 размерности массивов необходимо объявлять при помощи выражений из целых констант, причем размер массива фиксируется во время компиляции. В силу определенных обстоятельств, в С99 это правило было изменено. В С99 можно объявить массив, размерности которого определяются любыми допустимыми целыми выражениями, в том числе и такими, значения которых становятся известны только во время выполнения. Такой массив называется массивом переменной длины (variable-length array, VLA). Однако такими массивами могут быть только локальные массивы (то есть те, у которых область видимости — прототип или блок).

Не по теме:


Цитата Сообщение от fasked Посмотреть сообщение
то, что Вы показываете, называется variable-length array и никакого отношения к сабжу не имеет.
Не совсем так, нужно просто это понимать ;)

0
Сыроежка
Заблокирован
25.11.2011, 19:36 #20
Я написал пример, но никто меня не поправил! Видимо, кроме меня никто стандарт не знает!

То есть в этом примере допущена ошибка

C++
1
const int N = 10;
а в другой единице компиляции объявлено

C++
1
2
3
extern const int N;
 
int a[N];
По умолчанию константы имеют внутреннее связывание, поэтому в первом модуле также надо добавить спецификатор extern То есть должно быть


C++
1
extern const int N = 10;
а в другой единице компиляции объявлено

C++
1
2
3
extern const int N;
 
int a[N];
0
25.11.2011, 19:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2011, 19:36

Почему матрица выводится как обычный массив
//matriza.h #pragma once class matriza { float *b,max,s; int n,m,nom;...

Дан массив А на Н элементов (Н-константа). В массиве найти пять максимальных элементов.
Дан массив А на Н элементов (Н-константа). В массиве найти пять максимальных...

Двумерный массив <array>. const int value = array.size(); value не константа?
#include &lt;array&gt; #include &lt;iostream&gt; using std::array; using std::cout; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru