2017-07-10 4 views
-2

Je travaille actuellement sur un projet où je calcule la moyenne des 10 à 20 dernières mesures. Pour ce faire, je sauvegarde les 10 dernières valeurs dans un tableau. droite déplacer les éléments pour mettre à jour les données.Le décalage des éléments du tableau laisse vide les derniers éléments

Le code que j'utilise pour changer les valeurs:

void shiftvals() { 
    memmove(&val[1], &val[0], (sizeof(val)/sizeof(val[0]))-1); 
    for (unsigned int i = 0; i < (sizeof(val)/sizeof(val[0])); i++) 
    { 
     Serial.print(val[i]); 
     Serial.print(","); 
    } 
    Serial.println(); 
} 

Le code appelant la fonction:

#define ARR_SIZE 10 
uint16_t val[ARR_SIZE]; 

void loop(){ 
    Serial.print("Size of the array:\t"); 
    Serial.println(sizeof(val)/sizeof(val[0])); 

    shiftvals(); 

    val[0] = (analogRead(A0)); 
} 

Maintenant, le problème est que les dernières sorties seront toujours 0, même si le tableau se remplit bien. Lorsque j'augmente la taille du tableau, la quantité d'espaces vides augmente également.

Sortie:

396,396,381,462,503,195,0,0,0,0, 
472,472,396,381,462,247,0,0,0,0, 
495,495,472,396,381,206,0,0,0,0, 
435,435,495,472,396,125,0,0,0,0, 

Je suis vraiment confus, ce que je fais mal dans le memmove?

+0

Veuillez fournir un [mcve], et que voulez-vous dire par * tableau remplit bien * –

+1

Pensez au troisième paramètre de 'memmove'. Le chercher. – molbdnilo

+0

le troisième paramètre de memmove est Size_t, j'ai pensé que le dimensionnement était éteint, mais je ne pensais pas de prendre la taille définie du tableau comme size_t comme expliqué par michael @ passer, je crois que la sortie clarifie ce point –

Répondre

2

Le problème est dans votre appel à memmove. Votre taille est trop courte.

void shiftvals() { 
    memmove(&val[1], &val[0], (sizeof(val)/sizeof(val[0]))-1); 

    // that was only 9 bytes, but val[] is 20 bytes long. 

    // ... 
} 

Devrait être

void shiftvals() { 
    memmove(&val[1], &val[0], (ARR_SIZE - 1) * sizeof(val[0])); 
    // ... 
} 
2

Faites-le C++ façon:

#include <iostream> 
#include <array> 
#include <algorithm> 

std::array<int,10> val = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 

void shiftVals() 
{ 
    std::rotate(begin(val), end(val)-1, end(val)); 
} 

int main() 
{ 
    shiftVals(); 
    for(auto v: val) std::cout << v << " "; 
    std::cout << "\n"; 
} 

Tenir compte à pas en utilisant des variables globales.

+0

Je comprends que les variables globales sont normalement désapprouvées, mais j'ai besoin que ce tableau existe dans le programme, et je ne voulais pas la classe supplémentaire. le garder dans la boucle l'écraserait. –

+1

Le OP vs autres utilisateurs semblent être confus quant à savoir si C++ est une option ou non ... Si c'est le cas, alors ce code est bien meilleur que ce désordre de style C. @RonaldPhilipsen Ayant besoin de quelque chose pour exister dans le programme, cela ne signifie pas qu'il soit global: vous pouvez le faire dans une classe ou comme une variable translate-unit-local (static ou, en C++, un namespace) sans nom, puis passez-le partout où c'est nécessaire; cela est généralement moins difficile à raisonner et moins potentiellement dangereux que d'utiliser un global. –

+1

@underscore_d oui, il y avait la balise C++ "hint". Maintenant c'est C. –