Другое > 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 я что то не понял. можно это сделать не в виде отдельной функции, а как кусок основной программы? ну или обьясни какие параметры ей задавать (ну первый то понятно, а вот второй)
Навигация
Главная страница сообщений
Следующая страница
Предыдущая страница

Перейти к полной версии