Выражение должно иметь константное значение visual studio
Я использую консольное приложение Win32 / пустой проект.
Я не использую абсолютно ничего особенного, просто
И его единственная основная функция в файле cpp.
Размер массива должен быть целочисленным константным выражением или ICE (что означает, что он должен быть известен во время компиляции). Вы можете использовать const int в ICE, но только если его инициализатор сам является ICE.
Вызов функции, такой как keyword.size() , нельзя использовать в ICE, поэтому kwSize нельзя использовать в ICE.
Если он «отлично работает» в gcc, то это либо ошибка, либо какое-то расширение языка.
В C ++ 0x некоторые вызовы функций могут использоваться в выражениях интегральных констант, но они должны быть функциями constexpr , и на их использование существуют ограничения. Насколько мне известно, еще ни один компилятор полностью не поддерживает constexpr . В любом случае std::string::size не является constexpr .
keyword.size() оценивается во время выполнения, поэтому это не постоянная времени компиляции. В зависимости от компилятора может быть запрещено использовать размер массива, который зависит от некоторого значения времени выполнения.
Ответ такой: «выражение должно иметь постоянное значение». Константа должна быть решена во время компиляции.
Как уже упоминалось, непостоянные границы массива являются расширением GCC (вероятно, побочное преимущество его поддержки C99 - C99 действительно допускает непостоянные границы массива). Если вы хотите этого в C ++, вы должны использовать vector :
Чтобы превратить это в char * , выполните:
Это, хотя, строго говоря, не является допустимым C ++ до C ++ 0x, но работает должным образом во всех компиляторах, с которыми я сталкивался до сих пор. C ++ 0x ретроактивно благословляет такое использование, а также предоставляет эквивалент oldBuffer.data() .
GCC имеет расширение языка, позволяющее использовать массивы переменной длины. Visual C ++ этого не делает. Вы должны инициализировать стековые массивы с фиксированной константой времени компиляции.
int R = 300; // точка равновесия маятника
double fc = 0.0005; // коэффициент сопративления
double m = 0.1; // масса
double k = 0.1; // коэффициент упругости
double afi = 0, vfi = 0; // ускорение и скорость
double ar = 0, vr = 0;
bool state = false; // флаг движения тела (true - движется, false - стоит)
int flag = 0; // выбор что изменять (1-масса 2-упругость 3-положение)
int delay = 10; // Задержка в МС между кадрами
long time0 = 0; // Отметка системного времени
int x = (R - R0) * cos(fi); // положение маятника по декарту
int y = (R - R0) * sin(fi);
double E(double x) return (x - Width / 10) / 1000;
>
double Ln(double x) return x * 1000 + Width / 10;
>
void renderBitmapString(
float x,
float y,
void* font,
char* string)
char* c;
glRasterPos2f(x, y);
for (c = string; *c != '\0'; c++) glutBitmapCharacter(font, *c);
>
>
glClearColor(0, 0, 0, 1); // стираем все
glClear(GL_COLOR_BUFFER_BIT);
glColor3ub(255, 255, 255);
glBegin(GL_LINES); // Рисуем линию от центра до тела
glVertex2d(Width / 2, 7 * Height / 10);
glVertex3d(x + Width / 2, -y + 8 * Height / 10, 0);
glEnd();
glColor3ub(255, 0, 0);
glPointSize(20);
glEnable(GL_POINT_SMOOTH);
glBegin(GL_POINTS); // Рисуем 2 точки - цетр и тело
glVertex2d(Width / 2, 7 * Height / 10);
glVertex3d(x + Width / 2, -y + 8 * Height / 10, 0);
glEnd();
glBegin(GL_LINES); // Рисуем 2 ползунка
glVertex3d(Width / 10, 9.5 * Height / 10, 0);
glVertex3d(9 * Width / 10, 9.5 * Height / 10, 0);
glVertex3d(Width / 10, 9 * Height / 10, 0);
glVertex3d(9 * Width / 10, 9 * Height / 10, 0);
glEnd();
glBegin(GL_POINTS); // И 2 торчки на них
glVertex3d(Ln(m), 9.5 * Height / 10, 0);
glVertex3d(Ln(k), 9 * Height / 10, 0);
glEnd();
char text[] = "M"; // Рисуем букавки и цифарки на экране
renderBitmapString(0.5 * Width / 10, 9.5 * Height / 10 - 55, GLUT_BITMAP_TIMES_ROMAN_24, text);
text[0] = 'K';
renderBitmapString(0.5 * Width / 10, 9 * Height / 10 - 55, GLUT_BITMAP_TIMES_ROMAN_24, text);
char num[10];
sprintf_s(num, "%0.3f", m);
renderBitmapString(9.2 * Width / 10, 9.5 * Height / 10 - 55, GLUT_BITMAP_TIMES_ROMAN_24, num);
sprintf_s(num, "%0.3f", k);
renderBitmapString(9.2 * Width / 10, 9 * Height / 10 - 55, GLUT_BITMAP_TIMES_ROMAN_24, num);
void Reshape(GLint w, GLint h) < // Событие - изменение размеров окна
Width = w; // Запомнить новые размеры
Height = h;
glViewport(0, 0, w, h); // Область отображения
glMatrixMode(GL_PROJECTION); // Ортографическая проекция
glLoadIdentity();
glOrtho(0, w, 0, h, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
>
void Idle() < // Постоянное событие - IDLE
if (clock() - time0 < delay)
return; // Не истек интервал delay
time0 = clock();
if (state) < // Условие работы
// Расчет нового ускорения, скорости и координаты
afi = -m * 9.8 * sin(fi + PI) + sin(vfi) * (R0 + R) * -fc;
vfi += afi * 0.1;
fi += vfi * 0.1;
// Расчет нового ускорения, скорости и координаты
ar = -vr * fc - k * R0;
vr += ar * 0.1;
R0 += vr * 0.1;
x = (R + R0) * cos(fi); // Перевод к декарту
y = -(R + R0) * sin(fi);
glutPostRedisplay(); // Иниициировать событие Display
>
void Mouse(int button, int status, int cx, int cy) if (cy > 1.4 * Width / 10 || flag == 3) < // Если ниже ползунков
state = status == GLUT_DOWN ? false : state; // Нажата лкм - остановить движение
state = status == GLUT_UP ? true : state; // Отпущена лкм - запустить движение
>
flag = status == GLUT_UP ? 0 : flag; // Отпустили лкм? Прекратили изменять
>
cx -= Width / 2;
cy -= 2 * Height / 10;
cx = cx == 0 ? 1 : cx; // Защита от деления на 0
R0 = sqrt(cx * cx + cy * cy) - R;
fi = -atan2(cy, cx);
vfi = 0; vr = 0; afi = 0; ar = 0;
>
void main(int argc, char* argv[]) time0 = clock(); // Системное время в МС
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(Width, Height); // Размер окна
glutCreateWindow("maitnik");
glutDisplayFunc(Display); // Функция отображения
glutReshapeFunc(Reshape); // Функция смены размерности окна
glutKeyboardFunc(Keyboard); // Функция обраболтки клавиатуры
glutIdleFunc(Idle); // Функцция простоя IDLE
glutMouseFunc(Mouse); // Функцция обработки мыши
glutMotionFunc(Motion); // Функцция обработки движения мыши
glutMainLoop(); // Main библиотеки
>
Список ошибок
E0028 выражение должно иметь константное значение 30
E0028 выражение должно иметь константное значение 30
E0028 выражение должно иметь константное значение 30
E0028 выражение должно иметь константное значение 30
E0059 недопустимый вызов функции в константном выражении 30
E0028 выражение должно иметь константное значение 31
E0028 выражение должно иметь константное значение 31
E0028 выражение должно иметь константное значение 31
E0028 выражение должно иметь константное значение 31
E0059 недопустимый вызов функции в константном выражении 31
E0167 аргумент типа "double" несовместим с параметром типа "const char *const" 92
E0167 аргумент типа "double" несовместим с параметром типа "const char *const" 94
C2440 функция: невозможно преобразовать "double" в "const char *const " 92
C2440 функция: невозможно преобразовать "double" в "const char *const " 94
Обязательно ли при инициализации статического массива индекс должен быть константным значением?
К примеру создаем массив из N элементов.
Pelles C данный код пропускает, а MVS2010 выдает ошибку, что "х" не является константным значением. Всегда считал, что инициализировать не динамический массив, при работе программы, с помощью не константной переменной нельзя. Или я что то путаю? Можно ли прокомментировать данную ситуацию касательно применения в C и C++, а также хотел бы ссылку, где это описано в стандарте. Спасибо.
Но некоторые компиляторы (gcc вроде, например) пропускают и обычный вариант (как со статическими), но код, естественно, получается слегка непереносимый
В последнем стандарте Си (C99) введены массивы переменной длины, это позволяет указывать размерность массива не-константой.
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Обязательно ли при инициализации статического массива индекс должен быть константным значением?
К примеру создаем массив из N элементов.
Pelles C данный код пропускает, а MVS2010 выдает ошибку, что "х" не является константным значением. Всегда считал, что инициализировать не динамический массив, при работе программы, с помощью не константной переменной нельзя. Или я что то путаю? Можно ли прокомментировать данную ситуацию касательно применения в C и C++, а также хотел бы ссылку, где это описано в стандарте. Спасибо.
MVS 2010 не поддерживает стандарт языка С99, в котором можно объявлять локальные массивы переменной длины. То есть, похоже, ваш Pelles C уже поддерживает стандарт С99, а MVS 2010 не поддерживает.
Что касается С++, то там значение самого крайнего правого индекса должно быть констатным выражением.
Что касается С++, то там значение самого крайнего правого индекса должно быть констатным выражением. |
При объявлении статического массива все размерности должны быть константами времени компиляции. У динамического - крайнее левое значение может быть не константным.
При объявлении статического массива все размерности должны быть константами времени компиляции. У динамического - крайнее левое значение может быть не константным.
Нет, вы ошибаетесь. Можно при инициализации массива не указывать размер крайне левого индекса. Например,
То есть размер правого индекса не является константным выражением. Выражение просто может отсутствовать.
Нет, вы ошибаетесь. Можно при инициализации массива не указывать размер крайне левого индекса. |
Нет, я не ошибаюсь. Если вы его не указываете, это не значит, что он не константа времени компиляции. Просто компилятор определяет его другим путем.
То есть размер правого индекса не является константным выражением. Выражение просто может отсутствовать. |
Вы сами поняли, че сказали? Если вы перепутали право и лево (а только в такой интерпретации эта фраза приобретает смысл), то спешу вас уверить что он таковым является, согласно написанному выше.
Почему я получаю эту ошибку:
выражение должно иметь постоянное значение.
ОТВЕТЫ
Ответ 1
При создании такого массива его размер должен быть постоянным. Если вам нужен массив с динамическим размером, вам нужно выделить память для него в куче, и вам также нужно будет освободить его с помощью delete , когда вы закончите:
Если вы хотите фиксированный размер, тогда они должны быть объявлены как const:
даже не предоставляет имя переменной.
Ответ 2
С++ не позволяет использовать непостоянные значения для размера массива. Это так, как оно было разработано.
C99 позволяет размеру массива быть переменной, но я не уверен, что это разрешено для двух измерений. Некоторые компиляторы С++ (gcc) разрешают это как расширение, но вам может потребоваться включить параметр компилятора, чтобы разрешить его.
И я почти пропустил это - вам нужно объявить имя переменной, а не только размеры массива.
Ответ 3
Стандарт требует, чтобы длина массива была значением, которое можно вычислить во время компиляции, чтобы компилятор мог выделить достаточно места в стеке. В вашем случае вы пытаетесь установить длину массива на значение, которое неизвестно во время компиляции. Да, я знаю, что кажется очевидным, что он должен быть известен компилятору, но здесь это не так. Компилятор не может делать никаких предположений о содержимом непостоянных переменных. Итак, идите с:
UPD: некоторые компиляторы фактически позволят вам снять это. IIRC, g++ имеет эту функцию. Однако никогда не используйте его, потому что ваш код станет не переносимым для компиляторов.
Ответ 4
Ответ 5
Когда вы объявляете переменную как здесь
вы сообщаете компилятору С++, что во время выполнения вы хотите, чтобы 100 последовательных целых чисел были выделены в программную память. Затем компилятор предоставит вашей программе доступ к такой большой памяти, и все будет хорошо с миром.
Если вы скажете компилятору
у компилятора нет возможности узнать, сколько памяти вам действительно понадобится во время выполнения, не делая много очень сложного анализа, чтобы отслеживать каждое последнее место, где значения x и y изменены [если есть]. Вместо поддержки таких массивов с переменными размерами С++ и C настоятельно рекомендуют, если вы не хотите, чтобы вы использовали malloc(), чтобы вручную выделить нужное пространство.
TL; DR
a теперь представляет собой 2D массив размером 5x5 и будет вести себя так же, как int a [5] [5]. Поскольку вы вручную выделили память, С++ и C требуют, чтобы вы удалили ее вручную.
Ответ 6
Нет, он не обязательно должен быть постоянным, причина, почему его код выше неправильный, заключается в том, что ему нужно включить имя переменной перед объявлением.
Я использую консольное приложение Win32 / пустой проект.
Я не использую абсолютно ничего особенного, просто
И его единственная основная функция в файле cpp.
Размер массива должен быть целочисленным константным выражением или ICE (что означает, что он должен быть известен во время компиляции). Вы можете использовать const int в ICE, но только если его инициализатор сам является ICE.
Вызов функции, такой как keyword.size() , нельзя использовать в ICE, поэтому kwSize нельзя использовать в ICE.
Если он «отлично работает» в gcc, то это либо ошибка, либо какое-то расширение языка.
В C ++ 0x некоторые вызовы функций могут использоваться в выражениях интегральных констант, но они должны быть функциями constexpr , и на их использование существуют ограничения. Насколько мне известно, еще ни один компилятор полностью не поддерживает constexpr . В любом случае std::string::size не является constexpr .
keyword.size() оценивается во время выполнения, поэтому это не постоянная времени компиляции. В зависимости от компилятора может быть запрещено использовать размер массива, который зависит от некоторого значения времени выполнения.
Ответ такой: «выражение должно иметь постоянное значение». Константа должна быть решена во время компиляции.
Как уже упоминалось, непостоянные границы массива являются расширением GCC (вероятно, побочное преимущество его поддержки C99 - C99 действительно допускает непостоянные границы массива). Если вы хотите этого в C ++, вы должны использовать vector :
Чтобы превратить это в char * , выполните:
Это, хотя, строго говоря, не является допустимым C ++ до C ++ 0x, но работает должным образом во всех компиляторах, с которыми я сталкивался до сих пор. C ++ 0x ретроактивно благословляет такое использование, а также предоставляет эквивалент oldBuffer.data() .
GCC имеет расширение языка, позволяющее использовать массивы переменной длины. Visual C ++ этого не делает. Вы должны инициализировать стековые массивы с фиксированной константой времени компиляции.
Читайте также: