4
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;

int main()
{
    int n, j = 0;
    cout << "Amount of numbers: ";
    cin >> n;
    const int length = n;
    int numbers[length];

    if (length >= 1) {
        // Элементы с чётными индексами получают значение индекса, с нечётными - квадрата индекса
        while (j < length) {
            if (j % 2 == 0){
                numbers[j] = j;
            }
            else {
                numbers[j] = pow(j, 2);
            }
            j++;
        }
        // Выводим элементы массива
        j = 0;
        while (j < length) {
            cout << numbers[j] << endl;
            j++;
        }
    }

    system("pause>nul");
    return 0;
}

введите сюда описание изображения

  • 2
    По-хорошему, оно даже компилироваться не должно - нет в С++ массивов с длиной, определяемой во время выполнения... – Harry Feb 08 '18 at 13:13
  • @Harry так длина задаётся до выполнения, в строчке int numbers[length]; – Homo Civicus Feb 08 '18 at 13:14
  • Да? И чему она равна? 5? 10? 22? – Harry Feb 08 '18 at 13:16
  • @Harry значению переменной n, вводимому пользователем с клавиатуры – Homo Civicus Feb 08 '18 at 13:16
  • 1
    Вы уж выбирайте что-то одно. "Длина задается до выполнения" или "длина вводится пользователем". Потому что вводится она во время выполнения... Кстати, если сделать нормально, то все работает - https://ideone.com/f3GZbS И, кстати, напишите нормально - j*j, а не эти извращения pow(j,2) - тоже может влиять, проверьте... – Harry Feb 08 '18 at 13:18
  • @Harry - посмотрев на код и приложенный скрин с результатами, я подумал, что перетрудился :). Однако еще остались места на земле, где возможны чудеса. – Александр Муксимов Feb 08 '18 at 13:19
  • @АлександрМуксимов чудес в программировании не бывает) как бы нам этого не хотелось... – PavelNewSky Feb 08 '18 at 13:24
  • @PavelNewSky - Вы полагаете, ИМХО, вот пример перед нами - некорректная инициализация массива - однако программа работает :) – Александр Муксимов Feb 08 '18 at 13:27
  • @АлександрМуксимов но логика подсказывает, что раз компилятор сожрал такой код, значит ему нормально. корректность определяется тем, что хавает компилятор, а что нет. компилятор нами управляет :) – PavelNewSky Feb 08 '18 at 13:34
  • @PavelNewSky такое случалось во времена MS Dos, PC XT и QuicC, но на дворе 21 век. Поэтому я и говорю - чудеса :). Ладно нас сейчас отсюда погонят за флуд. – Александр Муксимов Feb 08 '18 at 13:38
  • @АлександрМуксимов Сорян за тупой вопрос, я просто решаю задачи к 1 главе учебника по C++ и ещё не шарю. Я здесь создаю константу length и присваиваю ей значение, введённое пользователем. И массив имеет длину length, а length - константа, как и положено. – Homo Civicus Feb 08 '18 at 13:40
  • Все нормально. Вам в ответе написали про динамические массивы. Если бы будете работать с с++, то прямой смысл разобраться с этой темой. Это очень важно. Что касается pow(), то это эффекты округления до целых. Моя ирония направлена вовсе не на Вас. – Александр Муксимов Feb 08 '18 at 13:44
  • @АлександрМуксимов Ок, спасибо за разъяснения – Homo Civicus Feb 08 '18 at 13:45
  • Каким компилятором вы компилировали программу? – wololo Feb 08 '18 at 13:50
  • @wololo CodeBlocks – Homo Civicus Feb 08 '18 at 13:52
  • 1
    CodeBlocks - это среда, а не компилятор. Компилятор там gcc. Возможность объявления массивов run-time размера является расширением компилятора gcc. К языку С++ это расширение отношения не имеет. В С++ это не разрешается. – AnT stands with Russia Feb 08 '18 at 14:40
  • @Homo Civicus, если Вы хотите, чтобы Вам помогали дальше, то поставьте зеленую галочку у ответа, который Вы считаете лучшим (по моему Ваша проблема решена) и проголосуйте "за" за остальные ответы, потому что люди на Вашу проблему тратили свое время. – Александр Муксимов Feb 09 '18 at 05:56
  • @АлександрМуксимов сделано – Homo Civicus Feb 09 '18 at 09:49

4 Answers4

3

Типом возвращаемого значения функции std::pow() является либо float, либо double, либо long double, т.е. возвращается значение с плавающей точкой.

В вашем примере, вы передаёте два аргумента типа int, и они оба внутри функции pow приводятся к типу double, и возвращаемое значение также имеет тип double.

Затем в вашем примере значение, возвращённое функцией pow и имеющее тип double приводится к типу int. В C++ типы с плавающей точкой приводятся к целочисленным типам путём отбрасывания дробной части (так называемое округление в сторону нуля).

Так процесс возведения в степень осуществляется в числах с плавающей точкой, то нужно быть готовым к тому, что результат получится не совсем точным. Например, если точный результат некоторого вычисления равен 25, то в общем случае результирующее значение может оказаться равным, например, 24.999999999999996. Приведение этого значения к типу int отбросит дробную часть и в результате получится значение 24.

Мне не удалось повторить вывод вашей программы, используя функцию std::pow() из заголовочного файла <cmath> (вероятно потому, что я использовал Visual Studio). Предполагаю, что, возможно, в вашем случае реализация функции pow() имеет примерно такой вид:

template <typename T1, typename T2>
double pow_bad(T1 base, T2 exp)
{
    return std::exp( double(exp) * std::log(double(base)) );
}

или что-либо подобное. Один из возможных результатов работы приведённой выше функции на ваших входных данных будет таким:

i^2.0 = pow_bad(i, 2) int( pow_bad(i, 2) )
1^2.0 = 1 1
3^2.0 = 9.0000000000000018 9
5^2.0 = 24.999999999999996 24
7^2.0 = 48.999999999999993 48
9^2.0 = 81.000000000000028 81
11^2.0 = 121.00000000000003 121
13^2.0 = 169 169

Хотя вывод и не совпадает в точности с выводом вашей программы, но суть, думаю, понятна.


Попробуйте с помощью отладчика зайти внутрь функции pow и посмотреть как она устроена внутри. Возможно, что ничего интересного там не будет, но попробовать стоит.

wololo
  • 6,221
2

Если вы хотите чтобы оно работало с размером массива который вводит пользователь, то нужно заменить

const int length = n;
int numbers[length];

на

int *numbers=  new int[n]

и перед

system("pause>nul");

добавить

delete[] numbers

почитайте про динамическую память в с++ https://ru.wikipedia.org/wiki/New_(C%2B%2B)

SkiF
  • 177
2

Функция pow не умножает значение x n раз, так как она также должна вычислять степень с использованием дробных показателей. Используйте другую функцию или напишите свою. Функция pow (возможно, используя логарифмы) использует значения с плавающей запятой для вычисления значения степени, поэтому с int работает не так, как вам кажется, что она должна работать. Также ваша функция для вычисления степени int будет явно работать быстрее.

2

Замените-ка для проверки

numbers[j] = pow(j, 2);

на

numbers[j] = j*j;

Потому что если не считать использованного нестандартного расширения, это единственное слабое место...

P.S. Не понимаю две любви студентов - к float вместо double и к pow там, где она совсем ни к чему...

Harry
  • 221,325
  • Да, при таком варианте выводятся корректные значения. Видимо, функция pow() работает не так, как я предполагал. – Homo Civicus Feb 08 '18 at 13:25