|
| Deklaration af variabel i C++ Fra : Morten Bakkedal |
Dato : 21-06-03 14:22 |
|
Jeg vil gerne deklarere og initialisere en variabel i en if-sætning og
samtidig teste dens værdi. Da == er stærkere end =, har jeg brug for at
sætte en parentes om initialiseringen ved =. Derfor har jeg konstrueret
koden:
vector<int> digits;
// ...
if ((int len = digits.size()) == 0)
// ...
Men GCC (2.95) nægter at oversætte dette:
/home/mbb/cpp/operator.cpp: In method `void Bigint::print()':
/home/mbb/cpp/operator.cpp:129: parse error before `='
Den har ingen problemer med at oversætte:
int len;
if ((len = digits.size()) == 0)
// ...
Hvad har jeg overset?
--
Morten Bakkedal
http://www.bakkeland.dk/
| |
Bertel Lund Hansen (21-06-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 21-06-03 14:42 |
|
Morten Bakkedal skrev:
>if ((int len = digits.size()) == 0)
>Hvad har jeg overset?
At det er en ulogisk konstruktion? BCpp nægter også at oversætte
det.
Hvorfor vil du ikke oprette variablen uden for if-sætningen?
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Morten Bakkedal (21-06-2003)
| Kommentar Fra : Morten Bakkedal |
Dato : 21-06-03 14:58 |
|
On Sat, 21 Jun 2003 15:42:11 +0200, Bertel Lund Hansen wrote:
> Hvorfor vil du ikke oprette variablen uden for if-sætningen?
For et minimere virkefeltet (= oversættelse af "scope") af den
midlertidige variabel. På samme måde som jeg ville gøre i en
for-løkke:
for (int i = 0; i < 10; i++)
// ...
--
Morten Bakkedal
http://www.bakkeland.dk/
| |
Bertel Lund Hansen (21-06-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 21-06-03 15:21 |
|
Morten Bakkedal skrev:
>> Hvorfor vil du ikke oprette variablen uden for if-sætningen?
>For et minimere virkefeltet (= oversættelse af "scope") af den
>midlertidige variabel. På samme måde som jeg ville gøre i en
>for-løkke:
Okay, jeg kan godt umiddelbart se ideen, men ved nærmere
eftertanke kan jeg nok ikke alligevel. Hvad skal du reelt bruge
variablen til som du ikke kan i forvejen med de allerede kendte
værdier?
Vis os lige hele if-blokken.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Morten Bakkedal (22-06-2003)
| Kommentar Fra : Morten Bakkedal |
Dato : 22-06-03 17:05 |
|
On Sat, 21 Jun 2003 16:21:26 +0200, Bertel Lund Hansen wrote:
> Vis os lige hele if-blokken.
Sådan ser den ud, når jeg har udskiftet "if ((int len = digits.size()) ==
0)" med "if (digits.empty())":
void Bigint::print()
{
if (digits.empty())
std::cout << "(0)" << std::endl;
else
{
cout << "(";
for (int i = digits.size() - 1; i >= 0; i--)
{
std::cout << digits[i];
if (i > 0)
std::cout << ",";
}
std::cout << ")" << std::endl;
}
}
--
Morten Bakkedal
http://www.bakkeland.dk/
| |
Mogens Hansen (22-06-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 22-06-03 19:30 |
|
"Morten Bakkedal" <news20040522@bakkeland.dk> wrote
[8<8<8<]
> for (int i = digits.size() - 1; i >= 0; i--)
Det ser ud til at være rigtigt, men jeg bliver altid lidt bekymret for de
steder hvor der er mulighed for off-by-one fejl, og hvor man skal tænke en
ekstra gang om det er rigtigt at der står ">=" og ikke blot ">".
Skrev du det rigtigt i første forsøg ?
Hvad med bruge reverse_iterator i stedet ?
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> digits;
digits.push_back(1);
digits.push_back(2);
digits.push_back(3);
cout << '(';
if(digits.empty()) {
cout << 0;
}
else {
for(vector<int>::reverse_iterator i = digits.rbegin(); digits.rend()
!= i; ++i) {
cout << *i;
if(&digits.front() != &*i)
cout << ',';
}
}
cout << ')';
}
eller hvis man er til det lidt tættere
cout << '(';
if(digits.empty())
cout << 0;
for(vector<int>::reverse_iterator i = digits.rbegin(); digits.rend() !=
i; ++i)
cout << *i << (&digits.front() != &*i ? "," : "\0");
cout << ')';
Venlig hilsen
Mogens Hansen
| |
Morten Bakkedal (22-06-2003)
| Kommentar Fra : Morten Bakkedal |
Dato : 22-06-03 22:46 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> writes:
> Det ser ud til at være rigtigt, men jeg bliver altid lidt bekymret for de
> steder hvor der er mulighed for off-by-one fejl, og hvor man skal tænke en
> ekstra gang om det er rigtigt at der står ">=" og ikke blot ">".
Det lyder som et fornuftigt princip.
> Hvad med bruge reverse_iterator i stedet ?
Det vil jeg gøre.
--
Morten Bakkedal
http://www.bakkeland.dk/
| |
Lasse Westh-Nielsen (21-06-2003)
| Kommentar Fra : Lasse Westh-Nielsen |
Dato : 21-06-03 16:36 |
|
"Morten Bakkedal" <news20040522@bakkeland.dk> wrote in message
news:pan.2003.06.21.13.58.08.70242@bakkeland.dk...
> On Sat, 21 Jun 2003 15:42:11 +0200, Bertel Lund Hansen wrote:
>
> > Hvorfor vil du ikke oprette variablen uden for if-sætningen?
>
> For et minimere virkefeltet (= oversættelse af "scope") af den
> midlertidige variabel. På samme måde som jeg ville gøre i en
> for-løkke:
>
> for (int i = 0; i < 10; i++)
> // ...
Jeg har faktisk gjort det samme nogle gange. Det er et helt nyt paradigme:
programmering med scopes!
Men, det du kan gøre er vel at deklarere et lille lokalt scope:
/* hovedprogram */
....
{
/* lokalt scope */
int len;
if ((len = digits.size()) == 0)
{
...
}
}
/* hovedprogram fortsætter */
....
Men er der en god grund til ikke at lave det som en funktion? Det er vel som
regel pænere...
Mvh Lasse
--
<signature>
Lasse Westh-Nielsen
lasse@daimi.au.dk
</signature>
| |
Martin Moller Peders~ (21-06-2003)
| Kommentar Fra : Martin Moller Peders~ |
Dato : 21-06-03 15:23 |
|
In <pan.2003.06.21.13.22.04.904825@bakkeland.dk> Morten Bakkedal <news20040522@bakkeland.dk> writes:
>Jeg vil gerne deklarere og initialisere en variabel i en if-sætning og
>samtidig teste dens værdi. Da == er stærkere end =, har jeg brug for at
>sætte en parentes om initialiseringen ved =. Derfor har jeg konstrueret
>koden:
>vector<int> digits;
>// ...
>if ((int len = digits.size()) == 0)
> // ...
>Men GCC (2.95) nægter at oversætte dette:
>/home/mbb/cpp/operator.cpp: In method `void Bigint::print()':
>/home/mbb/cpp/operator.cpp:129: parse error before `='
>Den har ingen problemer med at oversætte:
>int len;
>if ((len = digits.size()) == 0)
> // ...
>Hvad har jeg overset?
Det er ikke tilladt.
Skriv istedet for:
if (digits.size()==0) {
int len=digits.size();
}
for at opnaa samme virkning.
| |
Henrik Lynggaard (21-06-2003)
| Kommentar Fra : Henrik Lynggaard |
Dato : 21-06-03 15:41 |
|
Martin Moller Pedersen wrote:
> if (digits.size()==0) {
> int len=digits.size();
> }
>
> for at opnaa samme virkning.
eller
if (digits.size()==0) {
int len=0;
}
| |
Mogens Hansen (21-06-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 21-06-03 16:03 |
|
"Morten Bakkedal" <news20040522@bakkeland.dk> wrote
[8<8<8<]
> if ((int len = digits.size()) == 0)
Hvorfor vil du gemme værdien ?
Du _ved_ at den er 0.
Du _kunne_ skrive (men det er ikke ligefrem kønt):
if(int len = digits.size())
;
else {
// ...
}
Hvis du kun ville køre noget kode, hvis den ikke var 0 giver det lidt mere
mening, og du kan skrive
if(vector<int>::size_type len = digits.size()) {
//...
}
Hvis du ønsker at teste på om containeren er tom, er det langt klarere at
skrive
if(digits.empty()) {
// ...
}
Desuden er det et sted imellem måske lidt hurtigere (for std::vector) til
væsentligt hurtigere (f.eks. for std::list) at bruge "empty" i stedet for
"size".
"empty" har O(1) køretidskarakteristik for alle Standard Library containere.
"size" har O(n) køretidskarakteristik for std::list
> Den har ingen problemer med at oversætte:
Det er ikke tilladt.
Venlig hilsen
Mogens Hansen
| |
Mogens Hansen (21-06-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 21-06-03 16:34 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote
[8<8<8<]
> "size" har O(n) køretidskarakteristik for std::list
Det er iøvrigt ikke et _krav_ - men det er blot meget almindeligt og
forståeligt.
[8<8<8<]
> Det er ikke tilladt.
Ups - jeg fik vist klippet lidt forkert, så det var vist ikke tydeligt hvad
jeg snakkede om.
> if ((int len = digits.size()) == 0)
er ikke tilladt.
> if ((len = digits.size()) == 0)
er tilladt.
Venlig hilsen
Mogens Hansen
| |
Morten Bakkedal (22-06-2003)
| Kommentar Fra : Morten Bakkedal |
Dato : 22-06-03 16:18 |
|
On Sat, 21 Jun 2003 17:34:11 +0200, Mogens Hansen wrote:
> > > if ((int len = digits.size()) == 0)
> >
> > Hvorfor vil du gemme værdien ?
> > Du _ved_ at den er 0.
I den færdige version skulle det have udseendet:
if ((int len = digits.size()) == 0)
// ...
else
// Her skal len bruges
Jeg har nu lavet koden om, så der i if-sætningen bruges empty() og i
else-delen bruges size().
> > if ((int len = digits.size()) == 0)
>
> er ikke tilladt.
>
> > if ((len = digits.size()) == 0)
>
> er tilladt.
Jeg kan omformulere problemet lidt. Hvordan kan det være, at
if (int i = 5)
// ...
er tilladt, når
if ((int i = 5))
// ...
ikke er tilladt? Det første eksempel er beskrevet af Bjarne Stroustrup i
The C++ Programming Language. Det sidste vil ikke oversætte i GCC.
--
Morten Bakkedal
http://www.bakkeland.dk/
| |
Mogens Hansen (22-06-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 22-06-03 19:30 |
|
"Morten Bakkedal" <news20040522@bakkeland.dk> wrote
[8<8<8<]
> Jeg kan omformulere problemet lidt. Hvordan kan det være, at
>
> if (int i = 5)
> // ...
>
> er tilladt, når
>
> if ((int i = 5))
> // ...
>
> ikke er tilladt? Det første eksempel er beskrevet af Bjarne Stroustrup i
> The C++ Programming Language. Det sidste vil ikke oversætte i GCC.
Det korte svar:
Af samme grund som det ikke er tilladt at skrive
void foo()
{
(int i = 5);
}
Det lidt længere svar:
Jeg antager at det enten er Third Edition eller Special Edition af "The C++
Programming Language" du sidder med. (Hvis ikke så skift den ud med een af
ovennævnte)
I Appendix A, side 803 står der at en "if" statement skal være formet som
if ( condition ) statement
hvor "condition" er
expression
type-specifier-seq declarator = assignment-expression
altså enten et "expression" eller en erklæring.
I og med det du skriver hverken er et expression eller en erklæring kan det
ikke oversætte.
Venlig hilsen
Mogens Hansen
| |
Morten Bakkedal (22-06-2003)
| Kommentar Fra : Morten Bakkedal |
Dato : 22-06-03 22:43 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> writes:
> I Appendix A, side 803 står der at en "if" statement skal være formet som
> if ( condition ) statement
> hvor "condition" er
> expression
> type-specifier-seq declarator = assignment-expression
>
> altså enten et "expression" eller en erklæring.
> I og med det du skriver hverken er et expression eller en erklæring kan det
> ikke oversætte.
Det var lige hvad jeg havde brug for. Tak for det fine svar.
--
Morten Bakkedal
http://www.bakkeland.dk/
| |
|
|