argon bulletin board
Факултети => Факултет по математика и информатика => Темата е започната от: VooDooMaN в 26.01.2006, 11:15:51
-
Сложен и труден за разбиране или прост и очевиден :)?
Не се ли чувствате горди след като разберете един добре съчетан код спагети :)?
Убеден съм, че има хора които се кефят на операторите за побитово отместване в C++ например :).
-
Искам да чета всичко дето е код.
-
Предпочитам да пиша код, който е качествен. До колко е очевиден, това е субективно. Но ако нещо може да се направи по прост и елегантен начин, винаги предпочитам този подход.
А операторите за побитово отместване не знам що ги намеси. Ако за някой те правят кода "сложен и труден за разбиране", направо не ми се мисли...
Поздрави,
Николай Манчев
-
Лош пример, признавам :).
-
Наистина мн кофти пример :) Кои не обича да чете елентно написан код??? Иначе всичко де що се чете е ОК :-D
-
Обичам да чета мой код, щото си се радвам :mrgreen:
-
Със собствен код е ясно, проблемът основно идва като почне да се чете чужд код :).
-
Едно малко, но хубаво отклонение от темата:
В термините на Java каква ще бъде стойността на i след изпълнението на редове 2 и 3?
1: int i = -1;
2: i >>> 1; // i = ???
3: i++; // i = ???
-
Как по-конкретно ще се изпълни въпросния код?
Ще се изпълни ли въобще?
Примерът е много хубав. Налагало ли ти се е да го ползваш някъде ?
Простете ми за некомпетентността, но въпросния втори ред не ми говори нищо и направо не ми се мисли...
-
Ред 2) i = Integer.MAX_VALUE.
От двоично число с 32 единици получаваме двоично число, което започва с 0 ("нула") и има 31 на брой единици. В рамките на правилата за прав код (това е положително число и правият, обратен и допълнителен код съвпадат), това е точно Integer.MAX_VALUE.
Ред 3) i = Integer.MIN_VALUE
В ред 3 след извършване на аритметичната операция се получава "препълване", което е "препълване" само на пръв поглед. Ако към двоично число, състоящо се от една нула и 31 единици прибавим още една единица получаваме двоично число, състоящо се от една единица и 31 на брой нули. Според правилата на допълнителния код това е точно Integer.MIN_VALUE.
Абсолютно никъде и никога не ми се е налагало да пиша такъв код, това съм го виждал само по разни тестове. На практика ако аз видя такъв код бих уволнил човека, който го е написал. В моя случай - това значи да си подам оставката :)
P.S. Петък е, а и наближава полунощ. Ако не съм дал точно обяснение, моля някой да ме поправи.
-
:) Ето защо не ми се компилира кода - бил е от тестове ;).
-
NO COMMENT!!!!!!!!!! :-D
Ами VooDooMan ако искаш мога да ти посоча някои книшки в които има някъкви базици. Когато преди доста време трябваше да чета и да пробвам някакви примери на Pascal писани от някакъв преподавател може ли да си представиш че половината и повече даваха грешки или изобщо не тръгваха. Виж сега ти.
Поздрави,
Valdorval
-
От Форум :
Ползвайте условния оператор ?
Винаги когато имате случай който може да се интерпретира като:
if(конете_могат_да_летят)
a=уха;
else
a=жалко;
//Го свеждайте до:
a=(конете_могат_да_летят)?уха:жалко;
Изглежда много засукано и сложно и всички ще се впечатляват. Изследвайте внимателно всички условни конструкции, защото възможност за оператор ? може да се крие навсякъде. Можете да го влагате, да го пъхате на най различни места и въобще да правите як и трудно-четим код. Внимавайте обаче с това къде го пъхате. В условия на цикли ще направи програмата по-бавна.
Като цяло не може да ви донесе никаква полза освен по-малко писане. Бързината му е идентична с тази на if структурата.
Гъзария: 6/10
Реална полза: 3/10 //по малкото писане си струва :)
Правете коментар-шаблон
С++ е интересен език. Когато направите шаблонна функция, той не я компилира и въобще не я пипа докато не я извикате. Така че ако имате коментар, който съдържа сорс-код, без да е коментиран сорс-код, е приятно да е шарен като останалите си, изпълняващи се събратя. Пример:
//======================================
template <class T> void
COMMENT
() {
долната функция се използва така
int n=nekva_funkcia()
dolna_funkcia(h);
може да хвърли ексепшън, за това слагайте
и try catch блок
}//=====================================
void dolna_fukcia(int n) {...}
Ще пишете малко повече, обаче е изненадващо приятно да четеш оцветени коментари... :)
Гъзария: 8/10
Реална полза: 2/10
Индексирайте число с указател
Ами тъй като в С и С++, операторът [], в случай че не е предефиниран, просто прибавя едно число (указател), към друго (индекс), можем да правим следните калабалъци:
int ar[10] = {...};
for(int i=0; i<10; ++i)
cout << i[ar];
За съжаление (a може би и за щастие) с двумерни масиви не става. Там операцията е малко по-различна. Друг е въпроса че прави кода ужасно объркан и може да докара до инфаркт някой не достатъчно запознат със тънкостите на езика.
Гъзария: 9/10
Реална полза: 1/10
Правете празни цикли
Поради огромните възможности на for, можем да сместим голяма част от това което трябва да прави в самия него. Например:
//просто
for(int i=0; i<10; ++i)
cout << ar;
//->
for(int i=0; i<10 && (cout << a); ++i);
//сложно
s=x;
for(i=0; i<N; ++i) {
cout << s << ' ';
s+=a;
if(i>5)
a=8;
else
a=10;
}
//->
for(i=0, s=x; i<N && (cout << s << ' '); ++i, s+=a, a=(i>5)?8:10);
Е понякога нещата не е препоръчително да се усложняват толкова, обаче има и случаи, в които е полезно. (Не ме питайте за такива!) Факт е че цели програми могат да се вместят в един for.
Гъзария: 7/10
Реална полза: 3/10
Индексирайте литерали
Стриговите литерали от вида "аз съм стрингов литерал хахахаха", са интересно нещо, защото езикът ги интерпретира като const char*. И както можем да индексираме const char*, така можем и стринговия литерал. С помощта на няколко от горните съвети можем да направим интересна операция за изписване на текст.
int i=0;
while(putchar(i++["О боже! Къде ме набутаха?!?"]));
Гъзария: 9/10
Реална полза: 2/10 //абе аз по принцип не съм фен на литералите за това
Викайте main
За съжаление в С++ тази операция е забранена, обаче С програмистите могат да се повеселят с програми като тази:
int main(int argc)
{
if(argc==0)
return 0;
printf("%d ", main(argc-1))
return argc;
}
И като извикате "ludnica.exe a a a a a a" ще изкара резултат "0 1 2 3 4 5". Яко! Едва ли има и 1 на милион програми, в които това има макар и микроскопичен смисъл (продължавайте да не ме питате за такива!), но все пак изглежда шашаво. Още си спомням с умиление оцъкления поглед, когато видях такова нещо за първи път...
Гъзария: 10/10
Реална полза: 2/10
Естествено има и хиляди други примери за шашав, грозен и безполезен код. Чудесата които можете да направите само с #define са неизброими. Тези по-простички "съвети" ми хрумнаха сега. Ако се сетя още (простички) ще допълня.
П.П. ако случаино съм наръшил някои лиценз сажелявам просто не видях под какъв лиценз са примерите на саита от който ги взех .
иначе те са от : http://sourcecore.net/article.php?id=28
Author : iboB
-
Псевдокод :-D
-
Е, то ако е за простотията... С помощта на едно такова Java класче:
public class Basic {
protected static final class GotoException extends RuntimeException {
private GotoException() {}
}
private static final GotoException gotoEx = new GotoException();
public static int jump=10;
public static void GOTO(int line) {
jump = line;
throw gotoEx;
}
public static void STOP() {
GOTO (-1);
}
public static void PRINT(String s) {
System.out.println(s);
}
public static void PRINT(int i) {
System.out.println(i);
}
public static int[] DIM(int n) {
return new int[n];
}
public static double RND() {
return Math.random();
}
public static int INT(double d) {
return (int)d;
}
}
Може да се напише следното стандартно сортиране на хм... Java или Basic - въпрос на гледна точка :-D
public class Bubble extends Basic {
public static void main(String[] args) {
int I=0;int S=0;int N[] = null;
while(jump != -1) {
try {
switch(jump) {
case 10: N = DIM(10);
case 20: I = 0;
case 30: N = INT(1000 * RND());
case 40: I = I + 1; if (I < 10) GOTO (30);
case 50: S = 1; I = 0;
case 60: if( N < N[I + 1]) GOTO (80);
case 70: int T = N ; N = N[I + 1] ; N[I + 1] = T ; S = 0;
case 80: I = I + 1 ; if (I < 9) GOTO (60);
case 90: if (S == 0) GOTO (50);
case 100: I = 0;
case 110: PRINT (N);
case 120: I = I + 1; if (I < 10) GOTO (110);
case 130: STOP();
}
// if there was no GOTO then we want to end the program
STOP();
} catch(GotoException ex) {
// GOTO was called, and a GotoException has caused the
// control to pass outside of the switch statement
}
}
}
}
Резултат от изпълнението:
82
297
302
353
468
631
689
787
893
981
Предлагам някой друг да му сложи рейтинга за гъзария/реална полза :wink:
Поздрави,
Николай Манчев
-
С колко аспирина е препоръчително да се чете това :?
-
С колко аспирина е препоръчително да се чете това :?
Друго се ползва в случая. Аспиринът е за сутринта :-)
-
Яко! :lol:
Гъзария: 10/10
Кодът на Николай много кефи програмисти, закърмени с класически BASIC, асемблери и машинни езици. Дори след като овладеят Паскал, С и С++, те обичат GOTO, въпреки предупрежденията на смятащите се за "правоверни", че това било "лош стил", "не можело да се чете", "не можело да се поддържа" и др. подобни.
Давам оценка 10 и защото кодът е гъзария навярно и според верните и фанатични поклонници на Вирт и Дейкстра, които настръхват от GOTO, сънуват кошмари от Асемблер, и получават страхова невроза от машинни езици. Съчетанието между JAVA и GOTO за тях е светотатство.
Полезност: 10/10
Чудесно показно за способностите за "езикова мимикрия" и емулация на език от по-ниско ниво чрез език от по-високо, и по този начин - демонстрация на изчислителната пълнота и следствията от нея.
;)
-
tc tc :-D
-
Според мен кодът трябва да е максимално разбираем и ефективен!
-
Чудесно показно за способностите за "езикова мимикрия" и емулация на език от по-ниско ниво чрез език от по-високо, и по този начин - демонстрация на изчислителната пълнота и следствията от нея.
;)
Хм-м-м, може да се поспори по въпроса кой език е на високо и кой на ниско ниво. Дълги години съм програмирал на всякакви видиве BASIC и за мен този език е всичко друго, но не и "език от по-ниско ниво".
А и по какви критерии ще сравняваме двата езика?
Простота на конструкциите? Времето, необходимо за изучаване на езика? Времето, необходимо за написване на пълноценна програма?
И по трите критерия BASIC засега е ненадминат.
Иначе и Java я бива за туй-онуй... :wink:
P.S. Аз съм загубена кауза, и след 30 години за мен BASIC ще си остане Най-Великият Сред Великите Език За Програмиране.
-
Здравей,
Аз имах предвид Бейсик с класически черти:
- Номерирането на редовете и неизбежното GOTO е като на машинен език.
- Няма абстракции за подпрограми и параметри. GOSUB, RETURN и GOTO са аналогични съотв. на JSR, RTS и JMP напр. за 6502, така че програмистът трябва да мисли за разклонените алгоритми както ако пише на маш. език и дори трябва сам да разпределя паметта - номерата на редовете и на кои какво се намира.
- Няма създаване на нови типове и на абстрактни типове данни /освен вграден низ/.
- Само всеобщо видими променливи; половинчата абстракция за "съставен оператор" /което е на един ред.../
- Няма рекурсия.
... :)
По-късните усъвършенствани бейсици и псевдобейсици /като DarkBASIC/ очевидно не са "истинският Бейсик", за който стана дума в "езиковата мимикрия" с Джава.
Поздрави
-
Та като стана дума за асемблер, кой ще отговори на следната "лесна" гатанка:
Какво означава последователността от следните букви и цифри:
B44CCD21
Подсказвам, това е оп-кодът на програма, писана на асемблер за Intel x86 Real Mode.
-
Край на програмата ли?
-
Край на програмата ли?
Точно така:
B44C: MOV AH, 0x4C
CD21: INT 0x21
В рамките на старото DOS API това е най-дългият и елегантен начин да прекъснеш изпълнението на COM или EXE.
Има и още два начина:
CD20: INT 0x20 - Това прекъсване е малко deprecated и извикването му води до изпълнението на гореспоменатата 4-байтова програма само за съвместимост(май така беше... ама и да не е така то кой ли се занимава в днешно време с асемблер :))
RET - Не му помня оп-кода, а и сработва само ако стекът на програмата е празен, при което управлението се предава на всемогъщия COMMAND.COM
Сега си спомням за оня проект с графиката, дето целия курс трябваше да го пишем на асемблер преди 4 години! За щастие на по-модерните зайци, те никога няма да изпитат тръпката от програмиране на толкова ниско ниво! Освен ако някой не се захване с чудовището, наречено MSIL Assembler за .NET Framework (на никого не го препоръчвам, толкова е кофти колкото и изучаването на нормален асемблер, ако изобщо можем да си говорим за норамлен асемблер)!
В името на CTRL, ALT и светия DEL:
ENTER
-
Здравейте,
> ама и да не е така то кой ли се занимава в днешно време с ?асемблер
Кой ли се занимава днес със системните функции на DOS, не с асемблер... ;) Демота, програмиране на графични процесори, любители на ниското ниво, програмисти на микроконтролери и на MenuetOS... :)
>Сега си спомням за оня проект с графиката, дето целия курс
>трябваше да го пишем на асемблер преди 4 години!
Ще споделиш ли нещо повече за тоя проект?
Аз ще споделя статията си "Анализ на почти празен цикъл", в която пиша за тестове на Правец-8М, 8Д, Pentium 90 и Pentium 200 MMX на ниско и високо ниво и с различни машинни езици, асемблери и компилатори. :lol:
http://eim.hit.bg/eim21/analiz_21.htm
http://geocities.com/eimworld/eim21/analiz_21.htm
и "Как се чертае отсечка" в режим $13 с около 75 инструкции на 8086.
http://geocities.com/eimworld/eim22n/eim24/otsechka.htm
И не се въздържам да цитирам поне мъничко от първата статия. :-P
Използвано е юнашко наречие... ;)
-----------
...
"Първият": Правец-8М, 6502/1.018 MHz
За любимия си Емчо съчиних следното стихче на вършачопис, което драгият MONITOR преведе на глаголица:
300: A9 00 LDA #$00, 2
302: 8D 00 50 STA $5000, 4
305: A2 00 LDX #00, 2
307: A0 00 LDY #00, 2
309: EE 00 50 INC $5000, 6
30C: 69 01 ADC 01, 2
30E: C9 10 CMP #$10, 2
310: F0 03 BEQ $0315, 2
312: 4C 09 03 JMP $309, 3
315: A9 00 LDA #00, 2
317: E8 INX, 2
318: E0 10 CPX #$10, 2
31A: F0 03 BEQ $031F, 2
31C: 4C 09 03 JMP $309, 3
31F: A2 00 LDX #00, 2
321: C8 INY, 2
322: C0 10 CPY #$10, 2
324: F0 03 BEQ $329, 2
326: 4C 09 03 JMP $309, 3
329: 20 DD FB JSR $FBDD, 6 (ЗВЪНЧЕ)
32C: 60 RTS, 6
Както се вижда, в него освен празната въртележка, има и увеличаване с единица на клетка от паметта ($309: INC $5000), което е доста тежка казба за 6502 - цели 6 удара на сърцето... Сигурно също се вижда, че натрапващата се шестнайска ($10) е броят повторения и на трите вложени въртележки, следователно:
Общият брой цикления е N*N*N = N^3.
За лесно въвеждане на N бе написано кратко глаголище на личната ми програмистка "Основа" - BASIC.
10 N = 250 (N, M = N*N*N)
20 POKE 783, N
30 POKE 793, N
40 POKE 803, N
50 CALL 768
Като завъртях сметачето на въртележката (1.018 MHz), при N = 250 (M = 250^3 = 15.625E6), то се наигра за около 231.7 секунди, като постигна скорост от около 1018000/231.7 = 67436 врътки/сек. "Брей, не е малко" - си рекох и погледнах стихчето, за да преброя колко казби има във всяка врътка на най-вътрешната въртележка. Пет са, като ги гледам:
309: EE 00 50 INC $5000, 6
30C: 69 01 ADC 01, 2
30E: C9 10 CMP #$10, 2
310: F0 03 BEQ $0315, 2
312: 4C 09 03 JMP $309, 3
Тогава 67346*5 = 336730 казби/сек... Ех, да не беше това INC $xxxx, то изяжда 40% от цялото време (6/15). Все пак, и 67346/сек не са малко за сметачето...
Колко обаче са на BASIC?
5 N = 20
10 I = 0: J = 0; K = 0
20 C = 0
50 FOR I = 1 TO N
60 FOR J = 1 TO N
70 FOR K = 1 TO N
80 C = C + 1
90 NEXT: NEXT: NEXT
100 ?CHR$(7)(ЗВЪН)
Пуснах глаголището при N = 20 и то изглаголи всичко за около 31.2 секунди, или 20*20*20 = 8000; 8000/31.2 = 256/сек. Брей, че бавно... Тогава махнах ред 80, да бъде само празна въртележка, и милото свърши само за 9.2 сек - около 870 врътки/сек.
256/сек, при около 250-350 хил. казби/сек (както установихме по-горе) означава, че мекицата на BASIC изпълнява поне около 1000 казби за всяка врътка...
...
-----------
Поздрави
-
Еееех, Тошо, връщаш ме в сладката прегръдка на детството и добрия стар Правец8-М, монохромния монитор и скапаното, но безценно 5.25" флопи, голямо като гардероб ....
Както и да е, отклонихме се от темата.
Попита за проекта по асемблер. Задачата беше на асемблер да се напише малка програма (в случая игра), която да демонстрира основни познания за езика, пък и не чак толкова основни. Аз и колегата Даводов, заедно с Димитров и Георгиева сътворихме невероятна игра, в която ловец стряля по прелитащи патки. Само дето звук нямаше, но амимацията бе веднъж. Специално създадохме иновативен векторен енджин за графиката (по идея на Даводов). Разбира се за изчертаване на правите и дъгите изполвахме алгоритъма на Бреш, който е възможно най-добрия!
С две думи - беше невероятно приключение и почти съжалявам, че вие няма да се насладите на тръпката :)
А по темата за четимостта на кода - в университета никой не ни учи на работа в екип (или ако има проекти за двама те или се пишат само от единия, или двамата пишат отделни парчета и после сглобяват). За съжаление в реалния свят програмистите много често работят по един и същи сорс, или един трябва да коригира сорс на друг. В този случай е жизненоважно да има накаква (дори елементарна) конвенция и мнооого коментари. По тази причина за мен винаги е било минус изполването на някои "яки" оператори в езици като С++ и Java, като например инициализиране на няколко променливи в скобите на for-цикъла или използването на тернарния оператор (е не винаги) и особено едновременното присвояване на стойност на променлива и тестването й в if() условие. Според мен кода трябва да следва блок - схемата на програмата, а не да се вие по тънките оператори на езика.
А за GOTO: по принцип не съм фен на GOTO-програмирането (където на всеки 2 реда има по някое и друго GOTO), но този оператор представлява една от основните инструкции наред с присвояването, и неговото тотално отричане е меко казано глупаво . Има е случаи, в които използването на едно GOTO спестява писане на доста код и реално прави програмата по-разбираема (глупаво е да се напише безкраен цилъл и в него да се сложи break само и само да не се напише GOTO). Съвсем наскоро имах такъв инцидент ;)
-
Аз и колегата Даводов...
Според Ненка Трайкова за последните 10 години в нашия факултет не е стъпвал никой с фамилия "Даводов", така че, колега Митев, провери си правописа!
Иначе енджина наистина беше жесток! Поддържа цели осем векторни посоки, осем битов цвят и дължина на правата пак от порядъка на 8 бита, което прави 256 пиксела за една отсечка, в това число и по диагонал! Обектът, който трябва да се изчертае се представя като непрекъсната последователност от байтове с променлива дължина, групирани по тройки, при което на енджина само му се указват началните X и Y координати и адресът, на който се намира първия байт от обекта. Тази абстрактност ни позволи да си дефинираме лесно и бързо всякакви обекти и да ги пльосваме където си искаме по екрана , което ни даде достатъчно време да сътворим истински 2D shooter, което като оценки ни донесе общ сбор от 30 точки(в екипа бяхме пет човека, 3 момчета и 2 момичета, друг е въпросът кой е правил нещо и кой е спал).
И това нещо е създадено от хора, които по онова време са били първи курс, по на 18-19 години, при това изцяло на асемблер.
Тошко, ако наистина те интересува, сорсът е писан на TASM, пази ги колегата Димитров, ще му кажа да ги ъплоудне някъде или направо да ти ги прати.
-
Кефите, пичове... :lol:
>заедно с Димитров и Георгиева сътворихме невероятна игра, в която ловец стряля по прелитащи патки."
Хе-хе, може би нещо като "Ловна стрелба" за Правеца? :)
"Поддържа цели осем векторни посоки, осем битов цвят и дължина на правата пак от порядъка на 8 бита, което прави 256 пиксела за една отсечка, в това число и по диагонал!"
Т.е. чертае така:
| -- / \ а не произволни отсечки?
"Тошко, ако наистина те интересува, сорсът е писан на TASM, пази ги колегата Димитров, ще му кажа да ги ъплоудне някъде или направо да ти ги прати."
Да, бих се радвал на всичко възможно, което съхранявате по този проект! :)
>Разбира се за изчертаване на правите и дъгите изполвахме алгоритъма на Бреш, който е възможно най-добрия!
Бреш съкратено от Breshenham ли е или е друг? :)
Поздрави
-
Иначе енджина наистина беше жесток! Поддържа цели осем векторни посоки, осем битов цвят и дължина на правата пак от порядъка на 8 бита, което прави 256 пиксела за една отсечка, в това число и по диагонал...
Като го чета това и направо се забавлявам как различните хора подхождат към едни и същи проблеми... Аз принципно понеже съм мързел и за всяко нещо гледам да намеря някакъв hack, когато писах тоя проект си натворих спрайтовете за анимацията с растерен редактор и после на асемблер си написах само зареждачка от файловете с данните. Никакви енджини, никакви вектори... Цялата работа я свърших за 2 дни. Е, то верно после че на асистента му идваше да ми махне главата, ама нищо не можа да каже - нямаше условие в проекта кое как да се направи :-D
Поздрави,
Николай Манчев
-
Можем да си отворим нова тема "Source treasury", но на първо време го пускам тук :). Днес се натъкнах на следния код:
String strCurrentDate = DateTimeUtils.formatDate(Calendar.getInstance().getTime());
Date currentDate = ParseUtils.parseDate(strCurrentDate);