- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
#include <stdio.h>
void swap(long *a,long *b){
*a=(*a<<sizeof(*a)*4);
*a+=*b;
*b=*a ^ *b;
*b=(*b>>sizeof(*a)*4);
*a=(*a<<sizeof(*a)*4);
*a=(*a>>sizeof(*a)*4);
}
int main(){
long a=22807;
long b=1012;
printf("a=%ld b=%ld\n",a,b);
swap(&a,&b);
printf("a=%ld b=%ld\n",a,b);
}
FAIL. (т.к. нормально обменивает только числа в половину разрядности long'а).
P.S. Но реализация понравилась, такого извращения для обмена переменных я еще не видел, поэтому ловите плюс.
> long b=1012;
Автора сгубило неумение писать юнит-тесты
Что вы, это наоборот умение "как составить тесты для неработоспособной программы, чтобы сдать ее неопытному заказчику".
long long int a=-41000L;
long long int b=-5305L;
for(long i=0;i<=1000000L;i++){
printf("before a=%lld b=%lld\n",a,b);
swap(&a,&b);
printf("after a=%lld b=%lld\n",a,b);
swap(&a,&b);
printf("a=%ld b=%ld\n",a,b);
a++;b++;
}
Тогда, чтобы быть честным, запилите цикл до 4000000000 (можно с большим шагом). Баг с потерей старших разрядов один хрен не устранен.
> printf("after a=%lld b=%lld\n",a,b);
Юнит-тест не должен лишний раз показывать промежуточные результаты (разве что если найдет ошибку), а должен показывать результат теста - успех или ошибку. К примеру:
более правильно
#include <stdio.h>
void swap(int *a,int *b){
if(*a<0 & *b<0){
*a*=-1;*b*=-1;
*a=(*a<<sizeof(*a)*4);
*a+=*b;
*b=*a ^ *b;
*b=(*b>>sizeof(*a)*4);
*a=(*a<<sizeof(*a)*4);
*a=(*a>>sizeof(*a)*4);
*a*=-1;*b*=-1;
} else if(*a<0){
*a*=-1;
*a=(*a<<sizeof(*a)*4);
*a+=*b;
*b=*a ^ *b;
*b=(*b>>sizeof(*a)*4);
*a=(*a<<sizeof(*a)*4);
*a=(*a>>sizeof(*a)*4);
*b*=-1;
} else if(*b<0){
*b*=-1;
*a=(*a<<sizeof(*a)*4);
*a+=*b;
*b=*a ^ *b;
*b=(*b>>sizeof(*a)*4);
*a=(*a<<sizeof(*a)*4);
*a=(*a>>sizeof(*a)*4);
*a*=-1;
} else {
*a=(*a<<sizeof(*a)*4);
*a+=*b;
*b=*a ^ *b;
*b=(*b>>sizeof(*a)*4);
*a=(*a<<sizeof(*a)*4);
*a=(*a>>sizeof(*a)*4);
}
}
Да тут не только знак, тут в строке 4 половина разрядов числа a втопку уходит: *a=(*a<<sizeof(*a)*4). Новый вариант в этом плане ничуть не лучше.
> *a*=-1
Красота ;)
error: duplicate ‘short’
Рекомендую сравнить по количеству действий с тем как пишут "тупые", неилитарные кодеры.
А "умные" неилитарные кодеры пишут swap(a, b)
Что-то запамятовал, это какой язык?
Чувак показал пример сортировки пузырьком на своём языке:
правда неоднозначность семантики выяснилась слишком быстро.
http://ideone.com/jJswF
а с auto тоже смысл изменился из C++0x.
Если вы не заметили, то этот новый смысл как раз применяется.
>на register компилятор, насколько я помню, давно уже плюет с высокой колокольни.
Эх, надо было мне код зеленым оборачивать.
http://ideone.com/DzIRA
Даже в былые времена когда регистров было мало, это считалось сомнительным ибо существовал XCHG.
Это же просто головоломка. Зачем к ней так серьезно подходить?
P.S. То что говно - да. И к тому же (по крайней мере на x86) компилятор запилит временную переменную в регистре (если сами a и b не в регистрах), т.к. на x86 нельзя выполнять операции над двумя областями памяти одной командой.
А если они в регистрах, то обмен скорее всего будет в 3 действия через третий регистр.