/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
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/

Søg
Reklame
Statistik
Spørgsmål : 177580
Tips : 31968
Nyheder : 719565
Indlæg : 6409081
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste