Codice corretto??

Tutta l'informatica

Codice corretto??

Messaggioda clros » mer dic 07, 2005 2:42 pm

I miei studenti oggi mi hanno beffato:credevo che cose di questo genere non si potessero fare:

Codice: Seleziona tutto
...
cout<<"inserisci lunghezza vettote";
cin>>lunghezza;

int vettore[lunghezza];
...
Only AMIGA makes it possible !!
La colpa è sempre del Kernel!!
...un bit è formato da 8 byte...

Claudio "CP" La Rosa
Avatar utente
clros

Supremo
 
Messaggi: 3473
Iscritto il: ven mag 07, 2004 2:41 pm
Località: SYS 64738

Re: Codice corretto??

Messaggioda riko » mer dic 07, 2005 3:24 pm

clros ha scritto:I miei studenti oggi mi hanno beffato:credevo che cose di questo genere non si potessero fare:

Codice: Seleziona tutto
...
cout<<"inserisci lunghezza vettote";
cin>>lunghezza;

int vettore[lunghezza];
...


E infatti credevi bene tu. Scrivendo un sorgente C++
Codice: Seleziona tutto
#include <iostream>
#include <istream>
#include <ostream>

int main(){
  int length = 0;

  std::cout << "Inserisci la dimensione del vettore: " << std::endl;
  std::cin >> length;

  int vla[length];
  return 0;
}


e compilando con
g++ -pedantic -Wall -o vla vla.cc
il risultato è:

vla.cc: In function 'int main()':
vla.cc:11: error: ISO C++ forbids variable-size array 'vla'


Il C++ STANDARD ISO98 non supporta i cosidetti Variable Length Arrays. È semplicemente un errore, punto e basta.

Il fatto che poi il gcc (e altri compilatori) abbiano un estensione che li consente è semplicemente un di più. Infatti se uno compila con l'estensione -pedantic (cosa *sempre* consigliabile, a meno che non ci sia una buona ragione per non farlo) questo errore viene segnalato. -ansi lascia attivate alcune estensioni che *non* sono ansi, come i vla, appunto.

I VLA sono invece consentiti da C99. Per esempio:
Codice: Seleziona tutto
#include <stdio.h>

int main(){
  int length = 0;

  puts("Inserisci la dimensione del vettore: ");
  scanf("%d", &length);

  int vla[length];

}


compilato con
gcc -pedantic -std=c99 -Wall -o vlac vla.c

non da alcun errore.

Vorrei ora, già che lo ho scritto, dire due commenti sul sorgente C++, cogliendo l'occasione.
In primo luogo *non* si usano iostream.h e compagnia (non mi stanco mai di ripeterlo, anche se lo sanno già tutti), sono fuori standard, con molti compilatori non funzionano già più, con molti altri cesseranno di funzionare.

Attenzione ad usare cout e cin senza namespace. Anche usare la direttiva
using namespace std;

è sconsigliata. Sostanzialmente elimina i vantaggi di avere usato i namespace. Conviene abituarsi anche nei piccoli programmi ad usare

o std::cout e std::cin

oppure includere nel namespace quello che ci serve. Esempio

using std::cin;
using std::cout;

(per esempio una mappa da stringhe a coppie di stringhe diverrebbe quasi illeggibile altrimenti std::map<std::string, std::pair<std::string, std::string>>).

Chiaramente è comprensibile invece che i testi usino using namespace... in quanto la chiarezza aumenta se sono coincisi.

Ultima cosa... questa è scarsamente risaputa e viene costantemente sbagliata anche nei corsi univeristari (oltre che da notevoli luminari).

Per usare cin e cout non basta includere iostream in quanto iostream deve semplicemente dichiarare cin e cout, ma non contiene (necessariamente) le definizioni si ostream e istream.
Il fatto che molte implementazioni includano dentro iostream istream e ostream (il che non viola lo standard) non significa che questo debba essere valido ovunque.
Questo è un errore che ha fatto (nel libro) Stroustrup stesso.

Per una spiegazione più approfondita, questo thread è esplicativo:
http://tinyurl.com/dtpnr
-enrico
fibs = 0 : 1: [ a + b | (a, b) <- zip fibs (tail fibs) ]


Akropolix: Community OFF-TOPIC di IKSnet
http://www.akropolix.net/forum

"se do da mangiare a un affamato mi dicono che sono un santo, se mi chiedo perch? ? affamato mi dicono che sono un comunista" (Helder C?mara, Arcivescovo di Recife)
Avatar utente
riko

Supremo
 
Messaggi: 3329
Iscritto il: gio mar 04, 2004 4:28 pm
Località: Chiba City

Messaggioda Blackfede » gio dic 08, 2005 10:29 pm

Non sapevo questa cosa dell'include per il cin e il cout...
Dovresti sitemare il link, segnala broken!
I troll sono solo dei dementi che finisco in /dev/null
-------------------------------------------
I video giochi non influenzano i bambini. Voglio dire, se Pac-man avesse influenzato la nostra generazione, staremmo tutti saltando in sale scure, masticando pillole magiche e ascoltando musica elettronica ripetitiva...e dopo qualche anno ci furono i rave party!
Avatar utente
Blackfede

Eroe
 
Messaggi: 1227
Iscritto il: gio gen 16, 2003 10:18 am
Località: Parma

Messaggioda riko » ven dic 09, 2005 10:17 am

Blackfede ha scritto:Non sapevo questa cosa dell'include per il cin e il cout...
Dovresti sitemare il link, segnala broken!


Non è broken. Per qualche ragione devi inseguire un po' di redirect. Comunque i post diretti sono questi.

http://groups.google.it/group/it.comp.l ... 1d4?hl=it&

http://groups.google.it/group/it.comp.l ... 639?hl=it&
-enrico
fibs = 0 : 1: [ a + b | (a, b) <- zip fibs (tail fibs) ]


Akropolix: Community OFF-TOPIC di IKSnet
http://www.akropolix.net/forum

"se do da mangiare a un affamato mi dicono che sono un santo, se mi chiedo perch? ? affamato mi dicono che sono un comunista" (Helder C?mara, Arcivescovo di Recife)
Avatar utente
riko

Supremo
 
Messaggi: 3329
Iscritto il: gio mar 04, 2004 4:28 pm
Località: Chiba City

Messaggioda riko » ven dic 09, 2005 10:19 am

Comunque lo sanno davvero in pochi. Io stesso sono più volte tentato a "non crederci", ma non ho la minima voglia di andare a verificare in approfondito.

D'altra parte Nicola Musatti ha letto e non ha contestato, il che mi fa assolutamente propendere che Kanze abbia ragione. Inoltre la cosa in se ha perfettamente senso.
-enrico
fibs = 0 : 1: [ a + b | (a, b) <- zip fibs (tail fibs) ]


Akropolix: Community OFF-TOPIC di IKSnet
http://www.akropolix.net/forum

"se do da mangiare a un affamato mi dicono che sono un santo, se mi chiedo perch? ? affamato mi dicono che sono un comunista" (Helder C?mara, Arcivescovo di Recife)
Avatar utente
riko

Supremo
 
Messaggi: 3329
Iscritto il: gio mar 04, 2004 4:28 pm
Località: Chiba City

Messaggioda Blackfede » dom dic 11, 2005 5:23 pm

Oddio, sul senso che iostream non contenga necessariamente le DEFINIZIONI, sono d'accordo...ma che non sia SUFFICIENTE quello per far funzionare cin e compagnia bella non ha molto senso. È logico invece pensare che iostream contenga gli include per istream e ostream. Ora, io sono molto arrugginito su ste cose, ma...cosa te ne fai di un'header che ti dichiara le cose senza avere un riferimento all'implementazione?
I troll sono solo dei dementi che finisco in /dev/null
-------------------------------------------
I video giochi non influenzano i bambini. Voglio dire, se Pac-man avesse influenzato la nostra generazione, staremmo tutti saltando in sale scure, masticando pillole magiche e ascoltando musica elettronica ripetitiva...e dopo qualche anno ci furono i rave party!
Avatar utente
Blackfede

Eroe
 
Messaggi: 1227
Iscritto il: gio gen 16, 2003 10:18 am
Località: Parma

Messaggioda riko » lun dic 12, 2005 12:20 am

Blackfede ha scritto:Oddio, sul senso che iostream non contenga necessariamente le DEFINIZIONI, sono d'accordo...ma che non sia SUFFICIENTE quello per far funzionare cin e compagnia bella non ha molto senso. È logico invece pensare che iostream contenga gli include per istream e ostream. Ora, io sono molto arrugginito su ste cose, ma...cosa te ne fai di un'header che ti dichiara le cose senza avere un riferimento all'implementazione?


Allora, iostream contiene le dichiarazioni. Fai una prova, crea un header "fasullo" contenente esclusivamente quello che lo standard definisce come header minimo di iostream, includi quello e prova a fare un cout.

Tieni presente che l'header minimo dice al compilatore: esiste da qualche parte un oggetto di tipo ostream, e ostream è un tipo. Tuttavia se tu provi a fare un <<, lui ti dirà che non può farlo, in quanto non ha modo di sapere quali sono i metodi di ostream

Per esempio considera questo header:
Codice: Seleziona tutto
#include <iosfwd>

namespace std{

  extern istream cin;
  extern ostream cout;
  extern ostream cerr;
  extern ostream clog;
}


a parte per il fatto che mancano i vari wcin e compagnia (ma è solo un esempio) sarebbe l'header che una implementazione sceglie per iostream.

Includendo quello come header per questo codice
Codice: Seleziona tutto
#include "myiostream.h"

int main(){
  std::cout << "Hello";

  return 0;
}


l'errore è
$ g++ -pedantic -Wall -ggdb main.cc -o main

main.cc: In function 'int main()':
main.cc:4: error: no match for 'operator<<' in 'std::cout << "Hello"'
make: *** [main] Error 1


Ora il fatto che molte implementazioni includano ostream in iostream è vero, ma il codice che usasse solo iostream potrebbe trovare un'implementazione standard con cui non compilasse. Sarebbe quindi codice non standard.

Il senso di definire cin e cout in iostream è piuttosto quello di poter include istream e ostream *senza* dichiare cin e cout, piuttosto che di includere iostream senza gli altri.

In effetti anche in un programma di medio-piccole dimensioni saranno più le classi che hanno bisogno di istream e di ostream ma che non se ne fanno nulla di cin e cout che viceversa.
-enrico
fibs = 0 : 1: [ a + b | (a, b) <- zip fibs (tail fibs) ]


Akropolix: Community OFF-TOPIC di IKSnet
http://www.akropolix.net/forum

"se do da mangiare a un affamato mi dicono che sono un santo, se mi chiedo perch? ? affamato mi dicono che sono un comunista" (Helder C?mara, Arcivescovo di Recife)
Avatar utente
riko

Supremo
 
Messaggi: 3329
Iscritto il: gio mar 04, 2004 4:28 pm
Località: Chiba City


Torna a Tecnologia, internet, coding

Chi c’è in linea

Visitano il forum: Nessuno e 8 ospiti

cron