Problema con vettori e cicli

Salve a tutti, sto realizzando un controller midi e fin qui tutto ok, il codice è logicamente corretto e funziona ma ho un problema con il ciclo sugli array;
In pratica se scrivo singolarmente le istruzioni queste funzionano, se le inserisco in un ciclo non più.Qualche aiuto?
Questo è il mio codice

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

int but1[6] = {2,3,4,5,6,7};
bool stat1[6] = {LOW,LOW,LOW,LOW,LOW,LOW};
int note1[6]= {1,2,3,4,5,6};

int i;

void setup() {
  MIDI.begin();
  Serial.begin(115200);
//  for(i=0;i=sizeof(but1);i++){
//    pinMode(but1[i], INPUT);
//    digitalWrite(but1[i],HIGH);
//  }

  pinMode(but1[0], INPUT);
  digitalWrite(but1[0],HIGH);
  pinMode(but1[1], INPUT);
  digitalWrite(but1[1],HIGH);
  pinMode(but1[2], INPUT);
  digitalWrite(but1[2],HIGH);
  pinMode(but1[3], INPUT);
  digitalWrite(but1[3],HIGH);
  pinMode(but1[4], INPUT);
  digitalWrite(but1[4],HIGH);
  pinMode(but1[5], INPUT);
  digitalWrite(but1[5],HIGH);
}


void loop() {
//  for(i=0;i=sizeof(but1);i++){
//      buttonPressed(but1[i],note1[i],stat1[i]);
//  }

  buttonPressed(but1[0],note1[0],stat1[0]);
  buttonPressed(but1[1],note1[1],stat1[1]);
  buttonPressed(but1[2],note1[2],stat1[2]);
  buttonPressed(but1[3],note1[3],stat1[3]);
  buttonPressed(but1[4],note1[4],stat1[4]);
  buttonPressed(but1[5],note1[5],stat1[5]);
}



void buttonPressed(int input,int chan,bool stato){
  if(digitalRead(input)==LOW){
    MIDI.sendNoteOn(chan, 127, 1);
    stato=HIGH;
  }
  if(digitalRead(input)==HIGH && stato==HIGH){
    MIDI.sendNoteOff(chan, 127, 1);
    stato=LOW;
  }
}

Grazie ,spero in un vostro aiuto

ciao Gabry,

attenzione che sizeof ritorna il numero di byte presenti nell’array e non quante posizioni…quindi se hai un array di int e vuoi contare le posizioni devi scrivere:

for(i=0;i<sizeof(but1)/2;i++)

EDIT : attenzione che = è assegnazione di un valore e non verifica

Verifica con un serial.print cosa restituisce l'operatore sizeof. Potrebbe aggiungere alla dimensione dell'array anche il terminatore e quindi mandare in overflow il ciclo for.

Comunque, per se non ti sei presentato…

Prova a mettere < invece di uguale, nella for

Molto basic nella tua storia, vero?

Anche per me…

Come lo odio scrivere dal tablet

Dopo aver messo a posto tutti gli errori arrivi ultimo…

ORSO2001:
ciao Gabry,

attenzione che sizeof ritorna il numero di byte presenti nell’array e non quante posizioni…quindi se hai un array di int e vuoi contare le posizioni devi scrivere:

for(i=0;i<sizeof(but1)/2;i++)

EDIT : attenzione che = è assegnazione di un valore e non verifica

Si, risolto era proprio questo;
visto che abbiamo trovato l’errore e che ne stiamo parlando, al posto del sizeof() c’è una funzione che restituisce il numero di elementi di un vettore?

Si

Sizeof vettore diviso sizeof elemento

>Gabry575: NON avendolo tu ancora fatto, nel rispetto del regolamento della sezione Italiana del Forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

Sotto forma di macro:

#define NumElementi(array) (sizeof(array)/sizeof(array[0]))

array è il nome dato al vettore, la macro ritorna il numero totale di elementi ospitabile dal vettore.

Chiamiamola ubound questa macro…

Comincerei a sentirmi a casa…

Il problema di questo metodo è che non funziona quando si ha un puntatore al vettore, invece del vettore vero e proprio.

Solitamente la cosa si gestisce in altro modo:

#define N_ELEM 6

int but1[N_ELEM] = {2,3,4,5,6,7};

// ...

  for(i=0;i<N_ELEM;i++){
    // ...

Aspetta...

un pensiero

questo significa che non è possibile in C conoscere a posteriori la dimensione di un array che non sia globale o almeno dichiarato nella funzione?

scusa la domanda, che ti sembrerà banale, ma non avevo mai visto la cosa da questo punto di vista

Precisamente. A tutte le funzioni che li trattano di solito si passa il puntatore all'array e la sua dimensione.

Nella STL (Standard Template Library) del C++ ci sono strutture dati "avanzate" che "sembrano" un array e permettono di ricavare la propria dimensione, ma questo ha un certo overhead e solitamente si evita in ambienti "ristretti" come quelli embedded. Esistono comunque delle implementazioni della STL a basso overhead, se le vuoi provare dai un'occhiata a std::vector, std::list, std::queue, std::deque.

Grazie

SukkoPera:
Precisamente. A tutte le funzioni che li trattano di solito si passa il puntatore all'array e la sua dimensione.

Giusto per estendere il discorso, in C/C++ non è possibile passare, o ritornare, direttamente degli array, si passano/ritornano solo i relativi puntatori.
Se un array deve essere visibile a tutto il codice e/o ha vita che dura per tutto il tempo di esecuzione del programma conviene crearlo come variabile globale, in questo caso è possibile usare la sizeof per conoscerne la dimensione in byte e/o il numero di elementi.
Un caso classico per l'uso di array, anche molto grossi, globali sono i font per i display grafici o le lut per i calcoli, tutti e due sono di tipo costant e posti nella flash sulle mcu.
Nel caso in cui l'array viene creato localmente e deve essere passato ad altre funzioni è necessario usare i puntatori, se serve conoscere la dimensione dell'array all'interno delle funzioni richiamate è obbligatorio passare anche questo parametro.
Da notare che nel momento in cui si crea un array in C la sua dimensione è nota fin da subito perché la imponiamo noi o come limite nella dichiarazione, p.e. "int myArray[20]", oppure per il numero di elementi che inseriamo nell'array durante la sua creazione, p.e. int myArray = {1,2,3,4}".
L'uso del sizeof diventa inutile nel caso di arry che inizializziamo con una dimensione ben precisa, senza precaricare i dati, basta introdurre questo valore sotto forma di define e quando ci serve è immediatamente disponibile senza perdere tempo per la sizeoff, che rammento essere un operatore che richiede diversi cicli macchina per essere eseguito se serve solo la dimensione in byte, molti cicli macchina se è necessario determinare il numero di elementi quando non sono composti da singoli byte.
Sizeof è comodo in fase di init del codice per conoscere le dimensioni di un array che viene preinizializzato in fase di creazione con molti dati, magari sono dei template che dobbiamo ogni volta modificare per il codice specifico, e mettersi a contare a mano tutti gli elementi e i byte è una bella scocciatura.
Diverso è il discorso per gli array dinamici, dove si usa la memoria dinamica, in questo caso non è possibile sapere le dimensioni in fase di creazione perché cambiano durante l'esecuzione del codice, però questo tipo di dati è da evitare assolutamente quando si lavora su una piccola mcu 8 bit con solo 2k di ram, dato che non esiste nessun sistema di controllo/limite dimensioni heap, recupero ram rilasciata, è un attimo far finire l'heap dentro la ram dati con conseguente crash del software.

astrobeed:
... senza perdere tempo per la sizeoff, che rammento essere un operatore che richiede diversi cicli macchina per essere eseguito se serve solo la dimensione in byte, molti cicli macchina se è necessario determinare il numero di elementi quando non sono composti da singoli byte.

Questo non mi torna. sizeof() è un operatore che viene valutato a tempo di compilazione, quindi di fatto è come se nel codice si scrivesse una costante, non dovrebbe comportare alcun overhead in esecuzione.

Dal C99 in poi la sizeof è determinata a runtime, per le versioni precedenti in fase di compilazione,

Che io sappia, è determinata a runtime solo per i VLA (Variable Length Array), d’altronde per questi non si può fare altrimenti, ma non è questo il nostro caso.

Trovo e riporto …

sizeof is always computed at compile time in C89. Since C99 and variable length arrays, it is computed at run time when a variable length array is part of the expression in the sizeof operand.

Same for the evaluation of the sizeof operand: it is not evaluated in C89 but in C99 if the operand is of variable length array type it is evaluated.

… spero sia corretto.

Guglielmo

Si è corretto, ed è quanto mi ricordavo, infatti col C99 sono stati introdotti gli array a lunghezza variabile e da qui la necessità di determinare la sizeof a runtime degli array.
Poi se il compilatore determina la sizeof a runtime solo per gli array che possono variare la dimensione, o lo fa per tutti, dipende da come è stato realizzato, per dare una risposta definitiva è necessario andare a vedere i sorgenti del gcc-avr, o chiederlo a chi si occupa del suo sviluppo.
Giusto per curiosità stasera provo a verifcare l'assembly di uno sketch dove metto un array a lunghezza fissa e uno a lunghezza variabile in modo da vedere come si comporta la sizeof nei due casi.

Francamente non vedo che senso potrebbe avere calcolare a runtime qualcosa che è già noto a compile time. Dal punto di vista dell'ottimizzazione è una ciofeca pazzesca :D.

Vedrai che viene fatto a runtime solo per i VLA, mi stupirebbe decisamente il contrario.