| Другое > Hard'n'Soft |
| Програмирование на C++ |
| << < (17/25) > >> |
| gepar:
Mr2,так а где ты нашёл return ( left * right)? Код всей функции приведи. |
| Mr2:
--- Цитата: gepar от 09 Май 2011, 02:47:55 ---Mr2,так а где ты нашёл return ( left * right)? Код всей функции приведи. --- Конец цитаты --- Не, я поменял местами right и left, и код компилируется. --- Код: ---Matrix operator*(const double left, const Matrix &right) { return (left* right); } --- Конец кода --- но кто их перемножает если не friend Matrix &operator*(Matrix&, const double);? А она по идеи может перемножать только return ( right *left); И то надо уточнить реально ли это.... По идеи ты должен написать код перемножения(числа на данные класса), а не просто умножить объект на какое то число. Вообщем я запутался. :'( Надо самому что нибудь сворганить и разобраться что и как.Потому как надо тестировать все функции а не просто в компиляторе эксперементировать. :( |
| gepar:
Mr2,ну тогда ты меня окончательно запутал при этом мне теперь непонятно почему оно вообще скомпириловалось. Вот смотри это у меня функция для умножения матрицы на число --- Код: ---Matrix& operator*(Matrix &left,const double right) { //результат Matrix& temp(left); for (int i=0;i<left.row;i++) for (int j=0;j<left.column;j++) temp.matrix[i][j]*=right; return temp; } --- Конец кода --- А это матрици на число, логично что я не хотел бы писать всё заново и просто в реализации оператора поменять местами операнды и пусть используется прошлая перегрузка. Да вот только когда ты поменял местами left и right то мне теперь совсем непонятно где же оно нашло перегрузку числа на матрицу (ведь эта перегрузка и написана для этого случая!). --- Код: ---Matrix operator*(const double left, const Matrix &right) { return (left* right); } --- Конец кода --- Добавлено позже: В общем вероятно код с такими исправлениями работать не будет либо работать будет не правильно, сейчас проверим. Добавлено позже: Нашёл ошибку в классе строка, хорошо бы было если бы оно и ругалось на него если в нём ошибка то была <_< Добавлено позже: Такс, после исправления в Row теперь хоть как-то компилируется ну и печатает саму матрицу (знать матрица создаётся по умолчанию/ с параметрами нормально и печатается тоже), умножение конечно же не работает (ещё бы ему работать, я пока не понял как компилятор вообще умудрился принять практически рекурсивный код при перегрузке умножения на число). |
| Mr2:
То есть ты хочешь в одном операторе использовать другой?(в операторе Matrix operator*(const double left, const Matrix &right) вызывается оператор Matrix& operator*(Matrix &left,const double right)?) Честно сказать не в курсе можно ли проделывать такой фокус с операторами. Как я понял оператор : --- Код: ---Matrix operator*(const double left, const Matrix &right) { return (left* right); } --- Конец кода --- вызывает сам себя. Но как он умножает я не понял. Может быть просто возвращяет Matrix &right без изменений.Это нужно программу тестировать. Я перегружал: --- Код: ---Matrix operator*( const Matrix &right,const float left,) { return ( right*left); } --- Конец кода --- И return ( right*left);как у тебя было изначально компилировалась. |
| gepar:
--- Цитата: Mr2 ---Честно сказать не в курсе можно ли проделывать такой фокус с операторами. --- Конец цитаты --- А почему бы и нет? Это ведь логично и выглядит коротко, только где-то опять ошибка закралась, а компилятор уже как следствие её здесь видит. |
| Mr2:
--- Цитата: gepar от 09 Май 2011, 15:05:55 ---А почему бы и нет? --- Конец цитаты --- А ты видел где либо чтоб оператор вызывал свою версию перегруженного оператора?(int*doubl вызывает double*int) --- Цитата: gepar от 09 Май 2011, 15:05:55 ---только где-то опять ошибка закралась, а компилятор уже как следствие её здесь видит. --- Конец цитаты --- --- Цитата: gepar от 09 Май 2011, 15:05:55 ---Это ведь логично и выглядит коротко, --- Конец цитаты --- Видимо ты так укоротил что твоя логика неподсильна компилятору. :lol: |
| gepar:
Mr2,ну так это же не логично писать сначала перегрузку для Класс умножить на double, а потом ещё и отдельно полностью double умножить на Класс. Действие то тоже самое нужно провести только в первом случае класс слева , а во втором класс справа будет от double. Добавлено позже: Нашёл ещё ошибку в перегрузке умножения (логическую конечно), откуда их столько на закрадывалось то. |
| Mr2:
--- Цитата: gepar от 09 Май 2011, 15:26:13 ---Mr2,ну так это же не логично писать сначала перегрузку для Класс умножить на double, а потом ещё и отдельно полностью double умножить на Класс. --- Конец цитаты --- Логика тут не причём. Как я понял для каждого оператора нужна своя реализация.Есть даже перегрузка для i++ и ++i и у каждой своя реализация. Ты гдето видел такую перегрузку как у тебя?или это твои личные выдумки? ;) --- Цитата: gepar от 09 Май 2011, 15:26:13 ---Нашёл ещё ошибку в перегрузке умножения (логическую конечно), откуда их столько на закрадывалось то. --- Конец цитаты --- Я в коде менял местами: --- Код: ---return right.inverted()* (*this); *this= (right.inverted()* (*this)); --- Конец кода --- |
| HoRRoR:
Mr2, ну и я так делаю, и что? Это тоже мои личные выдумки? |
| gepar:
Mr2,нет, я там по строке не той матрицы пошёл под конец. То что ты менял я потом откатил если можно так назвать, тоесть я вернулся к своим старым исходниками. Добавлено позже: Тем не меннее я не понимаю почему я получаю ошибку здесь --- Код: ---Matrix operator*(Matrix &left,const double right) { //результат Matrix temp(left); for (int i=0;i<left.row;i++) for (int j=0;j<left.column;j++) temp.matrix[i][j]*=right; return temp; } Matrix operator*(const double left, const Matrix &right) { return (right*left); //ОШИБКА Matrix.cpp|164|error: no match for 'operator*' in 'right * left'| } --- Конец кода --- HoRRoR,может ты ещё взгляни да скажи где я туплю, ну не понимаю я почему оно не видит перегрузку выше и всё тут. Добавлено позже: Блин, смешно же, как только написал HoRRoR'у только что так и заметил что у меня const во второй же перегрузке, а в первой нет Matrix operator*(Matrix &left,const double right) Matrix operator*(const double left, const Matrix &right) |
| Mr2:
--- Цитата: HoRRoR от 09 Май 2011, 15:40:28 ---Mr2, ну и я так делаю, и что? Это тоже мои личные выдумки? --- Конец цитаты --- Не, я просто не в курсе о том можно ли так делать или нет. ;) --- Цитата: gepar ---Блин, смешно же, как только написал HoRRoR'у только что так и заметил что у меня const во второй же перегрузке, а в первой нет --- Конец цитаты --- Даже и не думал что константа влияет на перегрузку. :blush: |
| gepar:
Задолбался я с этими const, там не хватает, там много, сделал всё что можно const и теперь всё множиться и складывается где нужно (дописывал только const, реализации не трогал), теперь осталось найти ошибку в детерминанте и написать функцию для вычисления ранга. Добавлено позже: Кстати вначале задание казалось легче :D |
| gepar:
В общем курсовую до чт. оформил, допилил и сдал. Получил в итоге 95 за курсовую (наверное преподша не хочет при сдаче ведомости писать max балл), хотя преподша сказала что мол всё идеально хорошо, и 100 за сам курс ООП. Курсовая в итоге получилась самая большая в группе так как с кодом она вышла в 62 страницы :) Теперь можно продолжить в свободное время допроходить Дейтела, я там остановился в последний раз на манипуляторах потока... Добавлено позже: Таааак, у меня чувство дежавю, но спрошу: --- Код: ---# include <iostream> using namespace std; int main() { int ch; int a=3; cout<<"Before: "<<cin.eof()<<endl <<"Enter sometging: "<<endl; while((ch=cin.get())!=EOF) cout.put(ch); cout<<"\nEOF is: "<<ch<<endl; cin>>a; cout<<"\nFuck, A has not been changed: "<<a; cout<<"\nAfter EOF is: "<<cin.eof()<<endl; return 0; } --- Конец кода --- Почему "убивается" последний cin и программа завершается? Я так понимаю символ конца строки у нас остался в потоке и при cin>>a он мешает, но как его убрать тогда? Добавление cin.ignore () перед cin>>a ничего не меняет, да и сколько cin'ов не делай он всё равно я вижу остаётся в потоке до завершения программы, но почему? Добавлено позже: Ещё непонятно почему gcount подсчитывает количество символов только при бесформатном вводе типа cin.read, было бы удобнее если бы он всегда считал. |
| ALEX_230_VOLT:
Я тут тоже курсовик здаю и такой довольно глупый вопрос: вот допустим у меня переменная типа string. В ней текст --- Цитата ---ID 100000 Фамилия: Иванов Имя: Иван Отчество: Иванович Улица: им. Пушкина Дом: 17 Квартира: 26 ID 100000 Фамилия: Иванов Имя: Иван Отчество: Иванович Улица: им. Пушкина Дом: 17 Квартира: 26 ID 100000 Фамилия: Иванов Имя: Иван Отчество: Иванович Улица: им. Пушкина Дом: 17 Квартира: 26 --- Конец цитаты --- вот как мне посчитать сколько раз там встречается сочиатние символов "ID"? ну и на будущее - как научится извлекать из этого сам номер? ну то есть прога видит "ID" и после пробела берёт следующие 6 символов и заносит в новую переменную. кстатитут походу ещё конверсию из string в int придётся делать :-\ |
| HoRRoR:
--- Цитата ---Почему "убивается" последний cin и программа завершается? Я так понимаю символ конца строки у нас остался в потоке и при cin>>a он мешает, но как его убрать тогда? Добавление cin.ignore () перед cin>>a ничего не меняет, да и сколько cin'ов не делай он всё равно я вижу остаётся в потоке до завершения программы, но почему? --- Конец цитаты --- Не понял ни кода, ни вопроса. --- Цитата ---вот как мне посчитать сколько раз там встречается сочиатние символов "ID"? ну и на будущее - как научится извлекать из этого сам номер? ну то есть прога видит "ID" и после пробела берёт следующие 6 символов и заносит в новую переменную. кстатитут походу ещё конверсию из string в int придётся делать --- Конец цитаты --- --- Код: ---#include <cstring> #include <cstdlib> #include <vector> void findIDs(const char *str, vector<int>& ids) { char buf[7] = ""; while(str = strstr(str, "ID")) { str += 3; strncpy(buf, str, 6); ids.push_back(atoi(buf)); } } --- Конец кода --- |
| gepar:
ALEX_230_VOLT,элементарно, Ватсон. Даже писать ничего толком не надо :) --- Код: ---# include <iostream> using namespace std; int main() { char a[]="ID 1043500 bla bla ID 10235400 bla bla ID 12340"; //наша строка char *b; int n; //сколько всего таких ID b=strtok(a,"ID"); cout<<"Our id is: "<<atoi(b); n++; while(b=strtok(NULL,"ID"))//пока у нас ещё есть в строке сочетания символов ID { cout<<"\nOur id is:"<<atoi(b);//Выводим этот ID на печать n++;//увеличиваем счётчик } return 0; } --- Конец кода --- Собственно алгоритм я написал, не забудь учесть что ID то может и не быть вообще в строке твоей то. Добавлено позже: HoRRoR,а если ID больше 6 цифр? Хотя это я думаю уже пусть ALEX_230_VOLT учитывает. --- Цитата: HoRRoR ---Не понял ни кода, ни вопроса. --- Конец цитаты --- Ну вот скомпилируй этот код, в итоге символ конца строки введённый чтобы пройти это --- Код: --- while((ch=cin.get())!=EOF) cout.put(ch); --- Конец кода --- застрянет и --- Код: --- cin>>a; --- Конец кода --- выполняться не будет (оно сразу получает символ конца строки и пропускается). Убедиться в том что символ конца строки остаётся в потоке можно дописав в конце ещё cin.peek(), которая тоже возвращает код конца строки (-1). Как убрать символ конца строки из буфера чтобы можно было и дальше читать символы в таком случае? cin.ignore() не помогает. Добавлено позже: Ещё у меня тут было чудо задание написать на асме обработчик прерываний чтобы клава мигала,а спикер пк пищал. Сколько примеров не находил - не работали они у меня на пк и всё тут. Решил тогда взяться за написание на с++ и за инструмента от майкрософта под винду. Что мы имеем: майкрософт предоставляет вот такие вот возможности, использовать можно где угодно по сути. Но я так до конца со всем и не разобрался: есть клавиша и есть её скан код и вроде бы всё логично, да толкьо в примере сканкод у намлока 0x45, а в таблице кодов на которую есть ссылка там же код 0x45 принадлежит одной из клавиш основного ряда клавиатуры что сразу же меня запутало. Методом тыка и смотря на тот пример создал тогда вот такую прогу и сдал --- Код: --- #include <windows.h> #include <iostream> void SetNumLock( BOOL bState ) { BYTE keyState[256]; GetKeyboardState((LPBYTE)&keyState); if( (bState && !(keyState[VK_NUMLOCK] & 1)) || (!bState && (keyState[VK_NUMLOCK] & 1)) ) { keybd_event( VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 ); keybd_event( VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); } } void SetCapsLock( BOOL bState ) { BYTE keyState[256]; GetKeyboardState((LPBYTE)&keyState); if( (bState && !(keyState[VK_CAPITAL] & 1)) || (!bState && (keyState[VK_CAPITAL] & 1)) ) { keybd_event( VK_CAPITAL, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 ); keybd_event( VK_CAPITAL, 0x14, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); } } void SetScrLock( BOOL bState ) { BYTE keyState[256]; GetKeyboardState((LPBYTE)&keyState); if( (bState && !(keyState[VK_SCROLL] & 1)) || (!bState && (keyState[VK_SCROLL] & 1)) ) { keybd_event( VK_SCROLL, 0x91, KEYEVENTF_EXTENDEDKEY | 0, 0 ); keybd_event( VK_SCROLL, 0x91, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); } } int main() { int count=1000; do { SetNumLock( TRUE ); SetCapsLock(TRUE); SetScrLock (TRUE); SetNumLock( FALSE ); SetCapsLock(FALSE); SetScrLock (FALSE); if (count%50==0) std::cout<<'\a'; count--; }while(count); return 0; } --- Конец кода --- Но до конца так и не разобрался почему же она так странно работает. Вот например начальная версия программы на которой странности лучше заметны --- Код: --- #include <windows.h> #include <iostream> void SetNumLock( BOOL bState ) { BYTE keyState[256]; GetKeyboardState((LPBYTE)&keyState); if( (bState && !(keyState[VK_NUMLOCK] & 1)) || (!bState && (keyState[VK_NUMLOCK] & 1)) ) { // Simulate a key press keybd_event( VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 ); // Simulate a key release keybd_event( VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); } } void SetCapsLock( BOOL bState ) { BYTE keyState[256]; GetKeyboardState((LPBYTE)&keyState); if( (bState && !(keyState[VK_CAPITAL] & 1)) || (!bState && (keyState[VK_CAPITAL] & 1)) ) { // Simulate a key press keybd_event( VK_CAPITAL, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 ); // Simulate a key release keybd_event( VK_CAPITAL, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); } } void SetScrLock( BOOL bState ) { BYTE keyState[256]; GetKeyboardState((LPBYTE)&keyState); if( (bState && !(keyState[VK_SCROLL] & 1)) || (!bState && (keyState[VK_SCROLL] & 1)) ) { // Simulate a key press keybd_event( VK_SCROLL, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 ); // Simulate a key release keybd_event( VK_SCROLL, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); } } int main() { SetNumLock( TRUE ); SetCapsLock(TRUE); SetScrLock (TRUE); int a; std::cin>>a; SetNumLock( FALSE ); SetCapsLock(FALSE); SetScrLock (FALSE); } --- Конец кода --- Если в коде оставить в конце SetScrLock (FALSE) то выключится только scrolLock, а если убрать то выключиться капс и нам лок. Почему так? Я понял что там у нас вроде как идёт какой-то буфер в какой запихывая новые значения мы подпихиваем предыдущие, но всё же чего оно так странно работает-то ? :) Ну это я спрашиваю если кто пробовал таким баловаться, может там себе визуализатор музыки на индикаторы клавиатуры прикрутить пытались или ещё что :) |
| HoRRoR:
--- Цитата ---ALEX_230_VOLT,элементарно, Ватсон. Даже писать ничего толком не надо --- Конец цитаты --- Из пушки по воробьям. --- Цитата ---HoRRoR,а если ID больше 6 цифр? Хотя это я думаю уже пусть ALEX_230_VOLT учитывает. --- Конец цитаты --- Тогда парсить. Что-то вроде --- Код: ---int value = 0; while(*str >= '0' && *str <= '9') { value *= 10; value += (*str - '0'); str++; } --- Конец кода --- --- Цитата ---Ну вот скомпилируй этот код, в итоге символ конца строки введённый чтобы пройти это --- Конец цитаты --- Ещё бы знать, чему у тебя равен EOF. У меня при #define EOF '\n' всё отлично срабатывает. Добавлено позже: Если EOF у тебя -1 и ты ожидаешь конца потока, то как можно что-то считывать после того, как всё закончилось? Естественно, что при достижении конца потока попытка считать что-либо приведёт лишь к ошибке. |
| gepar:
--- Цитата: HoRRoR ---Из пушки по воробьям. --- Конец цитаты --- Ну почему же :) Вполне логично - ищем следующее вхождение ID преобразуем все цифры до первого символа в код ID, потом опять ... так не будем зависить от того сколько там цифр да и логично вроде, ну в общем я бы сделал так. Такую вещь как strstr я пока не использовал и не знал о ней, может с ней и правда удобнее. --- Цитата: HoRRoR ---Ещё бы знать, чему у тебя равен EOF. --- Конец цитаты --- -1 --- Цитата: HoRRoR ---Если EOF у тебя -1 и ты ожидаешь конца потока, то как можно что-то считывать после того, как всё закончилось? --- Конец цитаты --- Я хочу сбросить это состояние потока (помоему я повторяюсь повторяюсь повторяюсь :) ). Вот как пример будет надо сохранить два куска текста с пробелами и переводами каретки в два массива символов --- Код: ---# include <iostream> using namespace std; int main() { int n=127; char ch1[n]; char ch2[n]; cout<<"cin.get in ch1: "; cin.get(ch1,n, EOF); cout<<"/ncin.get in ch2: "; cin.get(ch2,n, EOF); cout<<"/n/nCh1 is: "<<ch1<<"\nCh2 is: "<<ch2; } --- Конец кода --- Так вот закончив ввод первого куска текста через ctrl+Z ввод второго не начнётся (ctrl+Z останется в потоке же), как его убрать оттудова чтобы был возможен ввод и второго куска текста? Ну должен же быть какой-то способ. Добавлено позже: Разобрался что мне нужен не cin.ignore(), а cin.clear() в данной ситуации. |
| HoRRoR:
--- Цитата ---Вполне логично - ищем следующее вхождение --- Конец цитаты --- Ты не ищешь вхождение, ты разбиваешь на лексемы, что абсолютно не нужно в данном случае. Тем более что поиск подразумевает под собой неизменность текста. --- Цитата ---Так вот закончив ввод первого куска текста через ctrl+Z ввод второго не начнётся (ctrl+Z останется в потоке же), как его убрать оттудова чтобы был возможен ввод и второго куска текста? Ну должен же быть какой-то способ. --- Конец цитаты --- Это не символ, это конец потока. Как ты из файла уберёшь конец файла, например? |
| ALEX_230_VOLT:
спасибо что откликнулись, но не сильно это помогло. дело в том, что у меня тип строки string, а НЕ массив из char. хотя покопавшись в инете я смог преобразовать string в char и код gepar заработал. а вот как использовать функцию HoRRoR я что то не понял. можно это сделать не в виде отдельной функции, а как кусок основной программы? ну или обьясни какие параметры ей задавать (ну первый то понятно, а вот второй) |
| Навигация |
| Главная страница сообщений |
| Следующая страница |
| Предыдущая страница |