Четверг, 18 Апреля 2024, 23:51

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 2 из 3
  • «
  • 1
  • 2
  • 3
  • »
Форум игроделов » Программирование » C/C++ » Пару логических задач для новичков)
Пару логических задач для новичков)
НохчиДата: Вторник, 24 Апреля 2012, 15:47 | Сообщение # 21
заслуженный участник
Сейчас нет на сайте
Да погляди же в что происходит отладчике или пошаговом режиме в студии.

Многие вопросы по Windows отпадут, если посмотреть тут
vasua99Дата: Вторник, 24 Апреля 2012, 16:04 | Сообщение # 22
GNU follower
Сейчас нет на сайте
Вот именно,что доступ к компу я временно не имею,а пользуюсь codepad.org.
P.S я не юзаю студию,т.к работаю под линем,а винда для игр только


Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
ТритонДата: Среда, 25 Апреля 2012, 08:21 | Сообщение # 23
постоянный участник
Сейчас нет на сайте
Quote (Apati)
т.к. если а и б в сумме превышают максимально допустимое значение для типа, то будет ошибка
Вот именно. Поэтому этот способ требует сразу двух дополнительных переменных двойной разрядности. А что было в условии?

Добавлено (25.04.2012, 08:13)
---------------------------------------------
Quote (vasua99)
у мея есть предположение что при неявном преобразовани при вызове функции происходит дополнение до 4х
Какое нафиг дополнение 5-ти до 4-х? Где ты нашёл преобразование? Где ты видишь хоть что то неявное? С какого перепугу что то вообще должно неявно дополняться? Явного же дополнения ты не написал.

Добавлено (25.04.2012, 08:21)
---------------------------------------------

Quote (vasua99)
короче смотри целый тип занимает 4 байта,а символ 1 байт, у нас есть строка (любая к примеру) тобишь массив символов.так вот при вызове функции обмена значениями (см выше) происходит неявное преобразование из ссылки на символ (который находится в массиве) в ссылку на целое.Но каким образом оно происходит?
Символ тоже не вещественный. Целый - это просто целый, а не конкретный тип, под ним подразумеваются:
signed small int, signed short int, signed long int, hyper, или их аналоги, char=signed small int. Где обязательное преобразование? я могу написать и так:
Code
void swap (char &x, char &y);
char s[]="Hellow";
swap(s[0],s[4]);
и строка не испортится. Кроме того, приведение к ссылке на другой размер вообще не возможно.


Не всё так плохо, как оно есть на самом деле.

Сообщение отредактировал Тритон - Среда, 25 Апреля 2012, 08:14
НохчиДата: Среда, 25 Апреля 2012, 08:31 | Сообщение # 24
заслуженный участник
Сейчас нет на сайте
Тритон, дурачек, задолбал уже умничать. В функцию кстати два четырехбайтовых аргумента передается кстати(если х86).

Многие вопросы по Windows отпадут, если посмотреть тут
ТритонДата: Среда, 25 Апреля 2012, 09:26 | Сообщение # 25
постоянный участник
Сейчас нет на сайте
Ну да, адрес весит 4 байта. Но строка то весит 5 байт, не считая терминального ноля. Каким образом её можно дополнить до 4-х? А приведение к ссылке на другой размер не возможно, так как ссылка есть синоним и если это синоним байта, то он не может означать сразу 4. Так что это ты дурачок.
Code
small int a,b;
swap (long int &a, long int &b);
swap(a,b);// Ошибка, приведение не возможно
,
Code
uint8_t a,b;
swap (uint32_t &a, uint32_t &b);
swap(a,b);// Ошибка, приведение не возможно
,
Code
small int a,b;
swap (long int a, long int b);
swap(a,b);// Ошибки нет
,
Code
uint8_t a,b;
swap (uint32_t a, uint32_t b);
swap(a,b);// Ошибки нет
.
Code
small int a;
std::cout<<sizeof(a);
выведет 1, а не 4. На том же x86. Мало того, типы small int и char синонимичны, может быть только за исключением текстового ввода/вывода. Но small int - это как раз int.
Quote (Нохчи)
В функцию кстати два четырехбайтовых аргумента передается кстати
Компилировать то пробовал, прежде чем обзываться? 1 байт нельзя передать по ссылке, если функция просит 4. Если int весит 4 байта, а char 1 байт, то такой вызов даже не скомпилируется, он не возможен. Если аргументы передаются по ссылке, а символы весят по одному байту, то в функцию можно передать только однобайтные аргументы. И вообще, к ссылке не приводят, если аргумент - ссылка, то передаётся адрес того, что есть без каких либо фактических преобразований. signed/unsigned может быть ещё приводится, но без фактического преобразования, простой заменой интерпретации значения, то есть приведение к signed портит большие значения, а к unsigned - отрицательные. Да и то надо проверить, приводится ли вообще.
Code
#include <cstdlib>
#include <iostream>
using namespace std;
void swap222(int & a,int& b);
int main(int argc, char *argv[])
{
      char str[] = "Hello";
      swap222(str[0],str[4]);
      cout<<str;
      system("PAUSE");
}
void swap222(int & a,int& b)
{
      int t;
      t=a;
      a=b;
      b=t;
}
Quote
Compiler: Default compiler <br /> Building Makefile: "C:\Projects\cpp\dev\Íîâàÿ ïàïêà\Makefile.win" <br /> Executing make... <br /> make.exe -f "C:\Projects\cpp\dev\Íîâàÿ ïàïêà\Makefile.win" all <br /> g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" <br /><br /> make.exe: *** [main.o] Error 1 <br /><br /> Execution terminated
,
Code
#include <cstdlib>
#include <iostream>
using namespace std;
void swap222(char & a,char& b);
int main(int argc, char *argv[])
{
      char str[] = "Hello";
      swap222(str[0],str[4]);
      cout<<str;
      system("PAUSE");
}
void swap222(char & a,char& b)
{
      char t;
      t=a;
      a=b;
      b=t;
}
вывело
Quote
oellH
.
Code
#include <cstdlib>
#include <iostream>
using namespace std;
void swap(int & a,int& b);
int main(int argc, char *argv[])
{
      char str[] = "Hello";
      swap(str[0],str[4]);
      cout<<str;
      system("PAUSE");
}
void swap(int & a,int& b)
{
      cout<<"!!!!";
}
выводит тот же
Quote
oellH
, но без 4-х восклицательных знаков, то есть void swap(int & a,int& b); не выполняется, а значит ни какие аргументы ей не передаются, выполняется же другая функция.Тот же результат даёт даже
Code
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
      char str[] = "Hellow";
      swap(str[0],str[4]);
      cout<<str;
      system("PAUSE");
}
, что указывает на то, что откуда то снаружи подцепилась функция swap (видимо стандартная), эти не сложные тесты показывают, что она swap(char&, char&);
И ей передаются два однобайтных аргумента. Точнее два четырёхбайтных, но в них валяются только адреса однобайтных. Кстати, Нохчи, мне такой тест не нужен, кроме как для обнаружения готовой функции, мне хватает анализа, а ты на него не способен, что уже говорит о том, что дурачок именно ты. Так ты ещё и не смог оценить свои способности и не догадался провести тесты. А это уже говорит о психическом заболевании.


Не всё так плохо, как оно есть на самом деле.

Сообщение отредактировал Тритон - Среда, 25 Апреля 2012, 09:44
vasua99Дата: Среда, 25 Апреля 2012, 12:36 | Сообщение # 26
GNU follower
Сейчас нет на сайте
Тогда внимание вопрос:почему следующий код корректно работает(по крайне мере у меня компилит и работает правильно):
Code

void swap(int& a,int& b);
char my[] = "Hello";
swap(my[0],my[4]); // !!! char& - > int& - как?
printf("%s",my); // выводит oellH...


Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
НохчиДата: Среда, 25 Апреля 2012, 15:14 | Сообщение # 27
заслуженный участник
Сейчас нет на сайте
Товарищу Тритону видимо совсем плохо стало, попробую объяснить на пальцах. В функцию однобайтовый аргумент передать вообще не возможно, даже если написать так:
Code

char a;
func(a);

будет передан 4-байтовый аргумент, можете называть это дополнением до 4 байт или еще как-то. Это первое. Второе то, что
Code
void swap (char &x, char &y);  
  char s[]="Hellow";  
  swap(s[0],s[4]);

Таки испортит строку(читай #23).
К чему эта лекция из #25 я не понял. В любом случае ничего дельного ты не сказал.

vasua99, вызывается не твоя функция swap.


Многие вопросы по Windows отпадут, если посмотреть тут
ArchidoДата: Среда, 25 Апреля 2012, 15:29 | Сообщение # 28
Сэнсэй
Сейчас нет на сайте
Омг, скока букаф tongue

Quote (Тритон)
Кроме того, приведение к ссылке на другой размер вообще не возможно.


Тритон, Проверяй:

Code

void swap(int &a, int &b) {
         a ^= (b ^= (a ^= b & 0xFF) & 0xFF) & 0xFF;
}

...

char str[] = "Hello";     
swap((int&)str[0], (int&)str[4]);


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Среда, 25 Апреля 2012, 15:30
MatouДата: Среда, 25 Апреля 2012, 15:49 | Сообщение # 29
Исходный коТ
Сейчас нет на сайте
Мой разум отказывается это воспринимать.


SnuuxДата: Среда, 25 Апреля 2012, 15:53 | Сообщение # 30
постоянный участник
Сейчас нет на сайте
Quote (Matou)
Мой разум отказывается это воспринимать.

Аналогично...
НохчиДата: Среда, 25 Апреля 2012, 16:00 | Сообщение # 31
заслуженный участник
Сейчас нет на сайте
Смотрим что будет дальше cool

Многие вопросы по Windows отпадут, если посмотреть тут

Сообщение отредактировал Нохчи - Среда, 25 Апреля 2012, 16:00
vasua99Дата: Среда, 25 Апреля 2012, 18:12 | Сообщение # 32
GNU follower
Сейчас нет на сайте
если вызывается не моя функция,то какая тогда?и еще одно - при таком же раскладе,у с указателями такая же байда?

Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
ТритонДата: Четверг, 26 Апреля 2012, 15:29 | Сообщение # 33
постоянный участник
Сейчас нет на сайте
Quote (vasua99)
Тогда внимание вопрос:почему следующий код корректно работает(по крайне мере у меня компилит и работает правильно):
Потому что есть ещё одна такая функция. Обмен
, кстати, происходит в не зависимости не только от кода функции void swap(int& a,int& b);, но даже от факта её наличия/отсутствия, а код этой функции в любом случае не делает ничего. Кстати, наведи на аргумент в той стоке, где её вызываешь и тебе покажут правильный прототип void swap(T&, T&);, указывающий на то, что функция вообще шаблонная.

Добавлено (26.04.2012, 15:18)
---------------------------------------------
Quote (Нохчи)
В функцию однобайтовый аргумент передать вообще не возможно,
Бред. В функцию
Code
void func(char x)
{
    if (x==(char)0;)
    {
     return (char)1;
    }
    return x*func(x-1);
}
можно передать только однобайтный аргумент и ни какой другой. Так что всё зависит от самой функции.

Добавлено (26.04.2012, 15:21)
---------------------------------------------
Quote (Нохчи)
Таки испортит строку(читай #23).
нет. до свапа s=={'H', 'e', 'l', 'l', 'o', 'w', '\0'}, после свапа s=={'o', 'e', 'l', 'l', 'H', 'w', '\0'}. Где порча?

Добавлено (26.04.2012, 15:24)
---------------------------------------------
Quote (Archido)
Тритон, Проверяй:

Code

void swap(int &a, int &b) {
a ^= (b ^= (a ^= b & 0xFF) & 0xFF) & 0xFF;
}

...

char str[] = "Hello";
swap((int&)str[0], (int&)str[4]);
Про вторую функцию упорно забываем? Я же привёл тесты. Да и & 0xFF означает операцию AND с правым аргументом, приведённым к значению нужного размера. А если бы можно было привести к ссылке на больший размер, то ты бы вылез за границу конкретного данного. Что с массивами происходит при выходе за границу? В переменной просто нет места для лишних байтов и впихнуть их туда нельзя.

Добавлено (26.04.2012, 15:29)
---------------------------------------------
Quote (vasua99)
если вызывается не моя функция,то какая тогда?и еще одно - при таком же раскладе,у с указателями такая же байда?
Читай стандарт, описание диалекта и все подключаемые головы. В одном из этих мест будет ещё один своп.


Не всё так плохо, как оно есть на самом деле.

Сообщение отредактировал Тритон - Четверг, 26 Апреля 2012, 15:30
ArchidoДата: Четверг, 26 Апреля 2012, 15:49 | Сообщение # 34
Сэнсэй
Сейчас нет на сайте
Тритон
biggrin

Какая еще вторая функция? Так не пробовал сделать?
Code

void mycool_swap(int &a, int &b) {   
        a ^= (b ^= (a ^= b & 0xFF) & 0xFF) & 0xFF;   
}   

...   

char str[] = "Hello";       
mycool_swap((int&)str[0], (int&)str[4]);

В функцию передается два 4-байтных Int'a, а не char'a и при чем именно по сылке - раз символы в массиве все таки меняются smile . В теле функции swap никаких приведений типов нет, так, что думай почему оно так wink

Quote (Тритон)
Читай стандарт, описание диалекта и все подключаемые головы

>> подключаемые головы

tongue


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Четверг, 26 Апреля 2012, 15:51
ТритонДата: Четверг, 26 Апреля 2012, 16:24 | Сообщение # 35
постоянный участник
Сейчас нет на сайте
Quote (Archido)
Какая еще вторая функция? Так не пробовал сделать?
Code

void mycool_swap(int &a, int &b) {
a ^= (b ^= (a ^= b & 0xFF) & 0xFF) & 0xFF;
}

...

char str[] = "Hello";
mycool_swap((int&)str[0], (int&)str[4]);

В функцию передается два 4-байтных Int'a, а не char'a и при чем именно по сылке - раз символы в массиве все таки меняются . В теле функции swap никаких приведений типов нет, так, что думай почему оно так

str={'H','e','l','l','o','\0'}, sizeof (str)=6.
Code
str:         {'H','e','l','l','o','\0'}
1-й аргумент:  X   X   X   X
2-й аргумент:                  X    X   XX
Выход за границу массива. Кстати,
Code
union
{
      char x;
      hyper y;
};
void f(hyper &y);
x='q';
f(y);// Здесь нет выхода за границу, но даже это не приведение чара к ссылке на 8 байт (sizeof(hyper)=8), а порча данных.
Привести к ссылке на другой размер не возможно вообще, на другой размер можно привести только к значению. Каким образом - это уже зависит от конкретной реализации оператора приведения, или приводящего конструктора. Бывает и дополнение полями, и дополнение единицами, и можно наворотить ещё много чего.


Не всё так плохо, как оно есть на самом деле.

Сообщение отредактировал Тритон - Четверг, 26 Апреля 2012, 16:41
vasua99Дата: Четверг, 26 Апреля 2012, 16:25 | Сообщение # 36
GNU follower
Сейчас нет на сайте
как вариант отследить адреса функций..)

Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
ArchidoДата: Четверг, 26 Апреля 2012, 16:40 | Сообщение # 37
Сэнсэй
Сейчас нет на сайте
Омг, скока я нового узнал то седня, особенно про "приводящие конструкторы" happy . А в своем примере ты ерунду написал.

Ты мне скажи - ты мой код пробовал запускать? Видел результат? Можешь объяснить почему оно так работает? (или будешь говорить - что не работает? smile ) . И еще раз повторюсь: в теле функции swap никаких приведений типов нет.


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Четверг, 26 Апреля 2012, 16:40
ТритонДата: Четверг, 26 Апреля 2012, 16:49 | Сообщение # 38
постоянный участник
Сейчас нет на сайте
Quote (Archido)
"приводящие конструкторы"
ну если
Code
myclass
{
    public:
    myclass (myclass &x);
};
- копирующий, то как обозвать
Code
myclass
{
    public:
    myclass (int &x);
};
? Подсказка: выполняется функцию не существующего оператора приведения
Code
class int
{
    public:
     operator myclass ();
};
.

Добавлено (26.04.2012, 16:49)
---------------------------------------------

Quote (Archido)
И еще раз повторюсь: в теле функции swap никаких приведений типов нет.
Ты их воткнул в вызов. В явном виде. Но не привёл, а испортил. Символы переставятся сразу четвёрками, если за массивом есть другое данное, то полбеды, ты просто его запоганишь, а если там валяется функция, или память за массивом вообще не доступна приладе, то получишь крах с егогомессагой из системы. Привести же на другой размер нельзя. Значение можно, так как при этом создаётся новое значение уже другого данного, но в случае ссылки это должно быть то же самое данное.


Не всё так плохо, как оно есть на самом деле.

Сообщение отредактировал Тритон - Четверг, 26 Апреля 2012, 16:45
ArchidoДата: Четверг, 26 Апреля 2012, 16:59 | Сообщение # 39
Сэнсэй
Сейчас нет на сайте
Quote (Тритон)
Ты их воткнул в вызов. В явном виде. Но не привёл, а испортил. Символы переставятся сразу четвёрками, если за массивом есть другое данное, то полбеды, ты просто его запоганишь, а если там валяется функция, или память за массивом вообще не доступна приладе, то получишь крах с егогомессагой из системы. Привести же на другой размер нельзя. Значение можно, так как при этом создаётся новое значение уже другого данного, но в случае ссылки это должно быть то же самое данное.

wacko . А вообще, чувак, ты мне нравишься, пиши еще! tongue

Еще раз спрошу - ты смотрел результат выполнения кода? Вот тебе такое:
Code

void mycool_swap(int &a, int &b) {   
   a ^= (b ^= (a ^= b & 0xFF) & 0xFF) & 0xFF;   
}   

...   

char str[] = "Hello bro";   
mycool_swap((int&)str[0], (int&)str[4]);
std::cout << str;

Какой результат получается? Где и что тут портится? Жду новых историй tongue


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Четверг, 26 Апреля 2012, 17:00
ТритонДата: Пятница, 27 Апреля 2012, 07:05 | Сообщение # 40
постоянный участник
Сейчас нет на сайте
Хорошо, допустим строка у тебя длинная и за границу ты не выйдешь. Но функция то значение отдельного байта всё равно уже не способна ни прочитать, ни записать, так как он теперь зависим от соседних, а аргументы у тебя - байты. Уж если свопишь подстроки, то выглядеть это должно иначе. И тогда, понимая, что обрабатываешь данные другого размера, приводи внутри функции к блоку нужного размера, но подразумеваться то уже будет приведение 4-х символьной подстроки к двойному слову. Размер при этом уже совпадает. Речь то не о том, что нельзя хитрить с регистрами, а о том, что отдельный символ не приводится к ссылке на 4 символа. Если же "приводить", то получишь не ожиданные результаты и лишние сложности при чтении. Каждая строчка должна сама отражать решаемую задачу, а чтоб из mycool_swap((int&)str[0], (int&)str[4]); вытянуть задачу, придётся выполнить функцию и посмотреть результат. Хорошо, я способен выполнить её сам, но это относительно простой случай, а в более сложных остаётся пожелать удачного отладочного года, если не избавишься от подобного стиля. Так делать нельзя, это должно быть
Code
void swapby4(char &x, char &y)
{
     uint32_t t;
     t=*(uint32_t *)(&x);
     *(uint32_t *)(&x)=*(uint32_t *)(&y);
     *(uint32_t *)(&x)=t;
}
, либо функция с этим же заголовком и телом из вставки на асме, если охота её оптимизировать. А ни как не то, что ты написал.


Не всё так плохо, как оно есть на самом деле.

Сообщение отредактировал Тритон - Пятница, 27 Апреля 2012, 07:09
Форум игроделов » Программирование » C/C++ » Пару логических задач для новичков)
  • Страница 2 из 3
  • «
  • 1
  • 2
  • 3
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг