|
| Hvordan skriver jeg en std::string til skæ~ Fra : Stefan Kristensen |
Dato : 27-06-02 09:07 |
|
Følgende giver en memory fejl:
std::string test()
{
std::string txt("abc");
return txt;
}
void main()
{
printf("%s\n", test());
}
Hvad gør jeg forkert?
mvh
Stefan
| |
Stefan Kristensen (27-06-2002)
| Kommentar Fra : Stefan Kristensen |
Dato : 27-06-02 09:15 |
|
Der var jeg lidt for hurtig. Har fået svar i anden tråd.
stefan
| |
Rasmus Kaae (27-06-2002)
| Kommentar Fra : Rasmus Kaae |
Dato : 27-06-02 09:45 |
|
"Stefan Kristensen" <stk@rus.dk> wrote in message
news:3d1ac79e$0$147$edfadb0f@dspool01.news.tele.dk...
> Følgende giver en memory fejl:
>
> std::string test()
> {
> std::string txt("abc");
> return txt;
> }
>
void main()
{
printf("%s\n", test().c_str());
}
sådan.
| |
Bent Wagner (27-06-2002)
| Kommentar Fra : Bent Wagner |
Dato : 27-06-02 22:13 |
|
Rasmus Kaae <macaw@WHATEVERMAKESYOUHAPPYhotmail.com> wrote:
>void main()
>{
> printf("%s\n", test().c_str());
>}
>
>
>sådan.
Moar den slemme mand skriver void main() og ikke int main()
Bent Wagner
| |
Anders Lund (11-07-2002)
| Kommentar Fra : Anders Lund |
Dato : 11-07-02 20:51 |
|
"Bent Wagner" <psy@psy.bronderslev.dk> skrev i en meddelelse
news:slrnahn420.1v7.psy@psy.bronderslev.dk...
> Rasmus Kaae <macaw@WHATEVERMAKESYOUHAPPYhotmail.com> wrote:
>
> >void main()
> >{
> > printf("%s\n", test().c_str());
> >}
> >
> >
> >sådan.
>
> Moar den slemme mand skriver void main() og ikke int main()
Hvorfor må man ikke skrive void main, det står der konstant i den bog jeg
lige har læst.
Mvh
Anders Lund
| |
Kent Friis (11-07-2002)
| Kommentar Fra : Kent Friis |
Dato : 11-07-02 22:31 |
|
Den Thu, 11 Jul 2002 21:51:11 +0200 skrev Anders Lund:
>
>"Bent Wagner" <psy@psy.bronderslev.dk> skrev i en meddelelse
>news:slrnahn420.1v7.psy@psy.bronderslev.dk...
>> Rasmus Kaae <macaw@WHATEVERMAKESYOUHAPPYhotmail.com> wrote:
>>
>> >void main()
>> >{
>> > printf("%s\n", test().c_str());
>> >}
>> >
>> >
>> >sådan.
>>
>> Moar den slemme mand skriver void main() og ikke int main()
>Hvorfor må man ikke skrive void main, det står der konstant i den bog jeg
>lige har læst.
Fordi main returnerer int.
Hvis mylib.h definerer: int dosomething();
må man heller ikke i mylib.c skrive: void dosomething() {}
Gør man det alligevel, er resultatet undefined. En int og en void
fylder ikke lige meget på stakken, og derved er der risiko for at
returadressens offset bliver forskellig, og programmet får fat i
en forkert returadresse = Segmentation fault eller General protection
fault.
Mvh
Kent
--
Indlæringskurven til Linux er stejl, til tider lodret... Men for katten
hvor er udsigten på toppen dog fantastisk
- Michael G. Vendelbo i dk.snak
| |
Bent Wagner (12-07-2002)
| Kommentar Fra : Bent Wagner |
Dato : 12-07-02 05:02 |
|
On Thu, 11 Jul 2002 21:51:11 +0200, Anders Lund <webmaster@123grin.dk> wrote:
>Hvorfor må man ikke skrive void main, det står der konstant i den bog jeg
>lige har læst.
Det må man også godt, men vil man følge ISO standarden
skal man skrive int main.
Det er iøvrigt kortere at skrive int end void, men
det kan være svært at vænne sig til det, hvis void
ligger i fingrene.
Jeg har selv svært ved at huske at bruge std:: foran
ting fra standard biblioteket, men er ved at få styr
på det.
Jeg tør ikke sige om det nogensinde har været 'lovligt'
at bruge void main, men ingen af mine, efterhånden
mange, bøger bruger det.
Bent Wagner
| |
Morten Boysen (12-07-2002)
| Kommentar Fra : Morten Boysen |
Dato : 12-07-02 14:19 |
|
"Bent Wagner" <psy@psy.bronderslev.dk> wrote in message
news:slrnaisp9v.2na.psy@psy.bronderslev.dk...
> Det må man også godt, men vil man følge ISO standarden
> skal man skrive int main.
Hvis standarden eksplicit beskriver main til at returnere int, som
standartden gør, så er det ikke "lovligt" eller iorden at void. Der er
så en del kompilere, som accepterer det alligevel, men det er et
problem med kompilerne.
> Jeg tør ikke sige om det nogensinde har været 'lovligt'
> at bruge void main, men ingen af mine, efterhånden
> mange, bøger bruger det.
Det har aldrig været lovligt:
http://www.research.att.com/~bs/bs_faq2.html#void-main
--
Morten Boysen
| |
Torben W. Hansen (18-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 18-07-02 09:41 |
|
"Rasmus Kaae" <macaw@WHATEVERMAKESYOUHAPPYhotmail.com> skrev i en meddelelse
news:afeja4$l7e$1@news.net.uni-c.dk...
> "Stefan Kristensen" <stk@rus.dk> wrote in message
> news:3d1ac79e$0$147$edfadb0f@dspool01.news.tele.dk...
> > Følgende giver en memory fejl:
> >
> > std::string test()
> > {
> > std::string txt("abc");
> > return txt;
> > }
> >
>
>
> void main()
> {
> printf("%s\n", test().c_str());
> }
>
>
> sådan.
>
>
Er ny i C++ ville afprøve ovenstående kode. Jeg tilføjede include filer som
nedenfor, hvilke jeg ikke er sikker på er korrekte.
Problem 1: Jeg får fejlmeddelelsen " syntax error before '(' " i line
4.
Problem 2: Kan nogen forklare erklæringen std::string test(){...} samt
test().c_str()
Jeg har læst C++ af Kris Jamsa og kan ikke finde noget der ligner
ovenstående (jeg er klar over at dette ikke er en god bog)
#include <stdio.h>
#include <string.h>
std::string test() // linie 4
{
std::string txt("abc");
return txt;
}
void main()
{
printf("%s\n", test().c_str());
}
Med venlig hilsen
Torben W. Hansen
| |
Leo Laursen (18-07-2002)
| Kommentar Fra : Leo Laursen |
Dato : 18-07-02 10:48 |
|
Thu, 18 Jul 2002 10:40:46 +0200, skrev Torben W. Hansen
<mail@ins-intersoft.com>:
> Er ny i C++ ville afprøve ovenstående kode. Jeg tilføjede include filer som
> nedenfor, hvilke jeg ikke er sikker på er korrekte.
> Problem 1: Jeg får fejlmeddelelsen " syntax error before '(' " i line
> 4.
Standard namespace "std" er sikkert ikke defineret. (gæt)
> Problem 2: Kan nogen forklare erklæringen std::string test(){...} samt
> test().c_str()
s.c_str() er en operation tilknyttet klassen "string" der returnerer en
pointer til et nul-termineret char array, men samme indhold som s.
(* char) Det kan så bruges i printf().
> Jeg har læst C++ af Kris Jamsa og kan ikke finde noget der ligner
> ovenstående (jeg er klar over at dette ikke er en god bog)
Hvis den har været god. så er den ihvertfald forældet nu.
> #include <stdio.h>
> #include <string.h>
> std::string test() // linie 4
> {
> std::string txt("abc");
> return txt;
> }
> void main()
> {
> printf("%s\n", test().c_str());
> }
> Med venlig hilsen
> Torben W. Hansen
#include <iostream>
#include <string>
std::string test()
{
std::string txt("abc");
return txt;
}
int main() {
std::cout << test() << std::endl;
return 0;
}
Det lader til at virke; men jeg synes det er noget rod at returnere en
værdi, der ikke eksisterer længere, netop fordi man returnerer.
void main har vist aldrig været rigtig i c++, så måske er mere c, der
bare tilfældigvis virker i c++, at bogen handler om.
Leo
--
Don't worry. Life's too long.
-- Vincent Sardi, Jr.
| |
Ivan Johansen (18-07-2002)
| Kommentar Fra : Ivan Johansen |
Dato : 18-07-02 11:15 |
|
Leo Laursen wrote:
> void main har vist aldrig været rigtig i c++, så måske er mere c, der
> bare tilfældigvis virker i c++, at bogen handler om.
Nej, void main() har ALDRIG været hverken gyldig C eller C++. Det har
altid været en fejl at bruge void main() og ingen compiler burde tage
det, selvom mange gør.
Ivan Johansen
| |
Leo Laursen (18-07-2002)
| Kommentar Fra : Leo Laursen |
Dato : 18-07-02 11:53 |
|
Thu, 18 Jul 2002 12:15:10 +0200, skrev Ivan Johansen <NG@Padowan.dk>:
> Nej, void main() har ALDRIG været hverken gyldig C eller C++. Det har
> altid været en fejl at bruge void main() og ingen compiler burde tage
> det, selvom mange gør.
Med skam at melde, må jeg indrømme at jeg ofte har brugt void main()
(vist oprindeligt for at ungå en tilbagevendende fejlmeddelelse i
Borlands gamle Dos kompiler), og det uden at underviseren på mit kursus
komenterede det.(ellers iøvrigt en meget god underviser).
Et hurtigt kik i "C a Reference Manual", viser at du har fuldstændig
ret.
Leo
--
"What terrible way to die."
"There are no good ways."
-- Sulu and Kirk, "That Which Survives", stardate unknown
| |
Torben W. Hansen (18-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 18-07-02 11:26 |
|
Tak for svarene Leo...
> >Problem 1: Jeg får fejlmeddelelsen " syntax error before '(' " i
line
> > 4.
> Standard namespace "std" er sikkert ikke defineret. (gæt)
Hvordan gøres det i nedenstående kode ?
#include <stdio.h>
#include <string.h>
std::string test() // linie 4
{
std::string txt("abc");
return txt;
}
void main()
{
printf("%s\n", test().c_str());
}
Med venlig hilsen
Torben W. Hansen
| |
Leo Laursen (18-07-2002)
| Kommentar Fra : Leo Laursen |
Dato : 18-07-02 11:44 |
|
Thu, 18 Jul 2002 12:26:15 +0200, skrev Torben W. Hansen
<mail@ins-intersoft.com>:
> Tak for svarene Leo...
>> >Problem 1: Jeg får fejlmeddelelsen " syntax error before '(' " i
> line
>> > 4.
>> Standard namespace "std" er sikkert ikke defineret. (gæt)
> Hvordan gøres det i nedenstående kode ?
> #include <stdio.h>
> #include <string.h>
> std::string test() // linie 4
> {
> std::string txt("abc");
> return txt;
> }
> void main()
> {
> printf("%s\n", test().c_str());
> }
Med "#include <string>" virker det hos mig.
Leo
--
Be different: conform.
| |
Torben W. Hansen (18-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 18-07-02 12:50 |
|
"> Med "#include <string>" virker det hos mig.
>
> Leo
> --
> Be different: conform.
Det samme her. Fejlen var at jeg havde skrevet "#include <string.h>" i
stedet for "#include <string>" som du skriver ovenfor. TAK for hjælpen...
Med venlig hilsen
Torben W. Hansen
| |
Mogens Hansen (18-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 18-07-02 13:35 |
|
"Torben W. Hansen" <mail@ins-intersoft.com> wrote
> Hvordan gøres det i nedenstående kode ?
Det skal du ikke gøre.
C++ implementeringen (din compiler med tilhørende Standard Library gør det)
gør det.
>
> #include <stdio.h>
> #include <string.h>
>
> std::string test() // linie 4
> {
> std::string txt("abc");
> return txt;
> }
>
> void main()
> {
> printf("%s\n", test().c_str());
> }
En korrekt C++ udgave af ovenstående er (include ændret, main returnerer
int):
<code>
#include <cstdio>
#include <string>
std::string test() // linie 4
{
std::string txt("abc");
return txt;
}
int main()
{
std::printf("%s\n", test().c_str());
}
</code>
Venlig hilsen
Mogens Hansen
| |
Torben W. Hansen (18-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 18-07-02 13:49 |
|
> En korrekt C++ udgave af ovenstående er (include ændret, main returnerer
> int):
>
> <code>
> #include <cstdio>
> #include <string>
>
> std::string test() // linie 4
> {
> std::string txt("abc");
> return txt;
> }
>
> int main()
> {
> std::printf("%s\n", test().c_str());
> }
> </code>
>
>
> Venlig hilsen
>
> Mogens Hansen
Jeg har lidt svært ved at gennemskue udtrykket "test().c_str()" - jeg kunne
bedre forstå, hvis det hed f.eks. variabelnavn.c_str().
Desuden har jeg spørgsmål til "std::" og "string", som er sendt til Bertel's
tråd.
Tak Mogens-
Med venlig hilsen
Torben W. Hansen
| |
Morten Boysen (18-07-2002)
| Kommentar Fra : Morten Boysen |
Dato : 18-07-02 14:02 |
|
"Torben W. Hansen" <mail@ins-intersoft.com> wrote in message
news:ah6drl$2o03$1@news.cybercity.dk...
> Jeg har lidt svært ved at gennemskue udtrykket "test().c_str()" -
jeg kunne
> bedre forstå, hvis det hed f.eks. variabelnavn.c_str().
Der er ingen variabel. Til gengæld returnerer funtkionen test et
string objekt. Det du gør, er at kalde funktionen c_str() på det
objekt, som test() returnerer.
--
Morten Boysen
| |
Mogens Hansen (18-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 18-07-02 14:13 |
|
"Torben W. Hansen" <mail@ins-intersoft.com> wrote
> Jeg har lidt svært ved at gennemskue udtrykket "test().c_str()" - jeg
kunne
> bedre forstå, hvis det hed f.eks. variabelnavn.c_str().
"test" er en funktion, der returnerer et "std::string" objekt.
"string" er en klasse (i virkeligheden en typedef, men se bort fra det) som
ligger i det "namespace", der hedder "std".
Klassen "string" har en member-funktioner, som hedder "c_str" som returnerer
en "const char*" til en nul-termineret tekst - hvilket er det format som
"printf" kan bruge.
Når det er sagt, så lad være med at bruge "printf" overhovedet.
Brug C++'s stream klasser i stedet. F.eks.:
cout << test();
Venlig hilsen
Mogens Hansen
| |
Kent Friis (18-07-2002)
| Kommentar Fra : Kent Friis |
Dato : 18-07-02 14:34 |
|
Den Thu, 18 Jul 2002 14:48:36 +0200 skrev Torben W. Hansen:
>> En korrekt C++ udgave af ovenstående er (include ændret, main returnerer
>> int):
>>
>> <code>
>> #include <cstdio>
>> #include <string>
>>
>> std::string test() // linie 4
>> {
>> std::string txt("abc");
>> return txt;
>> }
>>
>> int main()
>> {
>> std::printf("%s\n", test().c_str());
>> }
>> </code>
>>
>>
>> Venlig hilsen
>>
>> Mogens Hansen
>
>Jeg har lidt svært ved at gennemskue udtrykket "test().c_str()" - jeg kunne
>bedre forstå, hvis det hed f.eks. variabelnavn.c_str().
Dette giver samme resultat:
std::string temp;
temp=test();
std::printf("%s\n", temp.c_str());
Den eneste forskel er at vi hælder resultatet af funktionen ned i en
variabel, og så bruger den. Men det er ikke nødvendigt, returværdien
fra en funktion kan sagtens bruges i en anden funktion uden at skulle
via en variabel.
Mvh
Kent
--
Demokrati er lige som den 29. februar - begge dele forekommer
en gang hver fjerde år.
| |
Bertel Lund Hansen (18-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 18-07-02 11:22 |
|
Torben W. Hansen skrev:
>Er ny i C++ ville afprøve ovenstående kode. Jeg tilføjede include filer som
>nedenfor, hvilke jeg ikke er sikker på er korrekte.
Det er det ikke. Inkluderede filer der ender med .h, er C's
hjælpefiler. Dem har man lov at benytte, men de åbner ikke for de
samme muligheder som C++' egne.
>Problem 1: Jeg får fejlmeddelelsen " syntax error before '(' " i line
>4.
C++' string er udefineret. Kun C's string er defineret, og den
har ikke noget med std at gøre.
>Problem 2: Kan nogen forklare erklæringen std::string test(){...} samt
>test().c_str()
Hvis C++-filen string havde været inkluderet, ville det oprette
en funktion med navnet test af typen string. {} omklamrer den
blok med kode som udgør funktionens krop.
>#include <stdio.h>
>#include <string.h>
Forkert, som sagt.
>std::string test() // linie 4
>{
>std::string txt("abc");
>return txt;
>}
I kroppen oprettes en (C++) stringvariabel, txt, som omgående
tildeles værdien "abc". Derefter returneres den.
>void main()
>{
>printf("%s\n", test().c_str());
>}
Main skal være int og returnere en talværdi. 0 betyder at alt
virkede. I større programmer lader man den ret7urnere f.eks. 1
hvis en fil ikke blev fundet, 2 hvis der var fejl ved læsningen,
3 hvis det ringer på døren midt i det hele osv., men til en test
lader man den bare returnere 0.
Den benytter C's metode til udskrift, og den vil gerne udskrive
den string der blev oprettet i test(), men da det er en
C++-streng, skal den konverteres. Det gøres med den konnvertering
som er indbygget i string, c_str().
Alt i alt er det noget forfærdelig rod af C og C++. Lav hellere
et rent C++-program:
#include <iostream> // Nu kan vi skrive ud
#include <string> // C++ string
std::string test() {
std::string txt("abc");
return txt;
}
int main() {
std::cout << test() << std::endl;
return 0;
}
cout svarer (groft sagt) til printf() i C, og endl skifter linje
og tømmer skrivebufferen. Efter cout kan man bruge lige så mange
elementer som man gider. De skal bare alle sammen have << mellem
sig. Man kan også benytte C's linjeskift om man vil:
cout << test() << "\n" << "Testen var vellykket\n";
Hvis man er træt af at sætte std:: foran alle systemelementerne,
kan man efter inkluderingerne skrive:
using namespace std;
Det er ligegyldigt for det kompilerede program hvilken form man
vælger.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Torben W. Hansen (18-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 18-07-02 13:23 |
|
Tak for din uddybning...
> >#include <stdio.h>
> >#include <string.h>
>
> Forkert, som sagt.
Imellemtiden har jeg fundet ud af at det fungerer med:
#include <stdio.h> // nødvendig for Ansi C, printf()
#include <string>
> Alt i alt er det noget forfærdelig rod af C og C++. Lav hellere
> et rent C++-program:
Helt enig;
men jeg vil gerne kunne forstå det der stod selvom det er noget rod - Det
giver lidt hjernegymnastik.
> Hvis man er træt af at sætte std:: foran alle systemelementerne,
> kan man efter inkluderingerne skrive:
>
> using namespace std;
Tak - det vidste jeg ikke. Det stod der heller ikke noget om i "Kris Jamsa
C++".
Dette afføder et par nye spørgsmål:
I den compiler jeg bruger (Dev C++) kan man tilsyneladende undlade både
"std:: " og "using namespace std;" . Er det pga. at compileren ikke
opfylder nyeste C++ standard ?
Vil det sige at "std" er en basis klasse og at "string" er en data type
defineret i "class std", hvilke eventuelt kan betragtes ved at åbne
headerfilen <string> ? Eller er vi igen over i noget med "Templates" som jeg
endnu ikke har nået at få læst ?
Med venlig hilsen
Torben W. Hansen
| |
Morten Boysen (18-07-2002)
| Kommentar Fra : Morten Boysen |
Dato : 18-07-02 13:50 |
|
"Torben W. Hansen" <mail@ins-intersoft.com> wrote in message
news:ah6cdf$2mjp$2@news.cybercity.dk...
> > Hvis man er træt af at sætte std:: foran alle systemelementerne,
> > kan man efter inkluderingerne skrive:
> >
> > using namespace std;
>
> Tak - det vidste jeg ikke. Det stod der heller ikke noget om i "Kris
Jamsa
> C++".
> Dette afføder et par nye spørgsmål:
Smid det hæfte ud og køb Accelerated C++ istedet. Det er en
fremragende bog.
> I den compiler jeg bruger (Dev C++) kan man tilsyneladende undlade
både
> "std:: " og "using namespace std;" . Er det pga. at compileren
ikke
> opfylder nyeste C++ standard ?
Ja.
> Vil det sige at "std" er en basis klasse og at "string" er en data
type
> defineret i "class std", hvilke eventuelt kan betragtes ved at åbne
> headerfilen <string> ? Eller er vi igen over i noget med "Templates"
som jeg
> endnu ikke har nået at få læst ?
Vi er over i noget tredje: namespaces. Alle standard funktioner og
klasser ligger i det namespace, der hedder std. Man bruger namespaces
til at gruppere en række ting, så man ikke ender i nameclashes.
--
Morten Boysen
| |
Torben W. Hansen (18-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 18-07-02 14:27 |
|
> Smid det hæfte ud og køb Accelerated C++ istedet. Det er en
> fremragende bog.
Er næsten gjort, men jeg skal lige have det sidste kapitel med.
Tak for hjælpen...
Med venlig hilsen
Torben W. Hansen
| |
Mogens Hansen (18-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 18-07-02 13:51 |
|
"Torben W. Hansen" <mail@ins-intersoft.com> wrote
> #include <stdio.h> // nødvendig for Ansi C, printf()
Det hedder faktisk:
#include <cstdio> // to use printf
> Tak - det vidste jeg ikke. Det stod der heller ikke noget om i "Kris Jamsa
> C++".
Er du overrasket ?
> I den compiler jeg bruger (Dev C++) kan man tilsyneladende undlade både
> "std:: " og "using namespace std;" . Er det pga. at compileren ikke
> opfylder nyeste C++ standard ?
Ja.
Bortset fra at der kun findes een formel C++ Standard: "ISO/IEC 14882:
1998(E)" (med een Technical Corrigedum, så vidt jeg husker).
>
> Vil det sige at "std" er en basis klasse og at "string" er en data type
> defineret i "class std", hvilke eventuelt kan betragtes ved at åbne
> headerfilen <string> ?
Nej.
"std" er et "namespace", altså en slags mængde af navne - nemlig den mængde
som hele Standard Library ligger i.
> Eller er vi igen over i noget med "Templates" som jeg
> endnu ikke har nået at få læst ?
Nej - det har ikke noget at gøre med templates.
Venlig hilsen
Mogens Hansen
| |
Torben W. Hansen (18-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 18-07-02 21:44 |
|
> Det hedder faktisk:
> #include <cstdio> // to use printf
Tak - det vidste jeg heller ikke
> > Det stod der heller ikke noget om i "Kris Jamsa C++
> Er du overrasket ?
Efterhånden kommer det ikke helt bag på mig...
> "test" er en funktion, der returnerer et "std::string" objekt.
> "string" er en klasse (i virkeligheden en typedef, men se bort fra det)
som
> ligger i det "namespace", der hedder "std".
> Klassen "string" har en member-funktioner, som hedder "c_str" som
returnerer
> en "const char*" til en nul-termineret tekst - hvilket er det format som
> "printf" kan bruge.
Det hjalp en del på forståelsen, men udtrykket "test().c_str()" spøger
stadig - formodentlig da jeg mangler et eller andet grundlæggende:
> Når det er sagt, så lad være med at bruge "printf" overhovedet.
> Brug C++'s stream klasser i stedet. F.eks.:
> cout << test();
Ja, det er jeg klar over - det var kun for forståelsens skyld at jeg kastede
mig over denne kodestump.
Med venlig hilsen
Torben W. Hansen
| |
Bertel Lund Hansen (18-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 18-07-02 22:28 |
|
Torben W. Hansen skrev:
>Det hjalp en del på forståelsen, men udtrykket "test().c_str()" spøger
>stadig - formodentlig da jeg mangler et eller andet grundlæggende:
En af fordelene ved C++' string er at der er en hulens bunke nyttige
funktioner som man arver når man opretter en string. Man kan beregne
længden, man kan udtage en delstreng, man kan kopiere tegnene til et array,
man kan konvertere den til en C-streng og meget andet.
Metoder knyttet til string kaldes med variablens navn, punktum (am. "dot")
samt funktionens navn:
Hvis vi har
std::string navn("Bertel Lund Hansen");
så kan vi få fat i
navn.size() // 18
navn.substr(7,4) // "Lund"
navn.c_str() // konvertering til C-format
Min lærer sagde at vi dotter os ind på funktionerne, og det kan man fint
sige. Hvis man selv skriver en klasse med metoder, skal man også dotte sig
ind på dem når man arbejder med et objekt der arver fra klassen.
class Animal {
public:
Animal (int l=0, int e=0) { legs=l; eyes=e; }
get_legs() { return legs; }
get_eyes() { return eyes; }
private:
int legs;
int eyes;
};
int main () {
Animal gysse (4,2);
cout << "Hunden Gysse har " << gysse.get_legs() << " ben." << endl;
return 0;
}
.... Og husk altid det forbistrede ; efter en klassedefinition!
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Torben W. Hansen (19-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 19-07-02 08:50 |
|
Tak for hjælpen...
> Metoder knyttet til string kaldes med variablens navn, punktum (am. "dot")
> samt funktionens navn:
Det forstår jeg godt - så længe det er " am.f(); " , men jeg forstår ikke
rigtig " am().f(); " som det oprindelige eksempel et sted i tråden bød på.
Som et lignende eksempel har jeg har skrevet et stykke kode nederst på siden
og hvor jeg risikere at få nogle "verbale tærsk", hvilket jo nogle gange
hører med til indlæringsprocessen. Pyt med det - bare jeg kan få afklaret
notationen funktion1().funktion2();
Som en øvelse har jeg desuden forsøgt at forklare dit kodeeksempel og
korriger mig endelig, hvis der er noget jeg har misforstået.
#include <iostream>
#include <string>
class Animal {
// Offentlig tilgængeelige metoder (funktioner) og evt. data
public:
Animal (int l=0, int e=0) { legs=l; eyes=e; } // Constructor metode - vist
nok inline
int get_legs() { return legs; }; // Interface metode -
vist nok inline
int get_eyes() { return eyes; }; // Interface metode -
vist nok inline
// Indkabsling af legs og eyes, kun synlige fra klassens egne metoder
private:
int legs;
int eyes;
};
int main () {
int dummy;
// Erklæring af objekt "gysse" og samtidig init. af legs og eyes via
constructor kald
Animal gysse (4,2);
cout << "Hunden Gysse har " << gysse.get_legs() << " ben." << endl;
cin >> dummy; // kun for at blive i consol mode indtil der indtastes noget
på kbd.
return 0;
}
Eksempel på funktion1().funktion2();
#include <iostream>
#include <string>
using namespace std;
class klasse
{
public:
void funktion(string parameter){variabel = parameter; cout << variabel <<
endl;}
private:
string variabel;
};
klasse c(void) { cout << "dette er kun en strengkonstant" << endl; };
int main()
{
int dummy;
klasse a;
klasse b;
klasse c(void); // er usikker på denne erklæing
a.funktion("a.variabel"); // Dette er et normalt funktionskald i objektet
"a"
b=c(); // c() udskriver streng - og returnerer et objekt af "klasse" til b
?
// betyder det at variable i b overskrives med værdier returneret fra c()?
c().funktion("c().variabel"); // Specielt svær - hvilken mening giver dette
?
// det var noget i denne retning som oprindeligt var vist i tråden - ikke
sandt ?
cin >> dummy;// kun for at blive i consol mode indtil der indtastes noget på
kbd.
}
Med venlig hilsen
Torben W. Hansen
| |
Bertel Lund Hansen (19-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 19-07-02 10:35 |
|
Torben W. Hansen skrev:
>Det forstår jeg godt - så længe det er " am.f(); " , men jeg forstår ikke
>rigtig " am().f();
I C kalder man en funktion med navn(). I det forliggende tilfælde var det
test(). Den returnerer en string. Test uden parenteser 'returnerer' en
compilerfejl.
Ved klasser derimod bruger man navnet uden parenteser.
Din forklaring af programmet er rigtig.
>Eksempel på funktion1().funktion2();
>#include <iostream>
>#include <string>
>using namespace std;
>class klasse
>{
>public:
> void funktion(string parameter){variabel = parameter; cout << variabel <<
>endl;}
>private:
> string variabel;
>};
Af tekniske grunde skal funktion() erklæres uden for klassen, men det ser
vi lige bort fra.
>klasse c(void) { cout << "dette er kun en strengkonstant" << endl; };
Er det et eksempel hvor du vil lave en funktion der returnerer en klasse? I
så fald mangler den at gøre netop dette (der mangler "return" og den klasse
der skal returneres).
klasse c(void) { klasse d; cout << "dette er kun en strengkonstant" <<
endl; return d; };
>int main()
>{
>int dummy;
>klasse a;
>klasse b;
>klasse c(void); // er usikker på denne erklæing
Den erklæring skal væk. C er allerede erklæret som funktion.
>b=c(); // c() udskriver streng - og returnerer et objekt af "klasse" til b?
Ja, i min version.
>// betyder det at variable i b overskrives med værdier returneret fra c()?
Jaee ... b bliver sat til den klasse der returneres med de variable som
denne returklasse har. B's tidligere værdi er tabt for evigt.
>c().funktion("c().variabel"); // Specielt svær - hvilken mening giver dette?
Ingen, men det er tilladt. Du kalder funktionen c som returnerer en klasse.
Denne klasses funktion() bliver så kaldt med parameteren "c().variabel" som
jo via klassens metoder bliver 'husket' i variablen variabel. Da der ikke
er nogen variabel eller andet der kan fastholde den returnerede klasse
eller dens variable, forsvinder den omgående i en blå tåge.
Generelle kommentarer:
Det er ulogisk at du lader en tilfældig funktion styre klassens variabel.
Det skal ske i en konstruktør.
Det er standard i Java (og C++?) at klassers navne begynder med stort. Det
er en praktisk konvention.
Nu har du prøvet at kaste forskellige elementer sammen og prøvet at få
lavet et lovligt program. Prøv i stedet at sætte dig et mål med et program
og så få det til at virke.
Og sørg for at det er *sidste* gang du kalder en funktion funktion, en
variabel variabel og en parameter parameter!
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Kent Friis (19-07-2002)
| Kommentar Fra : Kent Friis |
Dato : 19-07-02 10:52 |
|
Den Fri, 19 Jul 2002 11:35:27 +0200 skrev Bertel Lund Hansen:
>Torben W. Hansen skrev:
>
>Det er standard i Java (og C++?) at klassers navne begynder med stort. Det
>er en praktisk konvention.
I Java og VB, men ikke i C/C++. Og det er en p*sse irriterende
konvention, der totalt ødelægger flowet fra hjernen til tastaturet,
at man hele tiden skal stoppe op og huske at skrive med stort.
Mvh
Kent
--
"Intelligence is the ability to avoid doing work, yet get the work done"
- Linus Torvalds
| |
Torben W. Hansen (19-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 19-07-02 11:53 |
|
Mange tak for hjælpen...
> Din forklaring af programmet er rigtig.
TAK - pyh, så er der da sevet noget ind...
> Af tekniske grunde skal funktion() erklæres uden for klassen, men det ser
> vi lige bort fra.
Du mener sådan ?
i klassens krop:
void funktion(string);
uden for kroppen:
void klasse::funktion(string parameter){variabel = parameter; cout <<
variabel << endl;}
er det fordi den kommer til at ligge på stakken og dermed ikke er statisk ?
> Er det et eksempel hvor du vil lave en funktion der returnerer en klasse?
Ja, men jeg havde vist ikke helt check på det...
> så fald mangler den at gøre netop dette (der mangler "return" og den
klasse
> der skal returneres).
Præcis - men heldigvis fik du alligevel fat i essensen.
> >b=c(); // c() udskriver streng - og returnerer et objekt af "klasse" til
b?
> Ja, i min version.
Pga. "klasse d;" og "return d;"
> >// betyder det at variable i b overskrives med værdier returneret fra
c()?
> Jaee ... b bliver sat til den klasse der returneres med de variable som
> denne returklasse har. B's tidligere værdi er tabt for evigt.
Jeg forstår, at det gælder hele klassen, men er det ikke kun variablerne,
der vil være forskellige ?
> >c().funktion("c().variabel"); // Specielt svær - hvilken mening giver
dette?
> Ingen, men det er tilladt. Du kalder funktionen c som returnerer en
klasse.
> Denne klasses funktion() bliver så kaldt med parameteren "c().variabel"
HER ER DE FORLØSENDE ORD - det er c()'s returnerede klasses metode,
"funktion()", der kaldes. Det var da pokkers at det skulle tage mig så lang
tid at forstå dette... TAK! og atter TAK!
> Generelle kommentarer:
> Det er ulogisk at du lader en tilfældig funktion styre klassens variabel.
> Det skal ske i en konstruktør.
Hvorfor - er det ikke det man bruger interface funktioner til ?
> Det er standard i Java (og C++?) at klassers navne begynder med stort. Det
> er en praktisk konvention.
Taget til efterretning...
> Nu har du prøvet at kaste forskellige elementer sammen og prøvet at få
> lavet et lovligt program. Prøv i stedet at sætte dig et mål med et program
> og så få det til at virke.
Det har været vigtigt og lærerigt for mig at kæmpe med og få løst dette
elementære forståelsesproblem, hvilket har været målet.
Jeg har faktisk skrevet forholdvis store programmer tidligere, men i Ansi C.
> Og sørg for at det er *sidste* gang du kalder en funktion funktion, en
> variabel variabel og en parameter parameter!
Mener du i stedet "objekt elementer", "metoder", "data elementer" eller hvad
?
Med venlig hilsen
Torben W. Hansen
| |
Bertel Lund Hansen (19-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 19-07-02 13:22 |
|
Torben W. Hansen skrev:
>> Af tekniske grunde skal funktion() erklæres uden for klassen, men det ser
>> vi lige bort fra.
>Du mener sådan ?
>i klassens krop:
>void funktion(string);
>uden for kroppen:
>void klasse::funktion(string parameter){variabel = parameter; cout <<
>variabel << endl;}
Ja.
>er det fordi den kommer til at ligge på stakken og dermed ikke er statisk ?
Nej, det er fordi min compiler skriver:
Warning: Functions taking class-by-value argument(s) are not
expanded inline in function klasse::funktion(string)
og det forstår jeg ikke.
>> >// betyder det at variable i b overskrives med værdier returneret fra c()?
>> Jaee ... b bliver sat til den klasse der returneres med de variable som
>> denne returklasse har. B's tidligere værdi er tabt for evigt.
>Jeg forstår, at det gælder hele klassen, men er det ikke kun variablerne,
>der vil være forskellige ?
Hvis b og c har præcis samme type, så jo. Men et objekt af én type kan godt
arve fra en anden klasse (i samme hierarki). I så fald er metoderne ikke
længere nødvendigvis de samme.
>HER ER DE FORLØSENDE ORD
Fint nok.
>> Det er ulogisk at du lader en tilfældig funktion styre klassens variabel.
>> Det skal ske i en konstruktør.
>Hvorfor - er det ikke det man bruger interface funktioner til ?
Jeg skulle ikke have skrevet styre, men initialisere. Det bruger man ikke
en funktion, men en konstruktor til.
>> Det er standard i Java (og C++?) at klassers navne begynder med stort. Det
>> er en praktisk konvention.
>Taget til efterretning...
Og der er ikke noget problem med at huske det når man vænner sig til det
med det samme. Til gengæld er det nemt i koden at se om der er tale om en
klasse eller en variabel/funktion.
>Jeg har faktisk skrevet forholdvis store programmer tidligere, men i Ansi C.
Okay.
>> Og sørg for at det er *sidste* gang du kalder en funktion funktion, en
>> variabel variabel og en parameter parameter!
>Mener du i stedet "objekt elementer", "metoder", "data elementer" eller hvad?
Jeg mener at det er forvirrende at skulle skrive:
Tag variablen variabel og brug som parameter
i funktionen funktion().
Det er bedre med f.eks.:
Tag variablen v og brug som parameter i funktionen f().
Og endnu bedre med beskrivende navne.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Ivan Johansen (19-07-2002)
| Kommentar Fra : Ivan Johansen |
Dato : 19-07-02 13:44 |
|
Bertel Lund Hansen wrote:
> Nej, det er fordi min compiler skriver:
>
> Warning: Functions taking class-by-value argument(s) are not
> expanded inline in function klasse::funktion(string)
>
> og det forstår jeg ikke.
Det er kun en advarsel. Compileren kan ikke inline funktion der tager en
klasse som parameter. Advarslen kan ignoreres eller man kan overføre som
reference:
void funktion(const string ¶meter){variabel = parameter; cout <<
variabel << endl;}
>>>Det er standard i Java (og C++?) at klassers navne begynder med stort. Det
>>>er en praktisk konvention.
>>>
>>Taget til efterretning...
>
> Og der er ikke noget problem med at huske det når man vænner sig til det
> med det samme. Til gengæld er det nemt i koden at se om der er tale om en
> klasse eller en variabel/funktion.
Det er kun i Java man gør det. Alle standardfunktioner og klasser i C++
skrives f.eks. med små bogstaver.
Ivan Johansen
| |
Bertel Lund Hansen (19-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 19-07-02 14:49 |
|
Ivan Johansen skrev:
>>>>Det er standard i Java (og C++?) at klassers navne begynder med stort.
>Det er kun i Java man gør det. Alle standardfunktioner og klasser i C++
>skrives f.eks. med små bogstaver.
Okay, men jeg synes nu det er en rar ting. Men det hjælper jo
fedt hvis jeg er ene om det (sammen med min lærer).
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Torben W. Hansen (19-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 19-07-02 14:03 |
|
"Bertel Lund Hansen" <nospam@lundhansen.dk> skrev i en meddelelse
news:mf0gju0l6co83ct67935h8qh6g1qhek5c3@news.telia.dk...
> Nej, det er fordi min compiler skriver:
> Warning: Functions taking class-by-value argument(s) are not
> expanded inline in function klasse::funktion(string)
> og det forstår jeg ikke.
Men brokkede din compiler sig så ikke over dit eksempel, hvor du havde
constructor kroppen i klassen ? Animal (int l=0, int e=0) { legs=l;
eyes=e; }
> Hvis b og c har præcis samme type, så jo. Men et objekt af én type kan
godt
> arve fra en anden klasse (i samme hierarki). I så fald er metoderne ikke
> længere nødvendigvis de samme.
OK - det kræver lidt træning og tid at tænke i objekter, men forhåbentlig
kommer det med tiden...
> >HER ER DE FORLØSENDE ORD
> Fint nok.
Det har reddet min dag -
> Jeg skulle ikke have skrevet styre, men initialisere. Det bruger man ikke
> en funktion, men en konstruktor til.
OK - jeg forstår... (selv om jeg er bornholmer)
> Og der er ikke noget problem med at huske det når man vænner sig til det
> med det samme. Til gengæld er det nemt i koden at se om der er tale om en
> klasse eller en variabel/funktion.
Det lyder som en fornuftig regel - men hvad så med variable og funktioner
som TextString og GetImage() - er reglen så f.eks text_string og get_image()
?
> Tag variablen v og brug som parameter i funktionen f().
> Og endnu bedre med beskrivende navne.
Enig - man behøver ikke ligefrem at anstrenge sig for at gøre koden mere
ulæselig. Iøvrigt har jeg set foo() i eksempler flere steder. Er det en måde
at indikere, at det drejer sig om en OOP-funktion.
Endnu engang tak...
Med venlig hilsen
Torben W. Hansen
| |
Bertel Lund Hansen (19-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 19-07-02 14:53 |
|
Torben W. Hansen skrev:
>OK - jeg forstår... (selv om jeg er bornholmer)
Det er nu ikke de ringeste mennesker. Jeg har f.eks. en far der
var bornholmer til han skulle læse i København.
>Det lyder som en fornuftig regel - men hvad så med variable og funktioner
>som TextString og GetImage() - er reglen så f.eks text_string og get_image()
Der er næppe nogen regel. Jeg brugte understreg i Pascal, men i
Java er standarden textString og getImage(). Jeg ved ikke hvad
der er bedst.
>ulæselig. Iøvrigt har jeg set foo() i eksempler flere steder. Er det en måde
>at indikere, at det drejer sig om en OOP-funktion.
Nej. Af uudgrundelige årsager er "foobar" blevet betegnelsen for
en "dingenot" - altså en ubestemmelig genstand. Det har haft til
konsekvens at mange programeksempler benytter foo og bar. det
betyder så <enellerandentilfældigfidus>. Eks.:
class foo {
public:
int bar (int foobar) { return 7; }
}
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Torben W. Hansen (19-07-2002)
| Kommentar Fra : Torben W. Hansen |
Dato : 19-07-02 15:47 |
|
"Bertel Lund Hansen" <nospam@lundhansen.dk> skrev i en meddelelse
news:266gjucnjn4sdh9kh49lpnnbf1jrkqeni1@news.telia.dk...
> Det er nu ikke de ringeste mennesker. Jeg har f.eks. en far der
> var bornholmer til han skulle læse i København.
Læste han til "Københavner" - OK det var en joke - pga. at det er weekend.
Tak og god weekend...
Med venlig hilsen
Torben W. Hansen
| |
Martin Moller Peders~ (18-07-2002)
| Kommentar Fra : Martin Moller Peders~ |
Dato : 18-07-02 19:48 |
|
In <ff4djusplkl7mo655jbbfo9sut2kt9uk8n@news.telia.dk> Bertel Lund Hansen <nospam@lundhansen.dk> writes:
>Torben W. Hansen skrev:
>>Er ny i C++ ville afprøve ovenstående kode. Jeg tilføjede include filer som
>>nedenfor, hvilke jeg ikke er sikker på er korrekte.
>Det er det ikke. Inkluderede filer der ender med .h, er C's
>hjælpefiler. Dem har man lov at benytte, men de åbner ikke for de
>samme muligheder som C++' egne.
og de fleste (alle?) gamle c-header filer kan inkluderes som C++-header-filer ved at skrive
c foran f.x.
#include <cstdio> istedet for #include <stdio.h>
og
#include <cassert> istedet for #include <assert.h>
/Martin
| |
Bertel Lund Hansen (18-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 18-07-02 20:39 |
| | |
Bertel Lund Hansen (27-06-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 27-06-02 11:12 |
|
Stefan Kristensen skrev:
>Følgende giver en memory fejl:
Du har fået løsningen.
Problemet kommer sig af at printf kun kan håndtere elementer af
primitive typer, altså her en char *. Printf er ren C.
Std::string er noget helt andet som derfor skal håndteres af C++'
eget udskriftssystem som benytter std::cout.
--
Bertel
http://lundhansen.dk/bertel/ FIDUSO: http://fiduso.dk/
| |
|
|