« C4D C.O.F.F.E.E. 定数 const | トップページ | 10,000アクセスありがとうございます。 »

C4D C.O.F.F.E.E. 変数の寿命

グローバル変数は、何処からでも使用することができますね。
ローカル変数は…
宣言した関数内と、よく耳にしますが…

ご存知の方が多いと思います。

知っている方は読み飛ばしてください。

では、スクリプトです。

/*
グローバル変数/定数テスト
*/


//グローバル
const var G_CONST = 100;
var g_val = 200;

//関数
functionA()
{
  println("--funcA--");
  println(G_CONST);
  println(g_val);
}


main(doc , op)
{
  println("--main--");
  println(G_CONST);
  println(g_val);

  functionA();
}

問題なく動作しますね。

--main--
100
200
--funcA--
100
200

main()で宣言した変数をfunctionA()で使用は、できませんよね。

/*
ローカル変数テスト
*/


//関数
functionA()
{
  println("--funcA--");
  println(m_val);
}


main(doc , op)
{
  var m_val = 100;

  println("--main--");
  println(m_val);

  functionA();
}

実行すると、エラーが出ます。

[FAIL] Script 'xxxx' Line 9 Pos 17 : Variable or function expected

だからと言って、次のように関数の引数にmain()で宣言した変数を指定しても…

/*
関数の引数と変数
ローカル変数テスト
*/


//関数
functionA(m_val)
{
  println("--funcA--");
  println(m_val);

  m_val += 200;
}


main(doc , op)
{
  var m_val = 100;

  println("--main--");
  println(m_val);

  functionA(m_val);

  println("--main--");
  println(m_val); 
}

関数に変数が渡されたわけではなく、変数に格納された値が渡されただけなのです。
渡された値を関数内で変更しても、関数外で宣言された変数には変化ありませんね。

--main--
100
--funcA--
100
--main--
100

関数を定義した、functionA(m_val)は、たぶんfunctionA(var m_val)という具合に、関数の定義と引数用の変数の宣言が同時に行われるのでしょう。
main関数で宣言した変数の名前と、関数の定義の引数の名前を同じにしたからと言っても、同じものではなく、全くの別変数なのです。

では、次のスクリプト

/*
ブロックと変数
ローカル変数テスト
*/


main(doc , op)
{
  {
    var A = 200;
    var B = 300;

    println("A : " , A);
    println("B : " , B);
  }

  {
    var C = 400;
    var D = 500;

    println("C : " , C);
    println("D : " , D);
  }

}

問題なく実行されます。

A : 200
B : 300
C : 400
D : 500

では、次のように追加変更します。

/*
ブロックと変数
ローカル変数テスト
*/


main(doc , op)
{
  {
    var A = 200;
    var B = 300;

    println("A : " , A);
    println("B : " , B);
  }

  {
    var C = 400;
    var D = 500;

    println("C : " , C);
    println("D : " , D);
  }

  {
    println("A : " , A);
    println("B : " , B);
    println("C : " , C);
    println("D : " , D);
  }
}

同じ関数内にもかかわらず、実行するとエラーが起きます。

[FAIL] Script 'xxxx' Line 24 Pos 24 : Variable or function expected

変数の有効範囲(変数の寿命)は、関数単位ではなくブロック{}単位なのですね。

という事は…

/*
ブロックと共通変数名
ローカル変数テスト
*/


main(doc , op)
{
  var A = 600;
  println("A : " , A);

  {
    var A = 200;
    var B = 300;

    println("{A} : " , A);
    println("{B} : " , B);
  }

  println("A : " , A);
}

最初に宣言された変数Aは、次の新たなブロック内で宣言された変数Aとは別物であるわけですね。
新たに宣言された変数に値が代入されていても、最初に宣言された変数の値は、変更されません。

A : 600
{A} : 200
{B} : 300
A : 600

でも、こうなると、同じ変数名で最初に宣言された変数をブロック内で使いたい場合は、どうすれば良いのだろう?分かりません。
同じ名前にしない事だろう。
紛らわしいし、デバッグも大変になるからね…

今回は、単純にブロックを使いました。

が、気を付けなければならないのが、if()など条件によって変数を使う場合ですね。

/*
ポイントとポリゴンの表示
ローカル変数テスト
*/


main(doc , op)
{
  if(instanceof(op , PointObject))
  {
    var pts = op->GetPoints();
  }else{
    return
;
  }

  if(instanceof(op , PolygonObject))
  {
    var pgs = op->GetPolygons();
  }

  println(op->GetName());
  var c;
  for(c = 0 ; c < op->GetPointCount() ; c++)
  {
    println(c , " : " , pts[c]);
  }

  if(pgs != nil){
    for(c = 0 ; c < op->GetPolygonCount() ; c++)
    {
      println(c , " : " , pgs[c * 4] ,
                    " " , pgs[c * 4 + 1] ,
                    " " , pgs[c * 4 + 2] ,
                    " " , pgs[c * 4 + 3]);
    }
  }
}

ポイントオブジェクトの場合はポイント配列を取得し、そうでなかったら処理を中止。
ポリゴンだったら、更にポリゴン配列を取得。
ポイント配列を表示。
ポリゴン配列が取得できていれば、表示

の、つもり…

[FAIL] Script 'xxxx' Line 20 Pos 29 : Variable or function expected

だけど、ポイント配列の宣言が、if()のブロック内なので、ブロックから脱したとき、変数は無くまります。
同じように、ポリゴン配列変数もブロックから脱したとき、なくなります。

C.O.F.F.E.E.は、変数の宣言を関数内の何処に配置しても良いので、こんな事が起こります。

これを、うまい具合に動作させるには、if()のブロックを削除します。
でも、意図的に組んだのなら良いのですが、変数の宣言は、関数の最初にまとめて宣言するように心がけたほうが良いのでしょうね。

/*
ポイントとポリゴンの表示
ローカル変数テスト
*/


main(doc , op)
{
  if(instanceof(op , PointObject))
    var pts = op->GetPoints();
  else
    return
;

  if(instanceof(op , PolygonObject))
    var pgs = op->GetPolygons();

  println(op->GetName());
  var c;
  for(c = 0 ; c < op->GetPointCount() ; c++)
    println(c , " : " , pts[c]);

  if(pgs != nil){
    for(c = 0 ; c < op->GetPolygonCount() ; c++)
    {
      println(c , " : " , pgs[c * 4] ,
                    " " , pgs[c * 4 + 1] ,
                    " " , pgs[c * 4 + 2] ,
                    " " , pgs[c * 4 + 3]);
    }
  }
}

立方体
0 : [-100.000000,-100.000000,-100.000000]
1 : [-100.000000,100.000000,-100.000000]
2 : [100.000000,-100.000000,-100.000000]
3 : [100.000000,100.000000,-100.000000]
4 : [100.000000,-100.000000,100.000000]
5 : [100.000000,100.000000,100.000000]
6 : [-100.000000,-100.000000,100.000000]
7 : [-100.000000,100.000000,100.000000]
0 : 0 1 3 2
1 : 2 3 5 4
2 : 4 5 7 6
3 : 6 7 1 0
4 : 1 7 5 3
5 : 6 0 2 4

変数の有効範囲の事をスコープと言うのだけど…
Wiki

//ブロックの開始
  var a;
   
  //変数 a の有効範囲
//ブロックの終了

//ブロックの開始
  var pos;

  }  //ブロックの開始
    var vec;

    //変数 vec の有効範囲
  }  //ブロックの終了

  //変数 pos の有効範囲
//ブロックの終了

C.O.F.F.E.E.のスコープの場合は、'var' で変数宣言してからブロックの終了 '}' までという事だろうか?

そう言えば…

寿命とは関係ないですが、switch()のcaseでの変数宣言はできませんよね。

/*
switch()のcaseでの変数宣言
*/


main(doc , op)
{
  var a = 2;
  switch(a)
  {
    case 1:
      var b = 200;
      break;

    case 2:
      var c = 300
      break;

    case 3;
      var d = 500;
  }
}

[FAIL] Script 'xxxx' Line 11 Pos 11 : Variables declaration not allowed here

仮に宣言が可能でも、switch()のブロック内なので、switch()のブロックから脱した時に、なくなってしまいますけどね…

|

« C4D C.O.F.F.E.E. 定数 const | トップページ | 10,000アクセスありがとうございます。 »