ローカルのauto変数(関数の中で宣言したstatic属性をつけてない変数)の初期値は「不定」です。「不定」というのは、プログラムを実行してみるまでその値が何になるか決まらないこと。0かも、1000かも、-32768かも、やってみるまでわかりません(まぁ、現実にはある傾向を持ったりはしますけれど、その期待をしてはいけないというのが約束)。で。
Arduino
1void loop(){
2 byte data_size;
3 long ans=0;
4 byte num[data_size];
ここまで、data_size変数の値は不定です。もしかしたら0かも、-100かもしれません。要素数が-100の配列ってなんでしょうね。どんな動作をしても文句は言えない状態です。一言で言えば「やってはいけない」です。
なんでこんなことをしているかと想像すると、
data_size=Serial.available();
でdata_sizeに3が入ったとしたら、その途端にnum[3]の配列が出来たことになる...と期待したんじゃないかと思います。残念ながらそうではありません。C/C++(そしてC++をベースにしたArduino言語を含む以下略)では、各文は「その時の値」で動作します。
byte num[data_size];
はその文を実行したときのdata_sizeの値によって動作が決まり、その後data_sizeをどんな値にしようともその結果が変わることはありません。
ついでにいうと、C++の文法上は配列の宣言に置いて要素数に変数は使えません(Cではオプション規格です)。Arduino IDEが内部的に使っているgccの独自拡張によって使えているだけだ、というのは一応気を付けておいたほうがいいかも知れません。
そして、恐ろしいことに、C/C++では、配列のサイズがめちゃくちゃで、マトモなサイズでなくても配列を生成し、そのめちゃくちゃな配列にデータを書き込むことも、さらには配列としてきちんと確保していない場所にデータを書き込むことも出来てしまいます。そのような場合、素直に「メチャクチャな動き」をしてくれればまだマシなのですが、しばしば「一見ちゃんと動いているように見えるが、関係のなさそうなところで突然破綻する」ことがあります。
以上が言語のレベルでの問題。
次はアプリケーションレベルの問題。
シリアル通信の物理的なデータの単位は1バイトです。それ以上でも以下でもありません(まぁ、UARTの設定で7bitとか9bitとかも出来るかも知れませんが、それはちょっとおいといて)。ナマのシリアル通信には「2桁」とか「3桁」という概念はないのです。送信側が"123"と"45"の数字を一気に送ったとして、受信側はそれをどう区切って受け取るかはシリアル通信のレイヤでは規定出来ないのです。"1"と"2345"、"12"と"345"、あるいは"1"と"2"と"3"と"4"と"5"、かも。"123"と"45"としてやり取りするには、送り側と受け側で「何らかの約束」をしてデータをグループ化する必要があります。
多くの場合は、改行やカンマなど、本来のデータには含まれていない文字を「区切り」(デリミタ)として送ること。送る側は"123"のあとに改行コードを送り、続けて"45"を送って改行コードを送る。受ける側は'1''2''3'を受信したあと改行コードが来たら、'1''2''3'が一組なんだなぁ、と知ることが出来て、じゃあそれを"123"として扱えばいいことがわかるわけです。"45"も同様。
データが必ず3桁だと決まっているのなら、"123456"を送っては"123" "456"と受け取る、と決められるかも知れません。
あるいは、あまり確実でないかも知れませんが、時間で切ってやるという考えもあるかも知れません。ある時間以内にまとめて"123"を送って、ある時間内に受け取ったデータは連続して"123"とする。そこから一定以上の間隔をあけて"45"を送り、受ける、なんていうのも考えられるかもしれません。
いろいろ方法はあります。通信は送信側と受信側が合意していればいいのですから。
Arduinoで、適当な区切り文字を設定する場合であれば、Serial::readStringUntil()関数を使うのが楽かも知れません。調べてみて下さい。
訓練としてそういう便利な関数を使わず地道にやるというのなら、例えば
Arduino
1const int SIZE = 16;
2byte buf[SIZE];
3int idx = 0;
4
5void setup() {
6 Serial.begin(9600);
7 Serial.print("Please enter the number!\n");
8}
9
10void loop() {
11 if (Serial.available() > 0) {
12 buf[idx] = Serial.read();
13 if (buf[idx] == '\n') { //データの区切りを受信した
14 int num=0;
15 int i=0;
16 while( '0'<= buf[i] && buf[i]<='9'){//有効な数字なら変換
17 num*=10;
18 num+=buf[i]-'0';
19 i++;
20 }
21 Serial.println(num);
22 Serial.print("Please enter the number!\n");
23 idx = 0;
24 } else {
25 idx = (idx + 1) % SIZE; //受信位置を一つすすめる。範囲外にさせないガードをしておく
26 }
27 }
28}
とか。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。