[C++] Pytanie o std::

Karolkens

Użytkownik
Dołączył
Luty 6, 2008
Posty
12
Nurtuje mnie jeden problem.

PHP:
#include <iostream>

using namespace std;

int function()
{
        cout << "Funkcja";
        return 0;
}

int main()
{
cout    << " Strumien "         
        << function()           //???
        << endl;                
}
Dlaczego wynikiem takiego programu jest ciąg:
Funkcja Strumien 0
a nie, tak jak by na to wskazywała kolejność:
Strumien Funkcja 0
Pewnie ma to jakieś 'głębsze' korzenie.
Tak czy siak prosiłbym o odpowiedź.
 
Ostatnio edytowane przez moderatora:

grzonu

Były Moderator
Dołączył
Grudzień 26, 2006
Posty
1390
bo pewnie kompilowane to jest do takiej postaci w asmie

call function//wypisuje sie funkcja i do eax przenoszone jest 0
push adres//adres stringu "strumien"
push eax//0 zwrocone przez funkcje
push adres2 //adres \r\n
call cout

nie patrzylem na to jak dokladnie wyglada wywolanie cout bo pewnie jakos inaczej sprawdze zaraz i updatuje temat
ale problem pewnie tkwi w tym ze najpierw wywolywana jest function() a potem dopiero pushowane sa argumenty do cout

//update

wywolanie cout wyglada tak

push parametr
push cout
call operator<<

Zeby bylo tak jak chcesz ty musisz wylaczyc w swoim kompilatorze optymalizacje bo kompilator chce zawsze uproscic kod ale czasem wlasnie tego typu rzeczy przez to robi.
 
Ostatnia edycja:

sinis

Użytkownik
Dołączył
Wrzesień 3, 2006
Posty
958
Inaczej.

Wywołanie masz takie:
cout << " Strumien" << funkcja() << endl;

Każde wywołanie rozpoczyna się od określenia parametrów. Pierwszy parametr to " Strumień", ok, wrzucamy na stos. Żeby określić drugi parametr trzeba wykonać funkcję. No to procesor wchodzi do funkcji, patrzy, o mamy "cout << "Funkcja";", no więc wykonuje to. (na ekranie pojawia się napis "Funkcja") Następnie procesor wykonuje "return 0;". O, owe 0 to wartość funkcji, czyli drugiego parametru! Czyli teraz na stosie jest " Strumien", 0 i endl. No to po wywołaniu couta (a właściwie operatora <<, jak powiedział grzonu) pokazuje się reszta napisu czyli " Strumien 0".
 

grzonu

Były Moderator
Dołączył
Grudzień 26, 2006
Posty
1390
Czyli patrzac z logicznego punktu widzenia to program wykonuje sie źle ale to nie wina kodu tylko kompilatora.
Mozesz jeszcze oprocz wylaczenia optymalizacji wypisacac w ten sposob.
cout << "Strumien";
cout << funkcja() << endl;
 

Boobie

Użytkownik
Dołączył
Lipiec 25, 2008
Posty
195
Czyli przydałby się nowy kompilator do C++ :)
 

sinis

Użytkownik
Dołączył
Wrzesień 3, 2006
Posty
958
Grzonu, wcale nie źle. Popatrz, tam są dwa couty, nie jeden. Jeden odpowiada za wyświetlenie "Funkcja", a drugi działa zaraz po wyjściu z funkcja() i pokazuje " Strumien 0". Wszystko jest OK.
 

5.56

Użytkownik
Dołączył
Luty 1, 2010
Posty
102
A może zamiast grzebać w opcjach kompilatora albo patchować program, nie wystarczyłoby zmienić funkcji, aby nie wywoływała tak brzydko znowu couta, tylko najzwyczajniej w świecie zwracała albo returnem, albo w postaci std;:string tenże tekst?
Z tego co właśnie eksperymentuję to nawet nie trzeba robić niewiadomo, czego, wystarczy:
Kod:
#include <iostream>
#include <string>

std::string Funkcja()
{
	return "Funkcja";
}

int main()
{

	std::cout << "Strumien "
	          << Funkcja()
		  << std::endl;
}
I ja się tam na c++ nie znam, ale "using namespace std;" jest chyba niezbyt optymalnym rozwiązaniem ;x
 

grzonu

Były Moderator
Dołączył
Grudzień 26, 2006
Posty
1390
@up no a gdzie sie podzialo 0 ;)

@sinis
kolejnosc jest z logicznego punktu widzenia taka :
wypisanie "strumien" -> wywolanie funkcji function() i wypisanie jej wyniku -> wypisanie endl
ale kompilator kompiluje to do postaci takiej ze najlpierw wywolywana jest funkcja function() i dopiero pushowany jest jej wynik i wywolywany jest cout
podsumowujac kompilator idzie na latwizne nie biorac pod uwage ze kolejnosc stringow na ekranie bedzie inna.
 

sinis

Użytkownik
Dołączył
Wrzesień 3, 2006
Posty
958
Ha! Nieprawda! Kompilator najpierw określa parametry, a żeby określić parametry musi wywołać function() (zostawia ramkę stosu i w function() pierwszy raz wywołuje couta), potem wraca, wrzuca eax na stos, wrzuca endla i call operator<<.
A właściwie to wygląda trochę inaczej:
ostream& operator<<(...); <- tak wygląda prototyp, czyli to nie jest jako tako wrzucane na stos, a zbierany jest jeden wielki ostream i on jest przekazywany coutowi. (albo od razu wszystko leci do couta).
 

Karolkens

Użytkownik
Dołączył
Luty 6, 2008
Posty
12
A może zamiast grzebać w opcjach kompilatora albo patchować program, nie wystarczyłoby zmienić funkcji, aby nie wywoływała tak brzydko znowu couta, tylko najzwyczajniej w świecie zwracała albo returnem, albo w postaci std;:string tenże tekst?
Z tego co właśnie eksperymentuję to nawet nie trzeba robić niewiadomo, czego, wystarczy:
I ja się tam na c++ nie znam, ale "using namespace std;" jest chyba niezbyt optymalnym rozwiązaniem ;x
Nie martw się, wiem jak wyświetlić stringa po mojej myśli. :) Widziałem przykład w książce i nie rozumiałem tej kolejności wyświetlania. Co do namespace, też nie jestem jakimś ekspertem, ale z tego co wiem, to przestrzenie nazw są jedynie dla wygody programowania i w razie kolizji różnych nazw.

BTW. Ale dysputa nad prostym programem. :D
 

grzonu

Były Moderator
Dołączył
Grudzień 26, 2006
Posty
1390
@sin
ale wywolanie tego jednego couta to w zasadzie 3 wywolania operatora << wiec kompilator moglby najpier wywolac jeden operator potem wywolac function a potem wywolac 2 operatory kolejne :D

Dlatego nie lubie strumieni ... wszystko mieszaja i do tego sa dziurawe :D
 
Do góry Bottom