C++: array bidimensionali in classe

Area di discussione libera.

Moderatore: Staff

Regole del forum
1) Rispettare le idee altrui.
2) Evitare le offese dirette.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Spiros
Linux 0.x
Linux 0.x
Messaggi: 36
Iscritto il: lun 3 dic 2007, 12:58
Località: Zurigo (CH)
Contatta:

C++: array bidimensionali in classe

Messaggio da Spiros »

Ho inizializzato in una classe Tabella un array bidimensionale bool righe[31][31]; Nel costruttore della classe voglio "riempirlo di zeri". Ho provato così:

Codice: Seleziona tutto

Tabella::Tabella ()
{
	for (bool* r = this -> righe; r < this -> righe + 961; ++r){
		*r = 0;
	}
}
Ma non va. L'errore è:

Codice: Seleziona tutto

Tabella.cpp: In constructor ‘Tabella::Tabella()’:
Tabella.cpp:6: error: cannot convert ‘bool (*)[31]’ to ‘bool*’ in initialization
Tabella.cpp:6: error: comparison between distinct pointer types ‘bool*’ and ‘bool (*)[31]’ lacks a cast
Sbaglio a difinire il puntetore r?

Ho proato anche con:

Codice: Seleziona tutto

for (bool* r = *(this -> righe); r < (this -> righe) + 961; ++r)

Avatar utente
simplex
Linux 2.x
Linux 2.x
Messaggi: 327
Iscritto il: mer 27 lug 2005, 0:00
Slackware: current
Desktop: xfce
Contatta:

Messaggio da simplex »

posta l'intera definizione della classe se puoi

Avatar utente
gallows
Staff
Staff
Messaggi: 3471
Iscritto il: lun 20 set 2004, 0:00
Desktop: cwm
Distribuzione: OpenBSD
Località: ~/
Contatta:

Messaggio da gallows »

Usa std::vector invece dei puntatori, in C++ non si programma così.
Poi se è bool potresti anche usare un bitset.

Spiros
Linux 0.x
Linux 0.x
Messaggi: 36
Iscritto il: lun 3 dic 2007, 12:58
Località: Zurigo (CH)
Contatta:

Messaggio da Spiros »

Ma, io ho pensato che per il lavoro che devo fare gli array di C++ sono proprio quello che ci vogliono, anche perché sono così "scarni". I puntatori mi piacciono, non sento il bisogno di avere cose più elaborate per questo tipo di lavoro.

Ho risolto così:

Codice: Seleziona tutto

Tabella::Tabella ()
{
	for (bool* r = *this -> righe; r < *(this -> righe) + 961; ++r){
		*r = 0;
	}
}

Avatar utente
puzuma
Linux 2.x
Linux 2.x
Messaggi: 482
Iscritto il: mar 4 lug 2006, 17:14
Nome Cognome: Stefano Salvador
Slackware: current
Kernel: 2.6.32.2
Desktop: KDE 4.4.0
Località: Udine
Contatta:

Messaggio da puzuma »

il tuo codice è più C che C++, quelli che usi sono array così scarni che sono array di C. Se vuoi usare tutte le features del C++ varebbe la pena di dare una letta a un po' di reference della STL e usare una classe già pronta come segnalato in altro post.

Se poi vuoi davvero un approccio a basso livello ti conviene seguire il consiglio di gallows e usare un bitset, così facendo useresti un ottavo della memoria (alpiù).

Avatar utente
gallows
Staff
Staff
Messaggi: 3471
Iscritto il: lun 20 set 2004, 0:00
Desktop: cwm
Distribuzione: OpenBSD
Località: ~/
Contatta:

Messaggio da gallows »

Allora dovresti usare il C. È solo un consiglio, poi (come è giusto che sia) puoi fare ciò che preferisci, ma usare il C++ come "C con classi" è considerato quasi all'unanimità cattiva programmazione.

Avatar utente
nuitari
Linux 3.x
Linux 3.x
Messaggi: 777
Iscritto il: dom 14 ott 2007, 12:51
Slackware: 12.0
Località: San Colombano al Lambro
Contatta:

Messaggio da nuitari »

Quoto in toto, in C++ si fa altro per gli array, fermo restando che una delle cose belle del C++ è che è un sovrainsieme del C.

comunque, è + veloce così

Codice: Seleziona tutto

#include <stdio.h>
#include <string.h>

using namespace std;

#define ROWS 10
#define COLS 10

class prova {
        public:

        int array[ROWS][COLS];

        prova(void)
        {
                memset(this->array, 0x0, sizeof(this->array));
        }
};

int main(void)
{
        prova pippo;
        printf("%d\n", pippo.array[0][0]);
        return 0;
}

Avatar utente
gallows
Staff
Staff
Messaggi: 3471
Iscritto il: lun 20 set 2004, 0:00
Desktop: cwm
Distribuzione: OpenBSD
Località: ~/
Contatta:

Messaggio da gallows »

Io farei così:

Codice: Seleziona tutto

#include <cstdio>
#include <bitset>

class Fred {
public:
    Fred() { }
    virtual ~Fred() { }                                                                                                                                                       
    
    void show() const
    {
        for (int i=0; i<m_rows; i++) {
            for (int j=0; j<m_cols; j++)
                std::printf("%d ", m_data[m_cols * i + j]);

            std::putchar('\n');
        }
    }

protected:
    static const int m_rows = 4;
    static const int m_cols = 4;

    std::bitset<m_rows*m_cols> m_data;

};

int main()
{
    Fred().show();
}

Spiros
Linux 0.x
Linux 0.x
Messaggi: 36
Iscritto il: lun 3 dic 2007, 12:58
Località: Zurigo (CH)
Contatta:

Messaggio da Spiros »

Capisco.
La STL la conosco, più o meno. So che cosa sono vettori, liste, iteratori etc., ma gli arrays C e i puntatori mi sembrano più complicati di sicuro, ma anche più accattivanti. E poi a informatica ci fanno lavorare solo con quelli...

Ma è giunto il momento di aprire gli orizzonti. Mi piacerebbe che qualcuno mi consigliasse una referenza più completa per la STL. Che cos'è il bitset?

Avatar utente
gallows
Staff
Staff
Messaggi: 3471
Iscritto il: lun 20 set 2004, 0:00
Desktop: cwm
Distribuzione: OpenBSD
Località: ~/
Contatta:

Messaggio da gallows »

Beh, C++ Programming Language di Stroustrup... ad ogni modo in rete si trovano valanghe di informazioni.:

http://www.cppreference.com/
http://www.cplusplus.com/
http://www.parashift.com/c++-faq-lite/

Ah, dimenticavo: lo std::bitset è sostanzialmente un insieme di bit. Lo puoi utilizzare ad esempio per attivare determinate opzioni in un programma oppure, come nel tuo caso, creare una sorta di array di valori logici.

ps. Sposto in "Libera"

Avatar utente
puzuma
Linux 2.x
Linux 2.x
Messaggi: 482
Iscritto il: mar 4 lug 2006, 17:14
Nome Cognome: Stefano Salvador
Slackware: current
Kernel: 2.6.32.2
Desktop: KDE 4.4.0
Località: Udine
Contatta:

Messaggio da puzuma »

sempre come spunto di riflessione visto che il tuo problema è settare dei valori booleani puoi divertirti a giocare con gli operatori bitwise:

Codice: Seleziona tutto

#include <stdio.h>

int main()
{
    // inizializza il set a  00000000
    char set = 0;
    printf("%x\n", set);

    // imposta il set a 00000001
    set |= 1 << 0;
    printf("%x\n", set);

    // imposta il set a 00000101
    set |= 1 << 2;
    printf("%x\n", set);

    // imposta il set a 00100101
    set |= 1 << 5;
    printf("%x\n", set);

    // imposta il set a 00100001
    set &= ~(1 << 5);
    printf("%x\n", set);

    return 0;
}
è molto più scomodo e illegibile di qualsiasi contenitore di C++ ma intanto impari qualcosa :-)

P.S. molto probabilmente std::bitset è implementato internamente con operazioni simili a queste.

Spiros
Linux 0.x
Linux 0.x
Messaggi: 36
Iscritto il: lun 3 dic 2007, 12:58
Località: Zurigo (CH)
Contatta:

Messaggio da Spiros »

Sono meravigliosi questi bitset!
Grazie mille, gallows, sto spulciando cppreference, poi vedrò anche gli altri. Sai, sono abituato all'autodocumentazione implementata in Python, con cui si arriva a conoscere tutto quanto sia già incluso nel linguaggio tramite le sue funzioni. Con c++ ero un po' sperduto. Ho guardato qualcosa qua e là, ma non ho mai trovato un granché.

Spiros
Linux 0.x
Linux 0.x
Messaggi: 36
Iscritto il: lun 3 dic 2007, 12:58
Località: Zurigo (CH)
Contatta:

Messaggio da Spiros »

Ok, un'utlima domanda, con cui però esco un po' dal seminato: la "compilazione separata" come funziona? Da quanto ho capito se ho, per esempio, una classe di nome tabella, inserisco in un file tabella.h ("header") la sola dichiarazione della classe e dei metodi, nel file tabella.cpp la vera e propria definizione e nel file con il programma vero e proprio (ossia con la funziona main) un semplice #include "tabella.h".
Poi non devo far altro che compilare separatamente il programma e il file tabella.cpp e unire i file (ad esempio con cat). Giusto?

Avatar utente
gallows
Staff
Staff
Messaggi: 3471
Iscritto il: lun 20 set 2004, 0:00
Desktop: cwm
Distribuzione: OpenBSD
Località: ~/
Contatta:

Messaggio da gallows »

Se ad esempio il tuo programma è strutturato così:

main.cc
tabella.h
tabella.cc

dai:

g++ -c main.cc
g++ -c tabella.cc
g++ tabella.o main.o

Ti consiglio comunque di imparare a scrivere i Makefile.

Spiros
Linux 0.x
Linux 0.x
Messaggi: 36
Iscritto il: lun 3 dic 2007, 12:58
Località: Zurigo (CH)
Contatta:

Messaggio da Spiros »

gallows ha scritto: Ti consiglio comunque di imparare a scrivere i Makefile.
Appunto. Quelli in linea di massima li so fare. Mi serviva quest'informazione per farne uno decente.

Come vedete ho un'infarinatura generale di tutto... :roll:

Rispondi