Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.11.2011, 12:19   #1
Тамарочка
Пользователь
 
Регистрация: 19.11.2011
Сообщений: 13
Восклицание Запись элементов одномерного массива с Rand.

Здравствуйте,недавно перешла с Pascal на C++, мало чего ещё понимаю.
Задали лабу по одномерным массивам,вроде ничего сложного но у меня возникла проблема в самом начале,поэтому работа стоит.Не смогла найти стандартного синтаксиса Rand, он везде разный.

Вот задание и исходник,объясните что не так??


15) Написать и отладить программу создания одномерного массива из 15 случайных вещественных элементов, которые принадлежат интервалу [-40; 30]. Найти произведение положительных элементов с четными индексами и среднее арифметическое отрицательных элементов.
//Одномерный массив
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
void main ()
{const int n=15;
int a[15];int result[8];
float pr,srednearifmetich,b;int k,i,c,ipol,ichet,iotr;
int summa=0;
srand(time(NULL));
for(int i = 0; i < 15; i++)
{
a[i] =(rand()%71)-40;
cout << a[i] << endl;
}
return 0;
}
Посоветуйте толковую книгу для самостоятельного изучения языка!!

Последний раз редактировалось Тамарочка; 19.11.2011 в 12:39.
Тамарочка вне форума Ответить с цитированием
Старый 19.11.2011, 15:10   #2
RAZOR1703
Пользователь
 
Регистрация: 15.12.2010
Сообщений: 74
По умолчанию

Во-первых, у Вас функция main объявлена как void. Это значит, что эта функция не должна возвращать никакого значения, поэтому сразу убираем return 0; .
Во-вторых, хорошо бы все переменные типа int объявлять в одном блоке через запятую, а не по несколько раз писать int x; int y; ...
В-третьих, для использования генератора случайных чисел, в Вашем случае, нужно подключить еще и библиотеку time.h.
В Вашем цикле переменная i объявлена второй раз, это ошибка. Надо так:
Код:
for(i = 0; i < 15; i++)
Читайте Шилдта

И массив, как я понимаю, у Вас должен быть из вещественных чисел. Почему он объявлен как int?

-------

Вот код. Постарался объяснить все как можно подробнее.
Код:
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#define N 15							//Количество элементов массива. Обычно это делают так

void main ()
{
	
	double a[N], prod = 1, aver = 0;	//Объявляем переменные вещественного типа double, 
										//обязательно инициализируем две последних
	int i, count = 0;
	srand(time(NULL));					//Используем эту функцию, чтобы связать rand() с текущим временем системы
										//Это делает rand() действительно rand-ом

	cout << "Initial array: " << endl;
	
	for(i = 0; i < N; i++)				//Заполняем начальный массив случайно сгенерированными числами
										
	{
		a[i] = (double)(rand()%701 - 400)/10;	//701 - разница между макс. и мин. значениями промежутка, -400 - минимальное
												//значение. Цифры взяты в 10 раз больше для того, чтобы можно было потом 
												//разделить на 10 и получить вещественное число. "(double)" здесь стоит для 
												//приведения результата выполнения rand() к типу double. Так можно делать и с 
												//переменными
		cout << a[i] << " ";					//Выводим наш массив, разделяя его этементы пробелом
	}

	cout << endl;								//Перевод каретки на начало следущей строки. 

	for (i = 0; i < N; i++)						//Цикл поиска наших результатов
	{
		if ( (a[i] > 0) && (i%2 == 1) )			//Здесь стоит условие, что элемент массива больше нуля и остаток от деления равен 1.
												//Равен 1 потому, что элементы нумеруются начиная с нуля, а ведь остаток от деления 
												//нуля на 2 равен нулю, и все собъется. То есть, на самом деле, нужно считать нечетные
												//элементы. "&&" в условии означает "и"
			
			prod = prod * a[i];					//Находим произведение элементов, отобранных условием					
		
		if (a[i] < 0)							//Здесь находим сумму отрицательных элементов и считаем их количество в count
		{
			aver = aver + a[i];
			count++;
		}
	}

	aver = aver / count;						//Находим среднее арифметическое отрицательных элементов, разделив их сумму на количество

												// Выводм результат на экран
	cout << "Product of positive numbers with even indexes: " << prod << endl;	
	cout << "Average of negative numbers: " << aver << endl;

}

Последний раз редактировалось RAZOR1703; 19.11.2011 в 16:44.
RAZOR1703 вне форума Ответить с цитированием
Старый 19.11.2011, 16:47   #3
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение
Во-первых, у Вас функция main объявлена как void. Это значит, что эта функция не должна возвращать никакого значения, поэтому сразу убираем return 0; .
Во-вторых, хорошо бы все переменные типа int объявлять в одном блоке через запятую, а не по несколько раз писать int x; int y; ...
В-третьих, для использования генератора случайных чисел, в Вашем случае, нужно подключить еще и библиотеку time.h.
В Вашем цикле переменная i объявлена второй раз, это ошибка. Надо так:
Код:
for(i = 0; i < 15; i++)
Читайте Шилдта

И массив, как я понимаю, у Вас должен быть из вещественных чисел. Почему он объявлен как int?
Позвольте мне тоже кое-что сказть во-первых.
Во-первых, даже если вы уберете return 0 в функции main, компилятор все равно вставит код, который соответсвует return 0;

Чтобы было понятно, то следующие два кода эквивалентны

Код:
int main()
{
   return 0;
}
и

Код:
int main()
{
}

Вопрос не в том, убирать предложение с return, а в том, что согласно стандарту языка С++ функция main, вызываемая в операционной среде, должна быть объявлена, как возвращающая значение типа int, то есть в виде int main(). Объявление void main() не соответсвует стандарту языка, а потому поведение программы с таким объявлением main неопреддеенное.

Во-вторых, кто вам сказал, что нужно все переменные одного типа объявлять в одной строке?! Как раз коогда они объявлены в одной строке, то для читающего код они выглядят как бессмысленная каша, так как неиззвестно, есть ли связь между этими переменными, то есть участвуют ли они в одном алгоритме функции в одном месте, или они не связаны между собой и участвуют в различных алгоритмах одной функции в разных местах.
Объявлять переменные нужно там. где они используются.

В-третьих, никакой ошибки, связанной с переменной i нет! В цикле объявляется локальная переменная, которая скрывает собой предыдущее объявление переменной с тем же самым именем в охватывающем блоке. ДДругое дело, что не имеет смысла объявлять переменную с этим именем в охватывающем блоке, так как она нигде не используется. Тем не менее это не является ошибкой.

В-четвертых, совершенно не поонятно, почему нужно чмтать Шилдта?! Разве другие авторы чем-то хуже. Надо читать стандарт С++. Кстати сказать, как раз вам это будет очень полезно!
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Сыроежка; 19.11.2011 в 16:59.
Сыроежка вне форума Ответить с цитированием
Старый 19.11.2011, 18:52   #4
RAZOR1703
Пользователь
 
Регистрация: 15.12.2010
Сообщений: 74
По умолчанию

Начнем с того, что я смотрел в корень ошибки: функция void не имеет возвращаемого значения. Это я исправил.
Цитата:
Объявление void main() не соответсвует стандарту языка, а потому поведение программы с таким объявлением main неопреддеенное.
Для начинающего программиста на C++ это не имеет особого значения. Хотите сказать, что невозможно предсказать поведение функции в коде подобного содержания?

Касательно объявления переменных. Посмотрите на объявление переменных в ОП-посте.
Код:
const int n=15;
int a[15];int result[8];
float pr,srednearifmetich,b;int k,i,c,ipol,ichet,iotr;
int summa=0;
Это нечитаемо. Не лучше ли сделать так?
Код:
const int n=15;
int a[15], result[8], k, i, c, ipol, ichet, iotr, summa=0;
float pr, srednearifmetich, b;
И - да - я согласен с тем, что, программируя на С++ переменные следует объявлять по мере их поступления и переменные, область использования которых ограничивается определенным блоком объявлять именно в этих блоках, если отсутствует цикл. Но, согласитесь, для человека, недавно перешедшего с Паскаля, поначалу трудно осознать то, что переменные можно объявлять где угодно в коде. Поэтому в своем примере я не стал менять конструкцию с объявлением.

Цитата:
В-третьих, никакой ошибки, связанной с переменной i нет!
С каких это пор переопределение переменной перестало быть ошибкой?
Код:
c:\program files (x86)\microsoft visual studio\myprojects\test1\test1.cpp(12) : error C2086: 'i' : redefinition
Цитата:
В-четвертых, совершенно не поонятно, почему нужно чмтать Шилдта?!
Ответ очевиден. Во-первых, потому, что автор попросил литературы по С++. Во-вторых, потому что это справочник по программированию на C++. Проглядывается параллель.

Цитата:
Разве другие авторы чем-то хуже.
Я же не кричал "Читайте Шилдта, и ни в коем случае не вздумайте читать кого-то другого!".
Я не говорю, что они чем-то хуже или лучше. Я всего-навсего поделился своим опытом.

Цитата:
Кстати сказать, как раз вам это будет очень полезно!
Это будет полезно для кого угодно. Конкретно мне - в том числе, даже не смотря на то, что текущий уровень знаний стандартов языка меня устраивает.
RAZOR1703 вне форума Ответить с цитированием
Старый 19.11.2011, 19:48   #5
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение
Начнем с того, что я смотрел в корень ошибки: функция void не имеет возвращаемого значения. Это я исправил.

Для начинающего программиста на C++ это не имеет особого значения. Хотите сказать, что невозможно предсказать поведение функции в коде подобного содержания?
.
Вы не исправили ошибку! Вы написали некорректный код, так как функция main должна иметь тип возвращаемого значения int, а не void. Иначе поведение программы неопределено.
То есть вы ничего не исправили, а лишь изменили некорректный для С++ код.
Для начинающего программиста как раз имеет большое значение с самого начала писать правильный код, то есть осваивать правильные синтаксис и семантику языка.

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение
Касательно объявления переменных. Посмотрите на объявление переменных в ОП-посте.
Код:
const int n=15;
int a[15];int result[8];
float pr,srednearifmetich,b;int k,i,c,ipol,ichet,iotr;
int summa=0;
Это нечитаемо. Не лучше ли сделать так?
Код:
const int n=15;
int a[15], result[8], k, i, c, ipol, ichet, iotr, summa=0;
float pr, srednearifmetich, b;
И - да - я согласен с тем, что, программируя на С++ переменные следует объявлять по мере их поступления и переменные, область использования которых ограничивается определенным блоком объявлять именно в этих блоках, если отсутствует цикл. Но, согласитесь, для человека, недавно перешедшего с Паскаля, поначалу трудно осознать то, что переменные можно объявлять где угодно в коде. Поэтому в своем примере я не стал менять конструкцию с объявлением.
Я не спорю, что объявление переменных в исходном примере не читабельно. Я возражал против вашего категорического заявления, что переменные одного типа должны быть все вместе объявлены в одной строке.

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение
С каких это пор переопределение переменной перестало быть ошибкой?
Код:
c:\program files (x86)\microsoft visual studio\myprojects\test1\test1.cpp(12) : error C2086: 'i' : redefinition
С каких пор? С тех самых поор, как появился язык С! Переменная во вложенном блоке скрывает переменную с тем же самым именем в охватывающем блоке.

Простой пример

Код:
int i = 1;

int main()
{
   int i = 2;
   {
      int i = 3;
      for ( int i = 4 ; i < ::i; i++ );
   }
}
В этом коде объявлено 4 переменных с одним и тем же именем. Но тем не менее этот код совершшенно корректен, хотя ничего полезного не деает. Вы прежде, чем размахивать сообщением об ошибке, приводите тот код, который вы компилировали! Иначе это похоже на обман зрителей фокусником.

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение
Ответ очевиден. Во-первых, потому, что автор попросил литературы по С++. Во-вторых, потому что это справочник по программированию на C++. Проглядывается параллель.


Я же не кричал "Читайте Шилдта, и ни в коем случае не вздумайте читать кого-то другого!".
Я не говорю, что они чем-то хуже или лучше. Я всего-навсего поделился своим опытом.


Это будет полезно для кого угодно. Конкретно мне - в том числе, даже не смотря на то, что текущий уровень знаний стандартов языка меня устраивает.
Понятно, вы прочитали Шилдта, других книг вы не читали, а потому теперь вы всем подряд советуете читать Шилдта. Между прочим справочник Шилдта по С++, если вы имели в виду его, написан крайне, так сказать, "легкомысленно". То есть многие важные вещи, которые на самом деле больше всего волнуют программистов, так как с ними связано большей частью непонимание, опущены в этом справочнике.

Кстати сказать, ваш совет читать Шилдта из ваших уст выглядет крайне двусмысленно! Вы, прочитав, Шилдта, так и не выяснили, что объявление функции void main() некорректное. Поэтому возникает естественный вопрос, то ли не стоит читать Шилдта, если он вам не дал нужных знаний, то ли не следует слушать ваших советов, так как вы сами не знаете С++.
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Сыроежка; 19.11.2011 в 20:02.
Сыроежка вне форума Ответить с цитированием
Старый 19.11.2011, 20:19   #6
RAZOR1703
Пользователь
 
Регистрация: 15.12.2010
Сообщений: 74
По умолчанию

Цитата:
Вы не исправили ошибку! Вы написали некорректный код, так как функция main должна иметь тип возвращаемого значения int, а не void. Иначе поведение программы неопределено.
Более грубую ошибку, с которой автору пришлось бы встречаться куда чаще, чем с некорректным определением функции main я как раз исправил.
Окай, пусть я буду не прав.
Цитата:
Я возражал против вашего категорического заявления, что переменные одного типа должны быть все вместе объявлены в одной строке.
Цитата:
категорического заявления
Цитата:
хорошо бы все переменные типа int объявлять в одном блоке через запятую, а не по несколько раз писать int x; int y; ...
Вы уверены, что на 100% знаете смысл слова "категоричный"?
Цитата:
Вы прежде, чем размахивать сообщением об ошибке, приводите тот код, который вы компилировали! Иначе это похоже на обман зрителей фокусником.
Да хотя бы тот, который в ОП-посте, слегка подправленный.
На заметку. В коде автора i пытается переопределиться в том же блоке, а не во вложенном.
Код:
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
void main ()

{
	const int n=15;
	int a[15];int result[8];
	float pr,srednearifmetich,b;int k,i,c,ipol,ichet,iotr;
	int summa=0;
	srand(time(NULL));
	for(int i = 0; i < 15; i++)
	{
		a[i] =(rand()%71)-40;
		cout << a[i] << endl;
	}

}
Цитата:
Понятно, вы прочитали Шилдта, других книг вы не читали, а потому теперь вы всем подряд советуете читать Шилдта
Здесь, по меньшей мере, два Ваших домысла. Читал, и не одну. Плюс к ним еще два самоучителя. И чтобы советовать "всем подряд", нужно как минимум посоветовать двум людям. Я этого не сделал. Лично мое мнение - справочник хороший, единственный минус - непоследовательный. Темы, которые, по идее, должны идти одна за другой встречаются зачастую в разных концах книги.

Последующую бессмысленную полемику, думаю, лучше опустить. На этом всё.

Последний раз редактировалось RAZOR1703; 19.11.2011 в 20:29.
RAZOR1703 вне форума Ответить с цитированием
Старый 20.11.2011, 04:54   #7
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение
Более грубую ошибку, с которой автору пришлось бы встречаться куда чаще, чем с некорректным определением функции main я как раз исправил.
Окай, пусть я буду не прав.
Да ничего вы не исправили! Вы не знаете С++ и написали безграмотный код!

Вот предложение из вашего собственного кода

void main ()

Что вы исправили?! Вы даже не понимаете, что вы делаете. То, что вы убрали return, абсолютно никак не повлияло на корректность кода! Вы хоть вчитывайтесь, что я вам пишу. Компилятор вместо вас вставил return 0. Не понимаете с первого раза? Повторяю. Вы убрали return, а компилятор его вставил. Ну, и что вы исправили?
Учите стандарт С++!

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение
Вы уверены, что на 100% знаете смысл слова "категоричный"?

Да хотя бы тот, который в ОП-посте, слегка подправленный.
На заметку. В коде автора i пытается переопределиться в том же блоке, а не во вложенном.
Код:
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
void main ()

{
	const int n=15;
	int a[15];int result[8];
	float pr,srednearifmetich,b;int k,i,c,ipol,ichet,iotr;
	int summa=0;
	srand(time(NULL));
	for(int i = 0; i < 15; i++)
	{
		a[i] =(rand()%71)-40;
		cout << a[i] << endl;
	}

}
Я еще раз спрашиваю вас, вы мое предыдущее сообщение поняли. Я вам привел пример нескольких объявлений переменной с одним и тем же именем. Вы хоть его проверяли?! Как вы читали Шилдта? По диагонали? Где вы видите объявление в привденном вами коде объявление переменной I два раза?! Здесь каждая переменная i объявлена в своем блоке кода: первая переменная объявена во внешнем блоке функции, а вторая переменная объявлена в блоке предложения for.

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение

Здесь, по меньшей мере, два Ваших домысла. Читал, и не одну. Плюс к ним еще два самоучителя. И чтобы советовать "всем подряд", нужно как минимум посоветовать двум людям. Я этого не сделал. Лично мое мнение - справочник хороший, единственный минус - непоследовательный. Темы, которые, по идее, должны идти одна за другой встречаются зачастую в разных концах книги.

Последующую бессмысленную полемику, думаю, лучше опустить. На этом всё.
Я не знаю, как вы читали Шилдта и что вы там еще читали, но вы совершенно не знаете С++. Я вас могу еще больше удивить. Одно и тоже имя можно переопределить в одном блоке! Удивились? Учите стандарт С++, молодой человек, или спросите меня, и я вам покажу, как одно и тоже имя в одной области объявления может означать совершенно разные сущности языка С++.

И нет никакой полемики, как вы наивно думаете. Полемика может вестись со специалистом по тонкостям языка. А здесь я просто указываю на ващу безграмотность. Я не всупаю с вами в дискуссии, потому что здесь не о чем дискуссировать. Я вам указал на ваши ошибки.
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 20.11.2011, 13:44   #8
Тамарочка
Пользователь
 
Регистрация: 19.11.2011
Сообщений: 13
По умолчанию

Большое спасибо за столь подробные ответы.
Очень жаль,что из-за меня разгорелась такая не шуточная дискуссия))
Книгу я прочту,но на этом останавливаться не буду.
Надеюсь что скоро тоже смогу так прекрасно программировать))
Тамарочка вне форума Ответить с цитированием
Старый 20.11.2011, 20:27   #9
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Тут дискуссии нет. Тут есть агрессивная безграмотность. Между прочим безграмотность обычно всегда агрессивна.

Что я вам хотел бы посоветовать. Первое, это измените объявление функции main с void main() на int main(). Стантдартные заголовки в С++ пишутся без указания расширения, то есть вместо, например, <iostream.h> следует писать <iostream>, вместо <stdlib.h> следует писать <cstdlib>. Заголовок <conio.h> остается в своем первоначальном виде, так как он не относится к стандартным заголовкам С++. Это конечно при условии, что у вас достаточно современный компилятор.
Если вы объявили целочисленную константу, задающую размер массива, то ее и надо использовать, а не "магическое" число 15.

Вот, как, например, может выглядеть ваш код.



Код:
 //Одномерный массив
#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <ctime>


int main()
{
   const int n = 15;
   double a[n];

   std::srand( std::time( NULL ) );
   for( int i = 0; i < n; i++)
   {
      a[i] = ( std::rand() % 710  - 400 ) / 10.0;
      std::cout << a[i] << std::endl;
   }

   double sum      = 0.0;
   int count           = 0;
   double product = 0.0;
   bool present     = false;

   for ( int i = 0; i < n; i++ )
   {
      if ( a[i] < 0 )
      {
         sum += a[i];
         count++;
      }
      if ( a[i] > 0 && i % 2 == 0 )
      {
         if ( !present )
         {
            present = true:
            product = 1.0;
         }
         product *= a[i];
      }
   }

   if ( count != 0 ) sum /= count;

   std::cout << "The average of negative numbers = " << sum << std::endl;
   std::cout << "The product of positive even numbers = " << product << std::endl;

   return ( 0 );
}
Если у вас старый компилятор, то укажите заголовки с расширением .h и уберите везде префикс пространства стандартных имен std::

что касается книги по С++, то справочник Шилдта вам не нужен, так как он не предназначен для начального курса по С++. Лучше купите замечательную книгу Дж. Либерти "Освой самостоятельно С++ за 21 день".
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Сыроежка; 20.11.2011 в 21:10.
Сыроежка вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
найти сумму элементов одномерного массива мария 12 Помощь студентам 5 28.05.2011 15:28
суммирование вещ-х элементов одномерного массива... uses_non Паскаль, Turbo Pascal, PascalABC.NET 1 29.04.2011 08:39
заданиT на обработку элементов одномерного массива Васильева Зинаида Помощь студентам 4 19.11.2010 18:55
Запись одномерного массива в столбец Maxx Microsoft Office Excel 7 13.08.2010 20:34
Проблемы с заменой элементов одномерного массива AlexanderIvanov Общие вопросы C/C++ 2 13.04.2010 10:23