Skocz do zawartości
czara

Sztuczki i kruczki w C - czyli jak zagmatwac kod programu.

Rekomendowane odpowiedzi

O ile sie nie myle operacje sa wykonywane od prawej, wiec bedzie to przypisanie tab[1] = 1 i i = 2 po tej operacji, dobrze ?

 

 

--- edit:

a moze i sie myle, bo gcc powoduje wykonanie tab[0] = 1, wiec wychodziloby wykonywanie operacji od lewej jednak (tymbardziej ze odworcenie miejscami post- i pre- inkrementacji dziala tak jak podalem na poczatku, wiec by sie zgadzalo).

 

---

zeby bylo smieszniej VC++ obydwie wersje wykonuje tak samo, tzn tab[1] = 1

---

BCB podobnie jak VC++...

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

do Megabyte

Jeżeli tab to tablica int-ów to na moje niewprawne oko czytając od prawej:

1) "i" zmieni sie na 1 ...

2) zostanie zapisane do tab[1]

3) zmienna i zostanie zwiekszona do 2.

i z tego co mnie uczono o ANSI C++ to tak właśnie wygląda.

 

do FiDO:

Z tego co pamiętam program w cpp może mieć w sobie (w pliku wykonywalnym) dane (weźmy chociaż selfextracting pliki zip). Ale to trzeba by po kazdej poprawce programu wklejac tam ponownie, wiec nie wiem czy o to chodzi. Oczywiście tłumaczenie na bierząco kodu wykonywalnego raczej nie wchodzi w gre, ale jezeli byłby to plik .o, to można wyfiltrować z tego kod źródłowy. hm. bez operacji plikowych? czyli filtrowanie pliku .o raczej nie wchodzi w gre. jak kedyś znajdziesz to chetnie też spojże :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Z tego co pamiętam program w cpp może mieć w sobie (w pliku wykonywalnym) dane. Ale to trzeba by po kazdej poprawce programu wklejac tam ponownie, wiec nie wiem czy o to chodzi. Oczywiście tłumaczenie na bierząco kodu wykonywalnego raczej nie wchodzi w gre, ale jezeli byłby to plik .o, to można wyfiltrować z tego kod źródłowy. hm. bez operacji plikowych? czyli filtrowanie pliku .o raczej nie wchodzi w gre. jak kedyś znajdziesz to chetnie też spojże :)

No wlasnie sek w tym, ze tam nie bylo takich rzeczy... pure C, wiele z tego nie pamietam, ale kod wygladal imponujaco i opieral sie na samych podstawach, zadnych cudow, to wlasnie bylo w nim takie wyjatkowe. Takie jakby rekurencyjne zrodlo.. nie wiem jak to opisac, trzeba zobaczyc :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

a może po prostu:

printf("for(int i = 0; i < 10; i++) {n");  for(int i = 0; i< 10; i++) {  printf("++i;n");  ++i;}printf("}n");

program który wczytuje plik źródłowy .cpp i przekształca kod (na poczatek caly main) właśnie w taki sposób dałoby się napisać. (uciążliwa będzie tylko kontrola {})

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Odpowiedź do mojego zadania:

Standart języka C++ nie definiuje jaki wynik ma dać ta operacja. Przez to są takie różnice w kompilatorach. Bo kompilator to może zrobić tak:

1. znaleść adres w pamięci pod którym ma zapisać wynik, czyli pod jakim adresem jest tab[0].

2. wykonać operacje po prawej stronie, czyli zwiększamy do jeden.

3. przypisanie i do wcześniej obliczonego miejsca w pamięci

4. na sam koniec zwiększenie i do 2.

 

czylo tab[0]=1

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Kiedys widzialem program, ktory wyswietla swoje zrodla bez korzystania z operacji plikowych oczywiscie. Wtedy moja wiedza byla nikla, jesli nie zerowa, a teraz chetnie jeszcze raz bym przestudiowal sobie ten kod, wie ktos z Was moze gdzie to lezy?  

Pisze w tym topicu, bo tam tez bylo troche ciekawych kruczkow

 

 

main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);}

To tak sżło jeśli dobrze pamietam

[/code]

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Co do nauki "głupot". Nie zgodzę się z Wami. Kiedyś, na pierwszych zajęciach z programowania (podstawy) facet powiedział nam: jeśli sądzicie, że znacie Pascala i umiecie sporo, zapraszam na zaliczenie eksternistycznie. Dam wam parę zadań, jeśli rozwiążecie je poprawnie, macie wszystko z głowy. Niewiele myśląc poszedłem spróbować swoich sił. Wraz ze mną mój kumpel (wiem, że jest dobry) i jeszcze parę innych osób. Koleś nie dał jakichś wyszukanych rzeczy. Dał absolutne podstawy. Nie pamiętam szczegółów, nie potrafiłbym ich teraz przytoczyć. Facet spojrzał na nas i z lekceważeniem rzucił "no i co, orły?". Uwalił nas. To nauczyło mnie, że często ludzie olewają podstawy myśląc, że 'to się jakby co sprawdzi w książce'. To potem wyłazi. Takie sprawdziany z kruczków mają na celu sprawdzenie, czy naprawdę orientujesz się w danym języku. Oczywiście przy założeniu, że sprawdzający nie przegina pały. Jednak jestem daleki od narzekania, że kolesie robią to tylko po to, by leczyć swoje kompleksy.

 

program, ktory wyswietla swoje zrodla bez korzystania z operacji plikowych

Kiedyś Bajtek ogłosił konkurs na napisanie jakiegoś programu. Miał być mały, zgrabny i pocieszny. Ot, programik. I właśnie jedną z nagród zdobył program napisany w Pascalu, który wyświetlał swoją zawartość. Jeśli bardzo Ci zależy FiDO, mogę poszukać tego numeru Bajtka i przepisać ten program.

 

i=0;

tab[i++]=++i;

Moim zdaniem jest to równoważne

tab[0]=2

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeśli bardzo Ci zależy FiDO, mogę poszukać tego numeru Bajtka i przepisać ten program.

Niekoniecznie.. swiat sie nie zawali, pozatym mam wyzej podany kod w C, ktory bardzo mi sie podoba bo jest krotki, a mimo to szokuje :>

i=0;

tab[i++]=++i;

Moim zdaniem jest to równoważne

tab[0]=2
A jednak jest to zalezne od kompilatora, standard ANSI nie przewiduje takich rzeczy, moze to i dobrze, nawet jakby to dzialalo w jednoznaczny spobob, wolalbym ten zapis rozbic na 2 linijki, ale zebym po zajrzeniu do tego po paru miesiacach nie musial sie zastanawiac o co tu chodzi.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Mi się wydawało, że y będzie równe 1, a tu program mi się na VC++.net nie skompilował :evil:

 

Jednak po zmianie na y = x/(*p); jest już ok 8)

 

Co do przykładu:

 

i=0; tab[i++]=++i;

Z tego co pamiętem to w jakiejś książce miałem tłumaczone operatory pre- i postinkrementacji (możliwe, że "Thinking in C++") i wyglądało to tak, że operator preinkrementacji jest wykonywany przed całą linią kodu, a operator postinkrementacji po całej linii kodu.

 

Czyli przykład należałoby interpretować jako:

 

i=0; ++i; //i=1tab[i]=i; // tab[1]=1i++; //i=2

i efekt, postaci tab[1]=1 i i=2 pokazuje VC++.net 2k3

8)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

wole BrainFuck:

+++++++++++>+>>>>++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++<<<<<<[>[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<[>++++++++++[-<-[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<[>>>+<<<-]>>[-]]<<]>>>[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<+>>[-]]<<<<<<<]>>>>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]++++++++++<[->-<]>++++++++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<<<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<-[>>.>.<<<[-]]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+>-]>[<+>-]<<<-]
Wypisuje liczbhy Fib. do 100 ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Kiedyś pisałem mały kurs C++ (nigdy nie ukończony :evil: ) i w jednym z podrozdziałów był taki kod:

 

#include <iostream> using namespace std;  int main(){	const double pi=3.1415;	double *p;	p=(double*)π	*p=14.28;	cout << pi << endl;	return 0;}

 

Czyli stałe nie są stałe :P.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Z innej beczki:

 

(mam nadzieję, że nie zostane z[CIACH!]owany za banalność tego pytania na tym ciekawym poście :P)

 

program ten sie nie kompiluje:

#include <list>using namespace std;class Type{public:  bool operator < ( Type cmp );};bool Type::operator < ( Type cmp1 ){  return 1;}int main(int argc, char* argv[]){  Type a, b;  a < b;  list< Type > l;  l.sort();  return 0;}

problem stwarza l.sort(), a nie sam operator.

komunikat: 'operator<' not implemented in type 'Type' for arguments of the same type

 

rozwiązanie problemu jest proste. wystarczy zadeklarować operator nie jako funkcje składową klasy:

#include <list>using namespace std;class Type{public:};bool operator < ( Type cmp1, Type cmp2 ){  return 1;}int main(int argc, char* argv[]){  Type a, b;  a < b;  list< Type > l;  l.sort();  return 0;}
Pytanie brzmi dlaczego??? co w specyfikacji c++ sprawia że <list> nie "chwyta" operatora z pierwszego programu? może mądrzejsi będą wiedzieli ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeju jeszcze FIDO nie odpowiedzial?

A co ja jestem? Chodzaca specyfikacja C++ ? Oj nie.. daleko mi do tego, baardzo daleko :)

Pozatym zrobilem sobie kilka dni przerwy od forum.

Operatory generalnie zawsze deklaruje sie jako friendy a nie membery ale nie pamietam dlaczego :)

Napewno dlatego, zeby umozliwic sobie przemiennosc dzialan na niektorych z nich (przy roznych argumentach), wiecej nie pamietam :)

 

BTW ten pierwszy przyklad jest poprawny, masz chyba jakis krzywy kompilator, ze tego nie przyjmuje. U mnie sie normalnie kompiluje i odpala.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

tylko ze komunikat: 'operator<' not implemented in type 'Type' for arguments of the same type pamietam byl dosyc standardowy, ksiazkowy taki

bartolomeo: wez jakas ksiazke i przeczytaj jak sie robi operatory, tam bedzie wszystko ladnie wyjasnione :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

ieh. kompilator z Builder`a 6 mam i musze sie na jakis inny przestawic. wiem. ale nie na MS na pewno! :evil: moze djgpp. builder ma jeszcze dodatkowo problemy z szablonami. jak sam definiuje szablony klas i definiuje ciała ich funkcji, to zamiast listy polecen po odwolaniu sie do niektórych obiektów wyskakuje:

[Fatal Error] Unit1.cpp(208): F1004 Internal compiler error at 0xc6549c with base 0xc10000

wszystko sie oczywiscie kompiluje ale musze sam sprawdzac (pamietac) jakie dokładnie funkcje czy pola znajduja sie w tych obiektach... (wygodny jestem :P)

 

bartolomeo: wez jakas ksiazke i przeczytaj jak sie robi operatory, tam bedzie wszystko ladnie wyjasnione :)

niestety moja uboga bibliografia opisuje oczywiscie takie rzeczy jak operatory, ale nie w kontekście STL ani innych bibliotek. Myslalem ze moze to sie rzadzi innymi prawami czy coś (w akcie desperacji probowalem nawet dopisywac extern przed operatorem ;))

 

poza tym ten operator w taki sposób użyty JEST poprawny z punktu widzenia operatorów bo nie interesuje mnie przemienność (typ po obu stronach '<' jest TAKI SAM) Pytałem o kontekst bibiotek. Nie lubie robić czegoś tylko dlatego że "tak powinno sie robić" (zawsze sfriendowane operatory).

 

jeżeli zaś chodzi o sfriendowanie operatorów to rzeczywiście chodzi o przemienność. jeżeli mamy typ wbudowany lub biblioteczny (np int) to jak zrobić by działało int + MojaLiczba? (musielibyśmy funkcje operatorową wpsać w typ int (niemożliwe), lub bawić sie w konwersje niestandardowe (czasochłonne, błędorobne)) Wtedy tak i wtedy funkcje operatorowe+friend sie sprawdzają.

 

mój błąd że nie sprawdziłem na innym kompilatorze zanim nagryzmoliłem tego posta :P sorry

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

no w STLu jest tak samo, nie ma ze inaczej; ze nie robisz "bo tak trzeba" to bardzo dobrze, ja generalnie tez, chyba ze sam tak stierdze, odpisalem jednak by w ogole jakas odpowiedz powstala

no, czyli generalnie nic nie wiemy dalej :D

tylko o to wlasnie chodzi ze mi sie wydaje ze spotkalem sie z tym problemem i on jest jakis podstawowy...

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

DJGPP sie nada.. a jak wolisz windowsowe GUI to Dev-Cpp, prawie ze to samo, oba IDE korzystaja z portow GCC na windowsa.

Ja sprawdzalem powyzszy kod wlasnie GCC :)

Pozatym nie wiem co masz do zarzucenia MS, co jak co, ale akurat to im wyszlo i cale MSVC++ jest bardzo przyjemnym srodowiskiem, jutro sprawdze czy ten kod sie na nim skompiluje :).

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

o nie .. MFC sux :D IMHO VCL od Borlanda jest znacznie lepiej pomyslany i wygodniej sie w nim pisze. A jak juz ma byc cos ze stajni MS to wolalbym sie juz zajac .NET i np. C# (do wyboru jeszcze pare innych jezykow), bedzie to tez bardziej przyszlosciowe, MS teraz ostro promuje .NET i mysle ze za pare lat bedzie to juz jakis standard.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

nie mowiem ze MFC nie sux, mowie tylko ze w nim sie programuje :) na szczescie wchodzi .NET...

problem w tym ze nie chodzi o wygode tylko o rynek i nazedzia, pracodawca kupuje srodowisko, Ty masz robic w tym co kaze a nie w tym co wygodne :) szczegolnie ze Borland kijowo supportuje winde, w visulalu piszesz bezposrednio przy windzie, comach itd, w Borlandzie sie jakos tego nie czuje, jakby wyzejpoziomowy jest

ale fakt, .NETa tez mozna sie uczyc, w sumie lepiej nawet

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie



×
×
  • Dodaj nową pozycję...