#cpp
Всем привет,учить недавно начал С++ пишу простые программки #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]" является неназначаемым" Подскажите, пожалуйста, где допущена ошибка и как ее исправить. Заранее благодарен.
Ответы
Ответ 1
У вас несколько проблем имеется в программе. В 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; } Ответ 2
Массивы должны быть постоянной длинны. int arr[10]; //Правильно const int size = 10; int arr[size]; //Правильно int size; cin >> size; int arr[size] //Не правильно Если вы заранее не знаете сколько вам нужно элементов используйте std::vector #include//... vector ints; ints.push_back(42); ints.push_back(314); ints.push_back(271); int i = ints[1]; //i = 314 В принципе, вы могли бы выделить массив нужного размера динамически int size; cin >> size; int arr* = new int[size]; arr[0] = 42; //... delete[] arr; //не забыть Но лучше доверить это вектору. Он сделает то же самое, но его писали умные люди(наверное) и в нем нет никаких ошибок(скорее всего). Плюс вектор сам меняет свой размер, и вам не нужно следить за тем сколько памяти вы выделили. Ответ 3
Как исправить код минимальными правками. Добавляем в include vector: #includeвместо объявления массива float f[n]; пишем так std::vector f(n); (создаст нужный "массив и заполнит нулями", классическое объявление f[n] на стеке не заполняет ими), а можно даже так std::vector f(n, 0); - в этом случае явно укажем, что хотим заполнить нулями (можно выбрать любой другой заполнитель). Все остальное будет работать так, как ожидается. Не нужно боятся использовать вектор - это "правильный" массив в с++. Ответ 4
Использовать динамические массивы // объявляем массив и выделяем под него память float * f = new float[n]; ................. // освобождаем выделенную память delete [] f;Ответ 5
3 варианта работы с массивами: 1) Массив константного размера int a[10]; const n = 5; int b[n]; 2) Динамический массив int n; std::cin>>n; int * a = new int[n]; //используем delete[] a; 3) Вектор #include. std::vector v(n);
Комментариев нет:
Отправить комментарий