Symfonia C++ proszę o jaśniejsze wyjaśnienie zadań z rozdziału preprocesor.

0

Witam zaczynam przygodę z programowaniem. Proszę o wyrozumiałość i pomoc.
Mamy w Symfonii C++ standard zadanie Rdz6, Preprocesor:
Mamy taki fragment programu:
#define CZYNNIK(a,b) ((a)/((a)+(b)))
int d=0
while (d<10)
{
cout << "Czynnik = " << CZYNNIK(++d,2.0);
cout<< ", dla d= " << d << endl;
}

Ile razy wykonają się instrukcję pętli. Czy w makrodefinicji jest błąd?

NO i teraz cały problem jest w tym, że gdzieś się pogubiłam. Tzn. odpowiedź jest 5 obiegów pętli (dla d o wartości 5, 6, 7, 8, 9<10).
Jak cały program będzie wyglądał? Pokazuje mi błędy nie bardzo dla mnie zrozumiałe.

#include <iostream>
using namespace std;

#define CZYNNIK(a,b) ((a)/((b)+(b)))
int main()
int d=0;
while(d < 10)
{
cout<<"Czynnik = " <<CZYNNIK (++d, 2.0);
cout<< ", dla d= " << d <<endl;
}
return 0;

1
  1. Dlaczego nikt nie odpowiada w moim wątku?
  2. Jakie błędy, w czym problem? Zadaj konkretne pytanie.
  3. Symfonia uczy C z klasami, a nie C++.
  4. W makrze najprawdopodobniej jest błąd.
  5. Polecam http://4programmers.net/Forum/Spolecznosc/Projekty/266221-nauka_c++_w_nowy_sposob?view=unread
0

znalazłam kilka odpowiedzi do tego zadania wszyscy zapewniaja że makrodefinicja jest poprawna. nie do końca oswoiłam się jeszcze z c++ ale od czegoś chciałam zacząć. Chyba prośbę kieruję, żeby ktoś łopatologicznie wyjasnił mi działanie tego programiku

1
  1. W pierwszym i drugim kodzie makra się różnią.
  2. W drugim ciało funkcji nie jest w klamrach.
  3. W przypadku tego pierwszego makra nie można używać inkrementacji jako argumentu, gdyż CZYNNIK(++d,2.0) zostanie przez preprocesor przerobione na ((++d)/((++d)+(2.0))), a dwie inkremenacje w jednej instrukcji to undefined behavior.
1

W tym programie masz UB - undefined behaviour¹. Wszyscy zapewniający, że jest poprawny najwyraźniej nie mają pojęcia o czym mówią.

Po pierwsze, Twoja odpowiedź nie jest poprawna, bo nawet w najbardziej prawdopodobnym wypadku kod wykona się dla d równych 0,2,4,6 i 8. Co można było sprawdzić po prostu go kompilując i odpalając (lenistwo?) http://melpon.org/wandbox/permlink/nc41zJZnQtz0e6d9

Makro to nic innego jak podmiana tekstu.

cout << "Czynnik = " << CZYNNIK(++d,2.0);

zostaje zamienione na

cout << "Czynnik = " << ((++d)/((++d)+(2.0)));

Masz tutaj dwa niesekwencjonowane przypisania do tej samej zmiennej - UB. http://en.cppreference.com/w/cpp/language/eval_order

¹ pół-żart głosi, że w przypadku UB kompilator może wygenerować dowolny kod i będzie to zgodne ze standardem - zarówno kod robiący to, czego programista się spodziewał, jak i kod formatujący dysk twardy. W przypadku UB prowadzących do (R)CE jest to jak najbardziej możliwe.

0

co do ludzi tylko sprawdzałam odpowiedzi. Nie daje mi jednak spokoju całe zadanie. Korzystam z poleconego CodeBlocks wpisując część tego programu prosto z ksiązki pokazuje ze czgos brak. po tym co ja napisałam poniżej prosi o jakiś inicjator.

0

Odsyłam do Dlaczego nikt nie odpowiada w moim wątku?
Szklana kula w niedzielę nie pracuje.

1

Bo to są fragmenty kodu, nie cały kod, brak: int main()

0

Przepraszam doczytałam teraz. zwyczajnie zapomniałam o klamrach {} z tym, że return musi być przed ostatnia } i chyba cały problem tutaj miałam. ups zabrałam Panu czas

1 użytkowników online, w tym zalogowanych: 0, gości: 1