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

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

#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 пользователей онлайн

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