Zaloguj się, aby obserwować  
UthersonL

Programowanie - pytania, problemy, przykłady programów

1812 postów w tym temacie

Witam mam problem z podstawami C++ - uczę się tego na konkurs informatyczny (fartem dostałem się do 2 etapu, a tam praca przy komputerze i c++ w wymaganiach). Korzystam z "Kurs C++ Od Zera do gier kodera". Tam autor opisuje wszystko na podstawie Visual C++, a ja korzystam z Dev-C++ i juz przy pierwszym kompilowaniu wywala mi błędy... Miałem wpisać:

// First - pierwszy program w C++
#include <iostream>
#include <conio.h>
void main()
{
std::cout << "Hurra! Napisalem pierwszy program w C++!" << std::endl;
getch();
}


błąd wywala przy znakach otwarcia i zamknięcia, ale wystarczyło zmienić na "[" i "]" i po problemie, tylko że wtedy wywala mi błąd linijkę niżej o "expected ] before ; token" i już kompletnie nie wiem, jak to zmienić, żeby działało...

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 24.03.2008 o 14:03, syriusz.b napisał:

// First - pierwszy program w C++
#include <iostream>
#include <conio.h>
void main()
{
std::cout << "Hurra! Napisalem pierwszy program w C++!" << std::endl;
getch();
}


błąd wywala przy znakach otwarcia i zamknięcia, ale wystarczyło zmienić na "[" i "]"
i po problemie, tylko że wtedy wywala mi błąd linijkę niżej o "expected ] before ; token"
i już kompletnie nie wiem, jak to zmienić, żeby działało...


Mogę jedynie dodać, że łączenie conio i iostream nie jest dobrym pomysłem - nie masz gwarancji kolejności wykonywania buforowanych zapisów na ekran. Znaków [ i ] w tym kodzie przecież nie ma...

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

np tak.

#include<iostream>;
using namespace std;

int main (void)
{
cout << "Hurra! Napisalem pierwszy program w C++! \n";
system ("PAUSE");
return 0;
}

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

No to teraz moja kolei. Mam napisać program w ASSemlberze, który będzie odczytywał liczbę z klawiatury w systemie dziesiętnym i wyrzucać na ekranie tą liczbę w systemie binarnym. Napisałem program który znajdziecie poniżej. Kompiluje tasm.exe - pokazuje ze nie ma błedów. Potem robie exe przy pomocy tlinka i wywala błąd offseta i teraz pytanie co tu jest nie tak ?

dane segment
tekst1 db ''Podaj liczbe dec: '',''$''
tekst2 db 10,13,''Liczba BIN: '',''$''
tekst3 db 10,13,''Zle wprowadziles DEC '',''$''
linia db 10,13, ''$''
max db 6
dlu db ?
buf db 0,0,0,0,0,0


dane ends
stosik segment stack
db 256 dup (?)
stosik ends

program segment
ASSUME ds: dane, ss: stosik, cs: program


start:
mov ax, seg dane
mov ds, ax

mov ah,9
mov dx, offset tekst1
int 21h

mov ah,10
mov dx, offset max
int 21h

xor cx,cx
mov cl,dlu
mov bx, offset buf

petla1:

mov al,[bx]
cmp al,'' ''
jne pom1
mov al,''0''
pom1:

sub al,30h
cmp al,10
jb ok1
jmp blad

ok1:

mov [bx],al
inc bx
loop petla1

xor cx,cx
mov cl, dlu
mov bx, offset buf
mov ax,0


petla2:

mov dx,10
mul dx
add al,[bx]
adc ah,0
inc bx
loop petla2

;AX to co wpisalismy DEC (pierwsza czesc zadania - odczyt hexa)

mov bx,ax


mov ah,9
mov dx, offset tekst2
int 21h

mov cx,16


petla3:

shl bx,1
jc jeden
mov dl,''0''
mov ah,2
int 21h
jmp koniec_p3
jeden:

mov dl,''1''
mov ah,2
int 21h


loop petla3

jmp koniec_p3

blad:

mov ah,9
mov ds, offset tekst3
int 21h

koniec_p3: mov ah,4ch


program ends
end start

Udostępnij ten post


Link to postu
Udostępnij na innych stronach


Dnia 24.03.2008 o 18:50, L33T napisał:

system ("PAUSE");
return 0;
}

Ostatnio na forum C++ dostałem ochrzan za system("PAUSE")
nie powinno się zatrzymywać systemu, lecz napisać
cin.ignore();
getchar();
return 0;
Ja do wczoraj robiłem tak jak Ty czyli system("PAUSE"), ale argumentacja o niepotrzebnym zatrzymywaniu systemu mnie przekonała.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 24.03.2008 o 19:16, pretorianie napisał:

Ostatnio na forum C++ dostałem ochrzan za system("PAUSE")
nie powinno się zatrzymywać systemu, lecz napisać
cin.ignore();
getchar();
return 0;
Ja do wczoraj robiłem tak jak Ty czyli system("PAUSE"), ale argumentacja o niepotrzebnym
zatrzymywaniu systemu mnie przekonała.

Zatrzymaniu systemu?! O_o

Co za kompletna bzdura. Funkcja system() powoduje wykonanie polecenia tak, jakby wykonywało się je z linii poleceń. Pause wcale nie zatrzymuje systemu - to komenda, która opróżnia bufor klawiatury po czym wykonuje dokładnie to, co robi getch() - czyta wejście konsoli (dane z bufora klawiatury).

Nie wiem na jakim forum Ci taką ciemnotę cisną, ale lepiej go nie odwiedzaj.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

o lol ciekawe :P
System("Pause") zatrzymuje twój program który masz odpalony i czeka aż depniesz klawisz.
getch() to natomiast artefakt made by borland, zwróć uwagę że przed użyciem dodajesz cin.ignore bez tego getch() zwróci ci wartość klawisza który wciśniesz.

Nie wiem kto cię uczył i gdzie piszesz ale na początek można spokojnie korzystać z biblioteki standardowej bez konieczności dołączania czegokolwiek. Bo początkujący ma z tym więcej zamieszania niż trzeba.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 24.03.2008 o 20:41, L33T napisał:

o lol ciekawe :P
System("Pause") zatrzymuje twój program który masz odpalony i czeka aż depniesz
klawisz.
getch() to natomiast artefakt made by borland, zwróć uwagę że przed użyciem dodajesz


Jesteś pewien? Przeprowadźmy prosty eksperyment. Skompilowany program:

#include <stdlib.h>
int main(int argc, char *argv[])
{
system("pause");
return 0;
}

Uruchamiamy w debuggerze.
windbg D:\projects\syspau\debug\syspau.exe

Ruszam (g). Kiedy wyświetla się komunikat "Aby kontynuować, naciśnij dowolny klawisz . . ." ctrl+break i ~*kn. Interesujący fragment:

00 0012fcdc 7633c732 ntdll!KiFastSystemCallRet
01 0012fcf0 6cb87ed9 kernel32!WaitForSingleObject+0x12
02 0012fd9c 6cb84aa6 MSVCR80D!system+0x569
03 0012fdc8 6cb84840 MSVCR80D!spawnve+0x5e6
04 0012fe18 6cb87a6a MSVCR80D!spawnve+0x380
05 0012fe58 004113cb MSVCR80D!system+0xfa
06 0012ff30 00411966 syspau!main+0x2b [d:\projects\syspau\syspau\main.cpp @ 5]
...

Wywołano MSVCR80D!spawnve, czyli powstał nowy proces. OK, .restart i breakpoint na MSVCR80D!spawnve (bm MSVCR80D!spawnve). g, kilka razy p, widzę interesujący fragment:

MSVCR80D!spawnve+0x6:
6d4b44c6 8b450c mov eax,dword ptr [ebp+0Ch] ss:0023:0012fe24=002b19c8

Wykonuję dump pamięci spod 002b19c8 i widzę:
0:000> db 002b19c8
002b19c8 43 3a 5c 57 69 6e 64 6f-77 73 5c 73 79 73 74 65 C:\Windows\syste
002b19d8 6d 33 32 5c 63 6d 64 2e-65 78 65 00 fd fd fd fd m32\cmd.exe.....

Czyli miałem rację - uruchomione zostanie cmd a w nim (prawdopodobnie) pause. Ok, niech program ruszy. Odpalam drugi debugger i podpinam się pod proces cmd.exe.
tasklist |findstr cmd
cmd.exe 6116 Console 1 2 464 KB
windbg -p 6116

0:001> ~* kn
00 001af73c 7639746d ntdll!KiFastSystemCallRet
01 001af828 7639759d kernel32!InvalidateConsoleDIBits+0x1b0
02 001af848 7647c8b7 kernel32!ReadConsoleInputA+0x1a
03 001af888 7647c9ae msvcrt!filelengthi64+0x606
04 001af8bc 49fdac77 msvcrt!getch+0x1d
05 001af8d0 49fc1e6f cmd+0x1ac77
06 001afd2c 49fc1d0d cmd+0x1e6f
07 001afd7c 49fc74b2 cmd+0x1d0d
08 001afdc0 49fc8d3d cmd+0x74b2
09 001afe04 76331d02 cmd+0x8d3d
0a 001afe10 775685eb kernel32!BaseThreadInitThunk+0x12
0b 001afe50 775685be ntdll!RtlInitializeExceptionChain+0x64
0c 001afe68 00000000 ntdll!RtlInitializeExceptionChain+0x37

O, patrz co jest na stosie - msvcrt!getch, niebywałe, prawda? Czyli jednak system("pause") wywołało w końcu getch...

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Dobrze zgodzę się że system("Pause") wywoła getch() z tym że zachowa nam się to inaczej niż sam golusieńki getch().

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 24.03.2008 o 21:09, L33T napisał:

Dobrze zgodzę się że system("Pause") wywoła getch() z tym że zachowa nam się to
inaczej niż sam golusieńki getch().

Możesz zdefiniować "inaczej"? getch() to getch() - to, że spawnuje się nowy proces nie zmienia jego działania. Jasne, system-pause nie jest optymalnym sposobem na zatrzymanie programu (szczególnie jeśli już się używa cin i cout) ale nie zmienia to faktu, że wciąż jest to getch(). :-)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

getch() nie należy do C++ tylko do C (chyba, głowy nie dam).
A przez inny rozumiem konieczność dodania cin.ignore lub cin.flush() a dla pauzy można dodać while(getchar() != ''\n'');

jeśli @syriusz.b pisze to na windzie to nie ma problemu i niech korzysta z system("Pause") które jest zgodne z standardem.

jeśli na linuxie to musi sobie radzić za pomocą getch() :)

Peace.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

int main()
{
int a;
cout<<"Podaj liczbe: "<< endl;
cin>> a;
cout<<"Podana liczba to: "<< a<<endl;
system("PAUSE");
return 0;
}
I tutaj kończy mi działanie, nie ma znaku zachęty, gdzie mógłbym coś napisać. Inaczej jest przy takim kodzie:
int main()
{
int a;
cout<<"Podaj liczbe: "<< endl;
cin>> a;
cout<<"Podana liczba to: "<< a<<endl;
cin.ignore();
getchar();
return 0;
}
Wtedy mam taką możliwość. Sprawdziłem to na prostych przykładach i rzeczywiście tak jest.
Załączam odpowiedź z tego forum gdy powiedziałem żeby zatrzymać, aby wyświetlić wynik przez system.

Być może nie potrafię się wyrazić, ale o to mi chodzi mnie więcej tak jak jest w tym załączniku który dodałem.

20080324220320

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 24.03.2008 o 21:29, L33T napisał:

getch() nie należy do C++ tylko do C (chyba, głowy nie dam).

getch jest częścią standardowych bibliotek C. C++ nie ma odpowiednika. MSDN zaleca używanie _getch dla zmniejszenia szansy kolizji z klasą/przestrzenią nazw standardu C++. Standard C++ nie przewiduje istnienia klawiatury, więc nie ma w nim getch-podobnej funkcji.

Dnia 24.03.2008 o 21:29, L33T napisał:

A przez inny rozumiem konieczność dodania cin.ignore lub cin.flush()

Ta konieczność wynika z tego, że nie powinno się mieszać iostream z stdio.

Dnia 24.03.2008 o 21:29, L33T napisał:

a dla pauzy można dodać while(getchar() != ''\n'');

I wprowadzić do aplikacji aktywne czekanie, które pchnie zużycie procesora do 100%? Nie, dziękuję. Poza tym getchar też nie jest częścią bibliotek C++.

Dnia 24.03.2008 o 21:29, L33T napisał:

jeśli @syriusz.b pisze to na windzie to nie ma problemu i niech korzysta z system("Pause")
które jest zgodne z standardem.

Pod Windows powinien użyć ReadConsoleInput. :-)

Dnia 24.03.2008 o 21:29, L33T napisał:

jeśli na linuxie to musi sobie radzić za pomocą getch() :)

Na Linuksie powinien użyć getch w połączeniu z tcgetattr/tcsetattr by zapewnić niebuforowane wyjście.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 24.03.2008 o 22:19, L33T napisał:

chcesz wstrzymać program tak? to ci dałem przykład że system("Pause") to robi nie kończąc
programu

http://img413.imageshack.us/img413/5377/beztytuu1bn4.jpg

Aha. Ok. Zgadza się tylko bardziej optymalnym rozwiązaniem jest to które ja podałem.
I to nie dlatego, że ja tak uważam. Nie od dzisiaj uczę się C++, ale cały czas szukam różnych rozwiązań.
Wkleiłem kawałek mojej rozmowy z forum na C++, ponieważ dążę do dyskusji (bardzo mnie denerwuje jak ktoś pisze: "oszalałeś! chyba Cię porąb..." Ja chcę się nauczyć, a nie słuchać dziwnych wyznać pod moim adresem.
A wracając do tematu, uważam że w prostych programach może nie ma to znaczenia, ale w większych pewnie tak (sam nie napisałem jeszcze niczego większego). Więc po co pielęgnować coś co może się okazać w którymś momencie złe,. Lepiej uczyć się od razu dobrze no nie?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 24.03.2008 o 21:39, pretorianie napisał:

Ale system("PAUSE") kończy mój program, a cin.ignore() + getchar() nie.

Żadna z funkcji nie kończy programu - program się kończy, bo "kończy się" kod w main. Różnica w działaniu jest taka, że system-pause wyświetli komunikat i poczeka na pierwszy wciśnięty klawisz. ignore() z kolei wymaga od Ciebie entera - zgodnie z domyślnymi wartościami parametrów to na niego czeka.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Utwórz konto lub zaloguj się, aby skomentować

Musisz być użytkownikiem, aby dodać komentarz

Utwórz konto

Zarejestruj nowe konto na forum. To jest łatwe!


Zarejestruj nowe konto

Zaloguj się

Masz już konto? Zaloguj się.


Zaloguj się
Zaloguj się, aby obserwować