Перейти к содержанию
СофтФорум - всё о компьютерах и не только

Помогите с C++


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

  • Ответов 169
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Пример (случайные числа будут от 1 до 10, эти пределы определяются числами в функции rand):

#include <iostream>#include <time.h>using namespace std;main(){int i,j,m[3][4]; srand(time(NULL)); for(i=0;i<3;i++)for(j=0;j<4;j++)m[i][j]=rand()%10+1;for(i=0;i<3;i++){for(j=0;j<4;j++){cout.width(5);cout<<m[i][j];}cout<<endl;} cout<<endl; getchar(); }

P.S. Определяются в rand не прямо, например, rand()%10+4 выдавала бы числа от 4 до 13 (остаток от деления какого-то большого случайного числа на 10, он может получаться от 0 до 9, плюс 4).

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

Если написать в объявлении функции следующее:

int func (int x, int y, int *pz, int *pc)

{

........

}

это значит что функция получет 2 переменные х и у и получает два...

О чем говорят звоздочки, о том, что функция получает указатели( т.е. адреса области памяти) или полчует значения, находящиеся по адреса, которые содержат указатели ?

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

...указателя на целые. Она получает аргументы pz и pc, которые, если их разыменовать, то есть считать их адресами, выдадут целые значения.

P.S. То есть, проще говоря, pz и pc и есть адреса целых.

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

daff9000:

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

calc.exe или mspaint.exe запускаются так просто потому, что эти программы лежат в папках, которые командный интерпретатор автоматически просматривает при поиске указанного файла, эти папки можно задать в настройках Windows, исходно это несколько системных папок вроде папки WINDOWS. Если надо запустить произвольную программу, то надо дать в параметре функции system полный путь к выполняемому файлу, чтобы командный интерпретатор его нашел. Например, если Word (это только пример, на самом деле адрес, скорее всего, будет отличаться) имеет полный адрес C:\Office\winword.exe, то вызывать его надо командой system("C:\\Office\\winword.exe"). Знаки \ тут удваиваются из-за правил записи строковых констант в C и C++, потому что знак \ относится к специальным знакам. Если в пути есть папки с пробелами в именах, то еще немного сложнее. Тогда надо указывать либо короткие имена папок (в них нет пробелов), либо использовать, как обычно, длинные имена с пробелами, но передаваемую командному интерпретатору строку заключать в кавычки (и не забыть при этом, что знак кавычек для строковых констант C и C++ также является специальным знаком). Поэтому, если бы тот же Word находился в папке C:\My Office, то есть в имени папки имелся пробел, то вызов Word'а выглядел бы так: system("\"C:\\My Office\\winword.exe\"")

C и C++ - очень мощные, но "нечеловеческие" языки, созданные профессионалами для профессионалов и заполненные всякими исключениями и фокусами, в их синтаксисе легко запутаться.

Спасибо, это понятно.

А скажем если ситуация следующеа:

есть папка, в ней несколько файлов, которые нужно открыть, мы ложем екзэшник в эту же папку. Как сделать, что бы при поиске файлов на открытие, он искал только в этом каталоге?...

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

А скажем если ситуация следующеа:

есть папка, в ней несколько файлов, которые нужно открыть, мы ложем екзэшник в эту же папку. Как сделать, что бы при поиске файлов на открытие, он искал только в этом каталоге?...

Ну, можно довольно запутанными функциями C++ по работе с файлами - пример поиска файлов в папке (со вложенными подпаками или только в этой папке), например, тут. Но куда проще идти по накатанной дорожке - функцией system передать эту задачу командному интерпретатору. Эта функция ведь фактически вызывает имитатор DOS, а в DOS решение таких задач - старинная забава. Теперь окунаемся в DOS. Чтобы файл искался только по заданному пути, надо к имени файла добавить путь к нему. Если этот путь заранее неизвестен, то . в DOS обозначает путь к текущему каталогу, в нашем случае - к тому, в который мы положили экзешник (т.е., например, .\calc.exe укажет искать calc.exe только в той папке, где экзешник).

P.S. При записи этого в строковой константе в C++ надо не забыть экранировать символ \, чтобы он не считался служебным, поставив перед ним второй такой же символ, как об этом я упоминал раньше.

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

#include <iostream>

#include <time.h>

using namespace std;

main()

{

int i,j,m[3][4];

srand(time(NULL));

for(i=0;i<3;i++)

for(j=0;j<4;j++)

m[j]=rand()%10+1;

for(i=0;i<3;i++)

{

for(j=0;j<4;j++)

{

cout.width(5);cout<<m[j];

}

cout<<endl;

}

cout<<endl; getchar();

}

Можно некоторые пояснения по коду, по принцыпу работы ?

т.е. сначала объявляем массив, потому во второй строчке после объявления указываем, что должна вызваться вункция srand(time(NULL));, а что идет дальше ?

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

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

P.S. Функция srand не вырабатывает случайные числа, она просто инициализирует генератор псевдослучайных чисел, используемый функцией rand, значением текущего времени, чтобы при каждом запуске программы функция rand вырабатывала другие псевдослучайные числа. .

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

Эх, не получается у меня разобраться. Мне нужно написать программу, которая выполняет в матрице инвертирование строк( перестановку элементов в обратном порядке) Память под матрицу следует распределять динамически. Нужно так же написать 3 функции:

1-заполнение двумерного массива случайными числами

2-вывод двумерного массива

3-инвертироваия строк...

Подскажите пожалуйста :greedy:

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

daff9000:

на что нужно поделить с остатком и что прибавить чтобы заполнялось из диапазона -100 ,100 ?
Я написал выше:
например, rand()%10+4 выдавала бы числа от 4 до 13 (остаток от деления какого-то большого случайного числа на 10, он может получаться от 0 до 9, плюс 4).
Будем отплясывать от этого. 10, значит, соответствует количеству разных чисел (остаток от деления на 10 может быть 0..9, а, например, от деления на 100 остаток мог бы быть 0..99, то есть 100 чисел).

В диапазоне -100..100 - 201 число. Значит, вместо 10 должно быть 201. Тогда rand()%201, значит, будет выдавать числа от 0 до 200 (почему не до 201: остаток от деления на 201, понятно, не может быть 201 - максимально 200). Теперь надо скорректировать эти числа, чтобы они шли от -100. Вычитаем для этого 100. Числа тогда будут вместо 0..200 в диапазоне -100..+100.

Так что получаем выражение rand()%201-100. Проверяем: при остатке от деления 0 все выражение выдаст -100, при остатке 200 выдаст +100. Где шампанское? :)

Нужно так же написать 3 функции:

1-заполнение двумерного массива случайными числами

2-вывод двумерного массива

3-инвертироваия строк...

Заполнение двумерного массива случайными числами уже сделано в примере выше, вывод двумерного массива тоже.

Инвертирование строк:

""ПОСЛЕДНИЕ БУДУТ ПЕРВЫМИ" - лейтмотив многих притч и высказываний Иисуса Христа, один из краеугольных камней Его учения" (Путеводитель по Библии) - люблю эпиграфы ;)

Напиши строку из пяти чисел, например, инвертируй в ней порядок чисел вручную и опиши, как это делал, на русском языке, а потом переведи в C.

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

Потом так же меняем второе и предпоследнее значения, и т.д.

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

Далее - это надо оформить в виде функций? Нет уж ;) . Пока, во всяком случае. Сначала напиши программу, которая делает это без функций, а потом, когда убедишься, что она работает, оформи отдельные части программы в виде функций. Иди от простого к сложному поэтапно, иначе ошибка будет сидеть на ошибке и погонять опечатками.

Память нужно выделять динамически? Это еще одно усложнение. Когда сделаем функции, переделаем массив в динамический. Или наоборот - переделаем в программе без функций массив в динамический и затем займемся выделением частей программы в функции. Но не все сразу.

Вообще я не совсем понимаю, в чем у тебя трудности? Например, вывод двумерного массива. В работе с несколькими измерениями (вложенные циклы)? Или еще в работе с одномерным массивом? Или еще просто в выводе чисел на экран?

Ну и последнее - я считаю, что это вопросы по изучению программирования. Если нужна просто готовая программа, то есть тема "сделайте все за меня". Если программка простая, то кто-нибудь (может, и я) напишет. Только для понимания языка это даст немного. Обратно на русский программу перевести не легче, чем с русского на C :blush2:

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

Мне как раз нужно понимать язык =)

Вот я написал програмку, которая заполняет массив и выводит его. Как поменять строки местами я представляю, но для простоты, не стал пока писать.

Пытался сделать функции, но не знаю, как передать в функцию массив (


#include <cstdlib>

#include <iostream>

#include "rus.h"

#include <time.h>

using namespace std;

int main()

{

unsigned short int n, m;

srand(time(NULL));

cout << Rus("Укажите размерность массива\n") << "n = " ;

cin >> n;

cout << "m = " ;

cin >> m;

cout << endl;

int massiv[n][m];

// Этот цикл заполняет и выводит массив.

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

{

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

{

massiv[j] = rand()%201-100;

cout << massiv[j] << "\t";

}

cout << endl;

}

char responce;

cin >> responce;

return 0;

}




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

daff9000:

Хорошая программа :) . Только одно замечание. Такая конструкция

cin >> n; cout << "m = ";cin >> m; cout << endl; int massiv[n][m];

нестандартна. По стандарту C++ объявление массивов должно содержать только константные выражения, которые компилятор мог бы посчитать еще при компиляции. Так, как у тебя, будет работать не на всех компиляторах. Правильный путь - использование динамического массива.

Мне нужно написать программу, которая выполняет в матрице инвертирование строк( перестановку элементов в обратном порядке)
Как поменять строки местами я представляю, но для простоты, не стал пока писать.
Непонятно. По мне, инвертирование строки - это запись ее элементов в обратном порядке. Инвертирование строк - то же самое со всеми строками. А поменять строки местами - это инвертирование порядка следования строк. Неясно, что имеется в виду.

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

#include <cstdlib>#include <iostream>#include "rus.h"#include <time.h>using namespace std;void fun(int** b, int n, int m){for (int i=0; i<n; i++) {for (int j=0; j<m; j++){cout.width(7); cout<<b[i][j];} cout<<endl;}}int main(){int n, m;cout<< Rus("Укажите размерность массива")<<endl<<endl;;cout<< "n = "; cin>>n; cout<<"m = "; cin>>m; cout << endl; int** massiv;massiv=new int*[n];for (int i=0; i<n; i++) massiv[i]=new int[m];srand(time(NULL));for (int i=0; i<n; i++)  {for(int j=0; j<m; j++){massiv[i][j]=rand()%201-100; cout.width(7); cout<<massiv[i][j];}cout<<endl;  }cout<<endl; fun(massiv,n,m);for (int i=0; i<n; i++) delete[] massiv[i];delete[] massiv;cout<<endl; system("pause");return 0; }

P.S. в отличие от функций, массивы в C++ - сложная штука, потому что на самом деле они не массивы, а их модели на основе применения операции индексирования к указателям (константным или обычным, в зависимости от того, где объявлены). Поэтому местами и временами они ведут себя весьма странно.

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

Программу я вроде бы написал, все работало до появления последней функции int i_matrix (int **matrix, int n, int m), которая меняет местами элементы каждой троки. Когда программа доходит до вызова этой функции, она зависает. Знаю, что проблема в ошибке сигментации, т.е. с памятью где-то не так работаю, помогите пожалуйста отыскать...

#include <cstdlib>#include <iostream>#include "rus.h"#include <time.h>using namespace std;int w_matrix (int **, int, int);int s_matrix (int **, int , int);int i_matrix (int **, int, int);int main(){int n,m;cout << Rus("Óêàæèòå ðàçìåðíîñòü ìàññèâà\n") << "n = ";	  cin >> n;cout << "m = ";  cin >> m;cout << endl;int **matrix;				matrix = new int *[n];	    for (int i=0;i<n;i++)   {matrix[i]=new int[m];  }w_matrix ( matrix,  n,  m);s_matrix (matrix,  n,  m);i_matrix (matrix, n, m);s_matrix (matrix,  n,  m);char responce;cin >> responce;return 0; }int w_matrix (int **matrix, int n, int m){srand(time(NULL));for (int i=0; i<n; i++)  {for(int j=0; j<m; j++){		matrix[i][j]=rand()%201-100; }  }return 0;  }int s_matrix (int **matrix, int n, int m){for (int i=0; i<n; i++)  {for(int j=0; j<m; j++){		 cout << matrix[i][j];		 cout << "\t";		 }cout << endl;  }return 0;  }int i_matrix (int **matrix, int n, int m){int t;  for (int i=0; i<n; i++){  for (int j=0; j<m/2; j++){t=matrix[n-i][m-j];matrix[n-i][m-j]=matrix[i][j];matrix[i][j]=t;}}return 0;  }
Ссылка на комментарий
Поделиться на другие сайты

С памятью явно не так. На каком элементе заканчивается массив длиной n? На элементе с индексом n-1. Какой элемент в функции i_matrix обрабатывается первым? С индексом n, то есть лежащий за пределами массива. Аналогично для m. Это C++...

Когда пишем n, имеем в виду n-1, если не хуже... :bleh:

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

С памятью явно не так. На каком элементе заканчивается массив длиной n? На элементе с индексом n-1. Какой элемент в функции i_matrix обрабатывается первым? С индексом n, то есть лежащий за пределами массива. Аналогично для m. Это C++...

Когда пишем n, имеем в виду n-1, если не хуже... :bleh:

Я нуб... =)

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

"Нуб (сленг англ. noob, от англ. newbie)

Нуб, в первую очередь, это неопытный пользователь, в отличие от ламера" :g:

( Википедия )

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

"Нуб (сленг англ. noob, от англ. newbie)

Нуб, в первую очередь, это неопытный пользователь, в отличие от ламера" :g:

( Википедия )

спасибо за подкол :) Ламер, так ламер... )

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

daff9000:

Никакого подкола. "в отличие от ламера". Ламер - воинствующий чайник. А нуб - " я еще не волшебник, я еще только учусь". Иногда, правда, применяется для определения назойливого новичка. Но ты написал "нуб" сам. А я хотел заметить, что это нормально.

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

Неожиданно появился такой вопрос: почему, когда в выше приведенной программе мы заполняем массив, то используем в цикле оператор

matrix[j]=rand()%201-100; Ведь matrix - это указатель, разве не нужно исползовать оператор взятия значения - (*), т.е. *matrix[j] = ...

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

Квадратные скобки после matrix - это тоже обозначения операций разыменования ("взятия значений"), только с другим синтаксисом и автоматически проводящих еще и суммирование адресов со значениями, указанными в скобках. Вообще квадратные скобки в C++ - не просто квадратные скобки, а символы определенных операций. Можно то же самое сделать, конечно, и через операции *:

*(*(matrix+i)+j) = rand()%201-100;

Кстати, вместо

matrix[j]

можно было записать и

i[matrix][j]

с тем же успехом. Потому что [] складывают указатель со смещением и разыменовывают результат, а порядок операндов в операции сложения не важен. Один операнд должен стоять слева от открывающей квадратной скобки, а второй справа. Это C++ :(

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

cout.width(5)

В одном из ваших примеров увидел подобное. Интуитивно понял, что это как бы отступ от края =) Но хотелось бы узнать более подробно :g:

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

width по-английски - ширина. Как подсказывает название, cout.width(5) устанавливает для последующего использования вывода через cout ширину поля, куда нужно вывести выводимое значение, то есть сколько позиций оно займет на экране. Под изображение числа отводится 5 позиций, там, где нет цифр или знака, в этих позициях будут стоять пробелы. Очень удобно для того, чтобы выводить числа друг под другом в колонку. Если число не поместится в отводимую ширину поля, поле автоматически увеличится до нужного размера, стройность колонки при этом нарушится, но это на крайний случай - лучше так, чем потерять цифры.

cout.precision(...) устанавливает число цифр после точки в вещественных числах, cout.fill(...) - заполняющий символ вместо пробела. Это всё функции класса cout.

Обычно после каждого вывода установленные этими функциями значения сбрасываются на значения по умолчанию, хотя в C++ многое зависит от конкретного компилятора. Впрочем, никому не возбраняется переписать класс cout под свои желания.

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

Оаботаю все с этой же программой. Переделал ее в классы. Теперь стоит задание:

К предыдущей задаче необходимо добавить операторы : +, =, * на число, когда число находится справа и слева., операторы ввода-вывода.

Только не могу понять, что это значит и как усуществить (

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

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

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

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

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

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

Войти

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

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

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



×
×
  • Создать...