Перейти к содержанию

Рекомендуемые сообщения

#include "stdafx.h"
#include <iostream>
#include <time.h>
using namespace std;
int i,j;
int l;
void rmatr(int **mas,int p)   // хочу забивать матрицу рандомом, правильно я написал? и растолкуйте как работает srand
{srand(time(NULL));
l=0+rand()%20;
for (i=0; i<p; i++)
{for(j=0;j<p;j++)
{mas[i][j]=l;};};}

void vershini(double p)
{cout<<"Vvedite k-vo vershin";
cin>>p;}

void main ()
{	const int n=100;
int S,k,q;
int D [n][n];
cout<<"Esli hotite random graf vvedite 1\n";
cin>>q;
if(q==1)
{vershini(S);
rmatr(D[n][n],S);}; // как записывать рандом матрицу в D[n][n] ?
cout<<"Znaete li vi pravila vvoda grafa? Esli da, vvedite 1	";
cin>>q;
vershini(S);
if (q==1)
{for (i=0; i<S; i++)
	{for (j=0; j<S; j++)
		{cout << "Vvedite D [" << i <<"]["  << j <<"] element=";
			cin >> D [i][j];};};}
else {cout<<"rassto9nie ot vershini k samoi sebe = 0 \n";
	for (i=0; i<S; i++)
		{for (j=0; j<S; j++)
			{cout << "Vvedite D [" << i <<"]["  << j <<"],\ngde rassto9nie ot versini[" << i <<"] k vershine["  << j <<"] ";
cin >> D [i][j];};};}

cout<<"\n\n";
cout<<"Graf imeet vid:\n";
for (i=0; i<S; i++)
	{	for (j=0; j<S; j++)
			{cout<<D[i][j]<<"  ";}
				cout<<"\n\n";};

for (i=0; i<S; i++)
{for (j=0; j<S; j++)
	{if (D[i][j]==D[i][i])
			{D[i][j]=0;};};}

cout<<"\n\n";
for (i=0; i<S; i++)
{for (j=0; j<S; j++)
	{cout<<D[i][j]<<"  ";}
		cout<<"\n\n";};


cout<<"\n\n";
cout<<"Graf posle vi4islenii";
for (i=0; i<S; i++)
{for (j=0; j<S; j++)
	{cout<<D[i][j]<<"  ";}
		cout<<"\n\n";};
cin>>S;
};

Изменено пользователем Honor
Ссылка на комментарий
Поделиться на другие сайты

Ля... Пхп проще, а курсач нужно писать на с++ ) а у меня проблема с ф-ями и массивами

Прошу помощи.

ПС. Плз только без передачи двумерного массива с помощью указателей в одномерном, ибо это мне не дано понять вообще наверн )

Ссылка на комментарий
Поделиться на другие сайты

Нагибатор_из_Сибири

когда у меня похожие проблему я иду на кафедру свою или чужую и прошу помощу у преподов,которых хорошо знают

 

сходи лучше на консультацию,там тебе больше помогут чем тут

Ссылка на комментарий
Поделиться на другие сайты

немного флуда,но язык c# по мойму намного лучше и легче

Не надо провоцировать на холивар. Один язык для одного, другой для другого.

Ссылка на комментарий
Поделиться на другие сайты

Как этот код должен был выглядеть
#include "stdafx.h"
#include <iostream>
#include <time.h>

using namespace std;
int i,j, l;

void rmatr(int **mas, int p)   // хочу забивать матрицу рандомом, правильно я написал? и растолкуйте как работает srand
{
srand( time(NULL) );
l = 0 + rand()%20;
for (i = 0; i < p; i++)
	for(j = 0; j < p; j++)
		mas[i][j]=l;
}

void vershini(double p)
{
cout << "Vvedite k-vo vershin";
cin >> p;
}

void main ()
{
const int n = 100;
   int S, k, q;
   int D[n][n];

   cout << "Esli hotite random graf vvedite 1\n";
   cin >> q;

   if (q == 1)
   {
   	vershini(S);
   	rmatr( D[n][n], S);
   } // как записывать рандом матрицу в D[n][n] ?

   cout<<"Znaete li vi pravila vvoda grafa? Esli da, vvedite 1    ";
cin>>q;
vershini(S);

if (q == 1)
	for (i = 0; i < S; i++)
		for (j = 0; j < S; j++)
		{
			cout << "Vvedite D [" << i <<"]["  << j <<"] element=";
               cin >> D [i][j];
           }
else 
{
	cout<<"rassto9nie ot vershini k samoi sebe = 0 \n";
       for (i = 0; i < S; i++)
		for (j = 0; j < S; j++)
           {
			cout << "Vvedite D [" << i <<"]["  << j <<"],\ngde rassto9nie ot versini[" << i <<"] k vershine["  << j <<"] ";
			cin >> D [i][j];
           }
}

cout << "\n\n";
cout << "Graf imeet vid:\n";
for (i = 0; i < S; i++)
{    
	for (j = 0; j < S; j++)
		cout<<D[i][j]<<"  ";
	cout<<"\n\n";
}

for (i = 0; i < S; i++)
	for (j = 0; j < S; j++)
		if (D[i][j] == D[i][i])
			D[i][j] = 0;

cout << "\n\n";
for (i = 0; i < S; i++)
	{
		for (j = 0; j < S; j++)
			cout << D[i][j] << "  ";
		cout << "\n\n";
	};


cout << "\n\n";
cout << "Graf posle vi4islenii";

for (i = 0; i < S; i++)
	{
		for (j = 0; j < S; j++)
			cout << D[i][j] << "  ";
		cout << "\n\n";
	}

cin >> S;
}



1. Первое - код пишется красиво. Не для того, чтобы на него по вечерам дрочить, а чтобы его можно было понять. Я твой код 10 минут приводил в порядок(тупо форматировал отступы), чтобы его можно было спокойно прочитать. Сам когда собственные коды годичной давности откроешь - охуеешь.
Учись СРАЗУ писать нормально. Я тебе выше привел пример того, как этот код будет выглядеть в GNU-стиле(форум может гробить размер отступов, каждый отступ 4 символа(1 таб)).

2. После закрывающей скобки блока(фигурной) не ставится точка с запятой - это пустой операнд получается, он нахер не нужен.

3. Если цикл for или условный оператор if состоит только из 1 операнда, не стоит всегда делать блок фигурных скобок - такое "явное" обозначение куска кода должно быть обосновано.

4. Давай переменным говорящие имена. Не S, p, b, k l, а Matrix, Size, temp и т.д. Не знаешь английского - учи и делай их транслитом пока не знаешь. Но учить обязательно.

5. Что делает функция void vershini(double p)? Я так понимаю, что ты хотел, что бы эта функция давала пользователю возможность ввести количество вершин.
При твоем объявлении функции переменная передается по значению, т.е. создается ее копия и ее значение передается в функцию. Все, что происходит с переменной double p внутри функции НИКАК не отразится на переменной S, значение которой в функцию передается.
Если ты хотел, чтобы в S оказалось то, что вводит пользователь в функции, тебе надо было или возвращать это значение функцией, или передавать переменную по ссылке, чтобы можно было ее менять.

В твоем случае получается, что объявляется переменная S, которая остается неинициализированной, и ее значение(случайное, т.к. она не инилиацлизирована) передается в функицю rmatr().

6. Зачем при задании случайного числа ты прибавляешь его к нулю? В чем логика?
l = 0 + rand()%20; эквивалентно l = rand()%20;

Работу функции rand(); курить тут: http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

srand(); генерирует стартовое случайное число основываясь на передаваемом ей параметре. О мелких деталях курить по ссылке что я дал выше.
У тебя неправильно заполняется матрица - она заполняется одним случайным числом, а не каждая ячейка своим. Если ты хотел каждую чейку случайным числом заполнить, то присваивание переменной l случайного числа надо было в цикл пихать.

7. Дальнейший смысл вычислений от меня ускользнул, ибо отсутствие комментариев или постановки задачи превращает понимание этого в мазохизм, чем я не увлекаюсь.

8. Для того, чтобы считать одно число или заполнить матрицу рандомом функция не нужна. Тем более, что вызывается она(rmatr) один раз.

9. З.ы. как ты в double собрался число вершин графа считать? Ваще понимаешь о чем речь?)))

10. З.з.зы. С отступами на форуме вроде все ок. И да, если у тебя переменная в функции константа - в твоем случае имеет смысл ее сделать через дефайн
#define BUF 100

Отдельно хочется пожелать выучить таки динамические массивы, это проще, чем кажется :) Изменено пользователем Хильмек ру
Ссылка на комментарий
Поделиться на другие сайты

спс что расписал.

 

По поводу функции, тольку учусь их использовать.

 

По поводу void vershini, как это возвращать? return p или return s? И как передать по ссылке(комманду знаю, но не понимаю нахоно надо и чем ссыылка от указателя отличается)?

 

9. З.ы. как ты в double собрался число вершин графа считать? Ваще понимаешь о чем речь?))) Всмысле? о_О

#define BUF 100 впервые вижу.

 

У тебя неправильно заполняется матрица - она заполняется одним случайным числом, а не каждая ячейка своим. Если ты хотел каждую чейку случайным числом заполнить, то присваивание переменной l случайного числа надо было в цикл пихать. ээээ?

Ссылка на комментарий
Поделиться на другие сайты

Функция может возвращать значение. Например,

 

int func()

{

return 5;

}

 

i = func();

 

В i будет 5, как несложно догадаться. Можно делать так - т.е. присваиваешь S значение функции ввода(в функции ввода читаешь что пользователь ввел и возвращаешь) и потом уже вызываешь rmatr(blabla, S).

 

Можно передать по ссылке, об этом почитай у Шилдта, я ниже ссылку дам. Можно ваще передать указатель на переменную. Тоже у Шилдта.

 

double - тип данных вещественного числа двойной точности. (float - одинарная). Иными словами - это для дробных, не целых чисел. Число вершин может быть дробным? нет, значит тип должен быть int(integer - целое)

 

#define BUF 100

директива препроцессора, которая на этапе обработки кода ДО компиляции заменяет в тексте везде BUF на 100. Зачем тебе заводить отдельную переменную статическую, тратить память? Раз уж массив делаешь статическим - делай его константного размера, переменная не нужна.

 

У тебя сейчас как делается - есть матрица 100x100. ты вычисляешь случайное число от 1 до 20 (предположим, получилось 7) и после этого в цикле запихиваешь это число в матрицу - любая ячейка в пределах цикла будет иметь значение 7.

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

 

for (int i = 0; i < m; i++)

for (int j = 0; j < n; j++)

matrix[j] = rand() % 20;

 

и заметь, ты экономишь таким образом еще одну переменную.

 

Вообще, рекомендую прочитать справочник Герберта Шилдта по С++, он отлично пишет и понятен, в отличие от того же Страуструпа. Каждую вещь, которую не понимаешь надо искать и читать и понимать. Иначе дальше плохо работающего калькулятора не уедешь))

 

З.ы. Справочник такой:

http://www.kodges.ru/74410-polnyj-spravochnik-po-c.html

Не самоучитель!

 

З.з.ы. Чуть не забыл - выкинь stdafx.h, он нужен только для вижуал студии, если поставлена галочка use precompiled headers. Старайся писать по максимуму на чистом C++ без привязки к платформе или среде - проще будет потом.

Ссылка на комментарий
Поделиться на другие сайты

Ох ссылочка полезная ))

Огромное Спасибо за всё!!

 

Ля. не понимаю как передавать массив через ф-цию без указателя или ссылки, напишите плз?)

Изменено пользователем Honor
Ссылка на комментарий
Поделиться на другие сайты

Сам массив передать в функцию нельзя, можно только указатель на него.

 

int a[10]; // пусть мы уже его чем то заполнили

 

int func(int *i); // указатель

int func(int i[]); // указатель на массив неопределенного размера

int func(int i[10]);// указатель на массив из 10 элементов

int func(int i[24]);// указатель на массив из 24 элементов

 

func(a);

 

Все три определения функции эквивалентны, т.к. в функцию передается указатель на 1-ый элемент массива. Соотв. все изменения в функции ИЗМЕНЯТ сам массив. И не важно, какое число указано в скобках - это ни на что не влияет. Кури книжку что я показал, там все это разжевано буквально в первых 100 страницах

Ссылка на комментарий
Поделиться на другие сайты

"Ага. Я тоже раньше так думал - "знание Basic не помешает", потом "знание Pascal не помешает", потом "знание C++ не помешает", потом "знание PHP+MySQL не помешает", потом "знание ASP не помешает", потом "знание Win2003 Server не помешает", потом "знание FreeBSD не помешает". А теперь я 21-летний дядько, сам живу в серверной, прячу в сервере пиво, ношу с собой оружие - бубен, лечу принтеры наложением рук, а сам мечтаю о мировом господстве и някаю на задержавшихся допоздна на работе сотрудников =)"

Ссылка на комментарий
Поделиться на другие сайты

пытался юзать глобальные переменнные, что бы без указателей, типо выполнилось в ф-ции и сохранилось. Болт. проштудировал темы с ф-ями и указателями - понял насколько я туп, Сделал вывод - забить болт на передачу двумерного массвива в ф-цию. Буду спецом с паяльником :good:

И Вообще, те проги которые пишем мы, можно написать в 2 раза короче без использования ф-ции и онанизма на указатели...

Ссылка на комментарий
Поделиться на другие сайты

Поздравляю. Ты сделал первый шаг к становлению быдлокодером и написанию своего первого действительно хуевого кода :good:

 

Глобальные переменные штука особая, использовать ее надо с осторожностью. Я редко видел случаи, где они очень были нужны.

 

Двумерный массив в функцию передается как любой другой. Внутри обращаешься как к двумерному массиву - это все есть у Шилдта.

 

Если ты не научишься в простых прогах использовать указатели и функции - ты никогда не научишься нормально программировать.

 

Кроме как читать Шилдта (всего, не ограничиваясь нужными главами) могу порекомендовать еще разве что Кернигана и Ричи, но лично мне они помогли мало.

Читай чужой код, как можно больше. И пиши свой, как можно больше. Другого пути научиться нет.

 

З.ы. Когда я начинал, я не мог понять, что такое "int *p". Долго. Такшта через это проходят все.

Ссылка на комментарий
Поделиться на другие сайты

Попробуй использовать карточки. Или листочки. Это - переменная, это ссылка. Важно воткнуть, что есть данные, а что есть ссылка на них.

Ссылка на комментарий
Поделиться на другие сайты

int A[5][5]={8, 2, 3, 6, 1,
			 4, 5, 6, 7, 2, 
			 7, 8, 6, 5, 3,
			 0, 1, 1, 4, 9,
			 2, 9, 2, 7, 2};
int *p[5]; // указатель на массив [5] типа инт. Правильно?
for (int i=0; i<5; i++)
	{p[i]=*&A[i];} // что тут происходит? -_-

Ссылка на комментарий
Поделиться на другие сайты

Неправильно.

 

int A[5][5] - ты создаешь массив 5х5 интов(целочисл.). В памяти он располагается как одномерный массив, т.е. как последовательность интов.

A - это указатель на массив. Точнее, на его первый элемент. В A хранится адерс.

* - оператор разыменовывания указателя, т.е. взятия данных по адресу. *A - взять данные, которые лежат по адресу, написанному в А, т.е. первый элемент массива. Т.е. *А = 8. Поскольку массив расположен в памяти последовательно, то *(A+1) - второй элемент массива, 2. И т.д. Здесь +1 означает +1 элемент, а не +1 к адресу.

& - оператор взятия адреса. Т.е. &А - адрес переменной А, в которой хранится адрес первого элемента массива.

 

Если представить, что у тебя есть пронумерованные листочки - ячейки памяти, и на них есть записи. На первом листочке написано - 8. На втором - 2. На десятом листочке, к примеру, написано "первый листочек". Т.е. 1 и 2 листок хранят данные - цифры, а 10-ый - адрес.

 

Теперь разберем что у тебя написано дальше.

int *p[5] - создается массив. Массив типа int*, т.е. массив указателей на целочисленные переменные. Тип указателя говорит только о том, какие данные хранятся по адресу в указателе. Сам указатель всегда число. Т.е. ты можешь сделать указатель char* на символ и указатель на число int* и присвоить одно другому. В примере с карточками указатель был бы карточкой "число на 1-ой карточке" или "символ на 1-ой карточке". Карточка остается карточкой, вопрос только в том, как ты будешь понимать данные с 1-ой карточки, как число или как символ.

 

итак, массив указателей на инты.

далее цикл, в цикле (отступление - зачем фигурные скобки? у тебя 1 оператор. кроме того, что скобки нечитабельны и создают кашу)

в цикле чудо оператор p=*&A;

p - это i-ый указатель из массива.

A - это i-ый элемент массива объявленного выше. Эквивалентно *(A+i)

&A - адрес i-ого элемента массива.

*&A - данные, которые лежат по адресу i-ого элемента массива. Бинго, это и есть сам i-ый элемент массива.

 

Т.е. ты указателю(где должен храниться адрес) присваиваешь само значение. Что есть неверно.

 

Указатель на массив - это само имя массива. Т.е. A. отдельно его объявлять не надо. Кури Шилдта, у него это оч подробно разобрано

Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...