Страницы

Поиск по вопросам

среда, 17 октября 2018 г.

Проблемы с массивом “тип массива ”float [n]“ является неназначаемым”

Всем привет,учить недавно начал С++ пишу простые программки
#include "stdafx.h" #include #include using namespace std;
int main() { int n; cout << "введите n: "; cin >> n; float a, b, h, s, f[n]; cout << "введите a: "; cin >> a; cout << "введите b: "; cin >> b; if (b>a) {
h = (b - a) / n;
for (int i = 1; i <= n; i++) { f[i] = (a + (i - 0.5) * h) / (1 + pow((a + (i - 0.5) * h), 2)); s = s + f[i]; } s = s*h; cout << "(f1+f2+f3+..+fn)*h= " << s << endl; } else {
cout << "введены данные не удовлетворяют условие (b>a)" << endl; } return 0; }
Ну при компиляции VS 2015 ругается на то что "выражение не определяется константой" и "тип массива "float [n]" является неназначаемым" Подскажите, пожалуйста, где допущена ошибка и как ее исправить. Заранее благодарен.


Ответ

У вас несколько проблем имеется в программе.
В C++ отсутствуют массивы переменной длины (Variable Length Arrays - VLA), размер которых можно задавать во время выполнения программы. В C++ размер массива должен быть известен на этапе компиляции, а потому задается константным выражением. Некоторые компиляторы имеют собственные расширения языка C++, которые включают поддержку массивов переменной длины, но, тем не менее, это не соответствует стандарту C++, а потому такой код будет не переносим.
Поэтому вам придется динамически распределять массив заданной пользователем длины. Например,
Float *f = new float[n];
Или если вы хотите, чтобы элементы массива были инициализированы 0, то
Float *f = new float[n]();
Но тогда вам придется самостоятельно удалять выделенную память при завершении программы. Например,
delete [] f;
Такой подход чреват возникновением ошибок, связанных с утечкой памяти, так как программисты порой забывают вызывать оператор delete [] для выделенной памяти.
Поэтому лучше предоставить это делать компилятору, используя стандартный контейнер std::vector, который объявлен в заголовке Деструктор этого контейнера автоматически удаляет всю выделенную память под свои элементы.
Например,
#include
//...
std::vector f;
В программе вы используете цикл следующего вида
for (int i = 1; i <= n; i++) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ { f[i] = (a + (i - 0.5) * h) / (1 + pow((a + (i - 0.5) * h), 2)); s = s + f[i]; }
Однако эта запись определения цикла неверная. Во-первых, индексы в массивах (и в стандартном контейнере std::vector) начинаютя с 0.
Во-вторых, при использовании в качестве значения индекса значения переменной n приводит к обращению к памяти за пределами массива, что веден к неопределенному поведению программы.
Правильный диапазон индексов для массива, имеющего n элементов, это [0, n), то есть n не входит в диапазон
Еще одна проблема связана с тем, что вы не инициализировали переменную s
float a, b, h, s, f[n]; ^^^
Поэтому она имеет неопределенное значение, и использование ее в предложениях, как, например, данное предложение
s = s + f[i];
приведет к неопределенному результату.
Локальные переменные следует стараться определять в наименьшей области видимости там, где они используется. Иначе многочисленные объявления локальных переменных до их использования только запутывают читающего ваш код программиста.
С учетом всего сказанного программа может выглядеть следующим образом.
#include "stdafx.h" #include #include #include
int main() { int n;
std::cout << "введите n: "; std::cin >> n;
float a, b;
std::cout << "введите a: "; std::cin >> a; std::cout << "введите b: "; std::cin >> b;
if ( a < b ) { std::vector f; f.reserve( n );
float h = ( b - a ) / n;
float s = 0.0f; for ( int i = 0; i < n; i++ ) { f.push_back( ( a + ( i - 0.5f ) * h ) / ( 1.0f + std::pow( ( a + ( i - 0.5f ) * h ), 2.0f) ) ); s += f.back(); }
s *= h;
std::cout << "(f1+f2+f3+..+fn)*h = " << s << std::endl; } else { std::cout << "введены данные не удовлетворяют условие (a < b)" << std::endl; }
return 0; }

Комментариев нет:

Отправить комментарий