Пару логических задач для новичков)
| |
Archido | Дата: Пятница, 27 Апреля 2012, 08:13 | Сообщение # 41 |
Сэнсэй
Сейчас нет на сайте
| Тритон Хех, ты вообще пишешь немного о чем-то своем , при чем не только в этой теме...
Изначально вопрос состоял в том, что приведение ссылок вообще невозможно. При чем это были твои слова. Речи небыло о том, хорошо это или плохо. Итак приведение в С++ возможно с чего угодно и на что угодно. Как оно там работает, хорошо это или плохо - это уже отдельная песня. Скажу только, что если понимать как оно работает - то никаких проблем с использованием таких вещей не будет. Целесообразность - отдельный вопрос, который тут не обсуждается.
Quote (Тритон) Хорошо, допустим строка у тебя длинная и за границу ты не выйдешь Если и выйду, то ничего не будет абсолютно. Инфа 100%
Quote (Тритон) Но функция то значение отдельного байта всё равно уже не способна ни прочитать, ни записать Все можно: Code void swap(int &a, int &b) { char &x = *((char*)&a + 1); x = '7'; }
Quote (Тритон) аргументы у тебя - байты Аргументы - всегда байты
Quote (Тритон) Уж если свопишь подстроки, то выглядеть это должно иначе Я не своплю подстроки, я своплю два символа. Ты до сих пор не понимаешь как работает это конструкция: "a ^= (b ^= (a ^= b & 0xFF) & 0xFF) & 0xFF". Говорить больше не о чем.
Quote (Тритон) нельзя хитрить с регистрами Где и кто хитрит с регистрами? Или кто собирается это делать?
Все остальное, что ты написал - "поучения", как это таки плохо и как нужно это делать правильно. Благодарю бро, я терь просветленный.
P.S. У тебя большая каша в голове и ты "выкладываешь" эту кашу фактически в каждой обсуждаемой теме, при этом не очень хорошо разбираясь, собственно, в вопросах этой темы. Стоит чуток об этом подумать.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
Тритон | Дата: Пятница, 27 Апреля 2012, 09:01 | Сообщение # 42 |
постоянный участник
Сейчас нет на сайте
| Quote (Archido) Все можно: Code
void swap(int &a, int &b) { char &x = *((char*)&a + 1); x = '7'; } При этом ты затрёшь нолями ещё 3 байта. Если они и были по нолям, то всё в порядке. А если нет?
Добавлено (27.04.2012, 09:01) --------------------------------------------- Quote (Archido) Ты до сих пор не понимаешь как работает это конструкция: "a ^= (b ^= (a ^= b & 0xFF) & 0xFF) Ещё смешней. Когла читаешь Code void swap(int &a, int &b); , то за ним представляешь Code void swap(int &a, int &b) { int t; t=a; a=b; b=t; } , действительная реализация должна быть эквивалентно. Если же на самом деле будет Code void swap(int &a, int &b) { int t; t=a; a=(b&0x000000FF)|(a&0xFFFFFF00); b=(t&0x000000FF)|(b&0xFFFFFF00); } , то счастливой отладки функции Code void sort(int *data, int n) { int *i; int *j; int *e; e=data+n-1; for (i=data; i<e; ++i) { for (j=i+1; j<=e; ++j) { if (*i<*j) { swap(*i,*j); } } } } . Порча дважды противоположными образами - не лучшее решение. Своп байтов должен выглядеть, как своп байтов. Зачем приводить байты к адресам двойных слов, чтоб сразу же не явно приводить их к адресам снова байтов?
Не всё так плохо, как оно есть на самом деле.
Сообщение отредактировал Тритон - Пятница, 27 Апреля 2012, 09:06 |
|
| |
warzes | Дата: Пятница, 27 Апреля 2012, 09:44 | Сообщение # 43 |
участник
Сейчас нет на сайте
| блин, какие здесь умники собрались. Первая задача вообще вредная и до сих пор не дан ответ почему так. Поэтому я обязан здесь оставить вот это Code #include <cstdio> class A { public: virtual void p(int n=4) { printf("%d",n); } }; class B : public A { public: virtual void p(int n=4) { printf("%d",n+1); } }; int main() { A* my = new B(); my->p(); delete my; return 0; } На экране будет 5 а не 4. Так что топик стартер - зачем ты новичков вводишь в заблуждение этим: Quote Ответ:потому что сигнатура смотрится по базовому классу,когда вызывается виртуальный метод,а значит и подставляется 0,а не 2. Если не можешь ответить полностью то незачем и спрашивать. А то сейчас новички будут неправильно работать с виртуальными методами думая что вызывается базовый метод
Мой блог Вики DirectX
|
|
| |
Archido | Дата: Пятница, 27 Апреля 2012, 09:54 | Сообщение # 44 |
Сэнсэй
Сейчас нет на сайте
| Тритон Ох, ты меня вообще похоже не слышишь... Как же это сложно.
Quote (Тритон) При этом ты затрёшь нолями ещё 3 байта. Если они и были по нолям, то всё в порядке. А если нет? Code void Replace (int &arg) { char &x = *((char*)&arg + 0); x = 'W'; }
char str[] = "<+>"; Replace( (int&) str[1]); std::cout << str; //str = "<W>"; И где я их затер? Можешь даже в отладчике посмотреть последний байт параметра arg, он каким был - таким и остался.
О чем ты вообще пишешь? Прочитай мой предыдущий пост внимательно, хотя... придется наверное повторить на пальцах: Ты утверждал: "приведение к ссылке на другой размер вообще не возможно". На, что я тебе привел работающий пример, который делает каст сылки одного типа на другой, при этом, выполняя все тот же своп 2-х символов (а не 8-ми) без каких либо последствий. Точка. Дальнейшее бесмысленное обсуждение никакого значения не имеет. Вопрос закрыт.
vasua99 Давай еще задач для "новичков" , а то мы бестолково топчимся на одном месте
warzes Quote (warzes) Первая задача вообще вредная и до сих пор не дан ответ почему так Давно уже ответили . Правильнее вообще так: Code #include <cstdio> class A { public: virtual void p(int n=10) { printf("%d",n); } }; class B : public A { public: virtual void p(int n=20) { printf("%d",n+1); } }; int main() { A* my = new B(); my->p(); delete my; return 0; }
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
Сообщение отредактировал Archido - Пятница, 27 Апреля 2012, 10:10 |
|
| |
warzes | Дата: Пятница, 27 Апреля 2012, 11:48 | Сообщение # 45 |
участник
Сейчас нет на сайте
| Quote (Archido) Давно уже ответили . Правильнее вообще так: будет 10... Почему будет 10 (то есть выполнится A::p())? И почему в моем примере выполнится не A::p() а как раз таки B::p() Я специально привел такой код чтобы показать нестабильность представленного здесь ответа, если он был правильный то получается что этот код: Code #include <cstdio> class A { public: virtual void p(int n=4) { printf("%d",n); } }; class B : public A { public: virtual void p(int n=4) { printf("%d",n+1); } }; int main() { A* my = new B(); my->p(); delete my; return 0; } является исключением? Вот что я имел ввиду под "не вводите новичков в заблуждение неправильными выводами"
... Судя по тому что ты скопипастил с ошибкой, ты не обратил внимание на n+1 - { printf("%d",n+1); } в методе B::p. То есть получилось так - если значения по умолчанию разные то выполняется A::p. А вот если они одинаковые (как у меня) - то выполняется уже B::p. так что я пока не увидел здесь ответа на вопрос...
Мой блог Вики DirectX
Сообщение отредактировал warzes - Пятница, 27 Апреля 2012, 11:54 |
|
| |
Archido | Дата: Пятница, 27 Апреля 2012, 12:08 | Сообщение # 46 |
Сэнсэй
Сейчас нет на сайте
| warzes Советую для начала скомпилить мой код, посмотреть на результат и удивиться. Потом пройтись отладчиком и посмотреть - функция какого класса вызывается и с каким параметром. Далее подумать. После этих процедур уже можно и поумничать
P.S. Результатом там будет 11, а не 10.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
Тритон | Дата: Пятница, 27 Апреля 2012, 15:26 | Сообщение # 47 |
постоянный участник
Сейчас нет на сайте
| Quote (Archido) О чем ты вообще пишешь? О том, что нельзя писать: "Возьми синюю краску в банке с красной этикеткой, преврати её в белую и крась по верх бесцветного лака", да ещё и разбрасывать все эти цвета по десяти томам текста. Читать будет тяжко. Само же "приведение" означает: "Впихни не впихуемое". При этом будет снесена нафиг граница ячейки, что уже чревато. Так делать нельзя, а первая же попытка выполнить внутри "в лоб" любое присваивание затрёт часть данных. Code void f(char &x); ... char s[]="123456789"; f(s[3]); ... void f(int &x) { x=(int)'R'; } даст строку "123R\0\0\089". Зачем извращаться и писать Code x=((int)'R')|(x&0x00FFFFFF); ? Сначала грузим легковушку на платформу для перевозки 42-х тонного зеркала телескопа БТА, потом провозим её на этой платформе через ворота, рассчитанные на проезд легковушки, сносим их нафиг и заново строим, вместо того, чтоб нормально проехать своим ходом. Зачем? Провезти же легковушку таким способом через расситанные на неё ворота без их сноса не возможно.
Добавлено (27.04.2012, 15:26) --------------------------------------------- Нохчи, Archido, я сам способен написать ещё и не такое пособие, как делать не надо. Причём, оно будет работать правильно.
Не всё так плохо, как оно есть на самом деле.
Сообщение отредактировал Тритон - Пятница, 27 Апреля 2012, 15:42 |
|
| | |
Тритон | Дата: Пятница, 27 Апреля 2012, 15:44 | Сообщение # 49 |
постоянный участник
Сейчас нет на сайте
| Code void gauss(double *a, double *b, double *x, int n) { double *i; double *j; double *k; double z; double s; for (i=a; i<=a+(n-2)*n; i+=n) { for (j=i+n; j<=a+(n-1)*n; j+=n) { z=*j/*i; *j=0.0; for (k=j+1; k<j+n; ++k) { *j-=(*i)*z; } b[(j-a)/n]-=b[(i-a)/n]*z; } } for (i=a+(n-1)*n; i>=a; i-=n) { s=0.0; for (k=i+1; k<i+n; ++k) { s+=(*k)*(x[(k-a)/n]); } x[(i-a)/n]=(b[(i-a)/n]-s)/(*i); } } Это решение системы уравнений методом Гаусса, но коэффициенты системы передаются в линейном массиве. Но так делать не надо, потому что не споткнуться на таком тексте способны только автор и компилятор, но не тот человек, который будет читать это в чужой проге и разобраться то разберётся, но время потратит. И после собственного текста только со скаляром и тремя линейными массивами я буду утверждать, что метод Гаусса требует матрицу коэффициентов, а применить его к линейному массиву коэффициентов не возможно. В данном же примере аргумент a - неявная матрица.
Добавлено (27.04.2012, 15:44) --------------------------------------------- Quote (Archido) вот кстати, что есть в С++ стандарте по поводу параметров по умолчанию и виртуальных функций: Под твоим спойлером как раз иллюстрация того, то сигнатура берётся по номинальному классу.
Не всё так плохо, как оно есть на самом деле.
Сообщение отредактировал Тритон - Суббота, 28 Апреля 2012, 06:27 |
|
| |
Archido | Дата: Пятница, 27 Апреля 2012, 15:48 | Сообщение # 50 |
Сэнсэй
Сейчас нет на сайте
| Quote (Тритон) Под твоим спойлером как раз иллюстрация того, то сигнатура берётся по номинальному классу. И чо?
Added: Всякие "сигнатуры", "номинальные классы", тема то для новичков , так, что давай на пальцах
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
Сообщение отредактировал Archido - Пятница, 27 Апреля 2012, 15:52 |
|
| |
Тритон | Дата: Суббота, 28 Апреля 2012, 06:23 | Сообщение # 51 |
постоянный участник
Сейчас нет на сайте
| В одну телегу впрячь нельзя коня и трепетную лань и ламброджина с тягачом не помещаются на общем шасси. Не впихуемое впихнуть можно, но только с разрушениями. Зачем сначала этим заниматься, а потом восстанавливать? И уж тем более ни одному компилятору не придёт в камень приводить символы к длинным интам не явно.
Добавлено (28.04.2012, 06:23) --------------------------------------------- Quote (Archido) Всякие "сигнатуры", "номинальные классы", тема то для новичков , так, что давай на пальцах Куда уж пальцее для виртуальных то функций? Номинальный - это как объявлен объект, или указатель, если в декларации указан базовый, то он совпадает с номинальным, если в декларации указан его потомок, то номинальный уже он, а сигнатуры - это синтаксисы вызовов виртуальных функций. Что сложного? Можно даже не начинать писать, но если краем уха слышал о декларациях данных, иерархии классов и о том, как вообще вызываются функции, то уже должно быть понятно, но сами виртуальные функции могу быть хоть как то понятны разве что новичку в их использовании, но не тому, кто начинает учить основные операторы и программирование линейных алгоритмов. А раз добрался до виртуальных функций, значит иерархию с декларациями может сам рассказать. Попробуй новичку на пальцах рассказать о разработке языков. Не поймет, как ни старайся и сколь простую лексику при этом ни используй. Не поймёт потому, что сама тема разработки языков не новичковая.
Не всё так плохо, как оно есть на самом деле.
Сообщение отредактировал Тритон - Среда, 02 Мая 2012, 15:27 |
|
| |
|