配列の要素の最大値を指定するには?


あい  2005-01-13 01:17:27  No: 118814

早速質問ですが,
要素が何個かわかっていない配列の最大値はどうやって指定すればいいでしょうか?

ReDim Preserve a(0 To 50)

としたのですが,50のところがループするごとに変わるプログラムを組んでいるため,

ReDim Preserve a(0 To UBound(a))

としたのですが,インデックスが有効範囲にありませんというエラーが
出てしまいます.
どうすればいいでしょうか?


特攻隊長まるるう  2005-01-13 01:32:27  No: 118815

なんの問題も無いです。+ 1 を忘れてるとかでは?
[VB6.0]
Private Sub Command1_Click()
    Dim a() As Integer
    Dim i As Integer
    ReDim a(0)
    For i = 0 To 3
        a(i) = i
        ReDim Preserve a(0 To UBound(a) + 1)
    Next i
    For i = 0 To UBound(a)
        Debug.Print a(i)
    Next i
End Sub


じゃんぬねっと  URL  2005-01-13 01:35:02  No: 118816

+ 1 しないといけませんよね。

ReDim Preserve ArrayVar(UBound(ArrayVar()) + 1)

# どうせゼロからなので、「0 To」は不要ですね。

また、パフォーマンスを上げるなら、+100単位とかで再定義しておいて、
最後のループを抜ける時に、データが入っている位置まで縮小して再定義するべきですね。


いな  2005-01-13 01:35:20  No: 118817

要素数ががわかっていないのであれば指定できませんよね?
わかった時点でRedimするなどをし、指定してください。

ReDim Preserve a(0 To UBound(a)+1)

とか。


じゃんぬねっと  URL  2005-01-13 01:36:20  No: 118818

気が合いますなぁ... (訳:被ってしまって申し訳ありません m(_ _)m )


いな  2005-01-13 01:44:17  No: 118819

三人かぶるとはこれまためずらしい。


特攻隊長まるるう  2005-01-13 01:44:53  No: 118820

>気が合いますなぁ... (訳:被ってしまって申し訳ありません m(_ _)m )
…ま、それほど間違うパターンが明白な質問と言う事でしょう(^^;)。
(訳:ボクはメモ帳に文章書いて、送信ボタン押す直前に更新して
被らないようにしてます。…結構、ここに居座って長いですからw )


kara  2005-01-13 02:01:16  No: 118821

> # どうせゼロからなので、「0 To」は不要ですね。
Option Base 1 などとしていた場合はあるべきかな
と言ってみる


じゃんぬねっと  URL  2005-01-13 02:30:06  No: 118822

>いな さん:
いなさんとは、別の掲示板で被ってしまったことがあったり...(w

>特攻隊長まるるう さん:
私も普段、更新してから投稿するようにしております。
ですが、よく忘れちゃいますね... ディスプレイに貼っておかないと (w

>Kara さん (ん? 私の知っている「かる」さんかな?):
う、そ、そうですね...
大変失礼しました m(_ _)m


いな  2005-01-13 02:49:18  No: 118823

>じゃんぬねっとさん
そそ、よく別の掲示板でかぶったり、
自分は、何か目新しい考え方や面白いロジックはないかなぁ〜と、巡回してます。


kara  2005-01-13 03:09:26  No: 118824

> (ん? 私の知っている「かる」さんかな?):
「かる」と名乗ったことは無いので、おそらく別の人かと思われます
# 当方いくつかの掲示板でkaraを名乗っているのですが、MS MVPの辛島さんとかぶっていることに最近気づきました

それはそうと、じゃんぬねっとさんってmixiの「C言語とC++言語」コミュの「ひどい! ソース!」トピックの47さんですよね?
私は53にて発言した虎( ´;゜;ё;゜;)です
以後お見知りおきを

ってここで雑談してどうする>俺


じゃんぬねっと  URL  2005-01-13 03:44:50  No: 118825

> MS MVPの辛島さんとかぶっていることに最近気づきました
あ、私のしっている「かる」さんはその「辛島」さんでございます。

> それはそうと、じゃんぬねっとさんってmixiの「C言語とC++言語」コミュの
>「ひどい! ソース!」トピックの47さんですよね?
> 私は53にて発言した虎( ´;゜;ё;゜;)です
> 以後お見知りおきを
うわっ!! 世界は狭い... マイミクしましょー

ってここで、マイミク申請してどうするw > じゃんぬ

# 皆さま、スレ汚しお許しくださいませ m(_ _)m


あい  2005-01-13 03:48:39  No: 118826

返信ありがとうございます.

ReDim a(0)
    For i = 0 To 3
        a(i) = i
        ReDim Preserve a(0 To UBound(a) + 1)
    Next i

1.a(0)なのに,どうしてiに0から3を入れることができるのですか?

2.皆様,かぶるくらい常識なことなのですが,どうしてUBoundに1を足すのでしょうか?


いな  2005-01-13 04:14:27  No: 118827

>2.皆様,かぶるくらい常識なことなのですが,どうしてUBoundに1を足すのでしょうか?

Private Sub Form_Load()
    Dim a() As String
    
    ReDim a(5)                   'aの要素数は5

    ReDim Preserve a(UBound(a))  'aの要素数を、aの要素数に拡張
End Sub

もともと有るa()の要素数は5なのに、Redimする意味はあるのでしょうか?


いな  2005-01-13 04:23:26  No: 118828

>>1.a(0)なのに,どうしてiに0から3を入れることができるのですか?

る〜ぷを考えてみましょう

ReDim a(0)
    For i = 0 To 3  
        a(i) = i    ...(i)
        ReDim Preserve a(0 To UBound(a) + 1)  ...(ii)
Next i

1.a(0)で宣言
2.For文開始、i=0
3.(i)の処理でI=0のためa(0)=0が入る
4.(ii)の処理でUBound(a) = 0のためa(1)ができる
5.For文にもどり、 i=1
6.(i)の処理でI=1のためa(1)=1が入る
7.(ii)の処理でUBound(a) = 1のためa(2)ができる
8.For文にもどり、 i=2
9.(i)の処理でI=2のためa(2)=2が入る
10.(ii)の処理でUBound(a) = 2のためa(3)ができる
11.For文にもどり、 i=3
12.(i)の処理でI=3のためa(2)=3が入る
13.(ii)の処理でUBound(a) = 3のためa(4)ができる
14.Exit Sub

以上ですが、不明点は?


いな  2005-01-13 04:24:42  No: 118829

激しく誤爆

>>12.(i)の処理でI=3のためa(2)=3が入る

12.(i)の処理でI=3のためa(3)=3が入る

です。


kara  2005-01-13 04:28:40  No: 118830

なんだか人の揚げ足とりばっかりしている気がしますが・・・
いなさん
>     ReDim a(5)                   'aの要素数は5
Option Baseが指定されていない限り、要素数は6ではないでしょうか?(0,1,2,3,4,5)
5は添字の最大数ですね

じゃんぬねっとさん
> うわっ!! 世界は狭い... マイミクしましょー
では、mixiで会いましょう


Dental  2005-01-13 04:29:18  No: 118831

# 被るのを覚悟の上で回答。

> 1.a(0)なのに,どうしてiに0から3を入れることができるのですか?
For〜Nextのループ中で、毎回 ReDim しなおして、
配列のサイズを、一つずつ増やしているからです。

『ReDim a(0)』が実行された直後は、a(0) しか使えません。
『ReDim a(1)』が実行されれば、a(0)とa(1)が指定可能になります。
『ReDim a(2)』であれば、a(0)〜a(2)が指定可能になるわけです。

ただし、「ReDim a(2)」を実行すると、配列のサイズは変更されますが、
既存のデータまでクリアされてしまいます。それを防ぐために、
「ReDim Preserve a(1)」のように、Preserveをつけて処理する事になります。

もっとも、提示されたコードでは「0 から 3まで」という事が明らかなので、
毎回 ReDim Preserve するのではなく、
  ReDim a(3)
  For i = 0 To 3
     a(i) = i
  Next
のようにした方が、効率が良いです。

> 2.皆様,かぶるくらい常識なことなのですが,どうしてUBoundに1を足すのでしょうか?

例えば、
  ReDim a(2)
で宣言された配列は、a(0)〜a(2) までが使えますね。

この配列に対して、新たに a(3) も使えるようにするなら、
  ReDim Preserve a(3)
のように、上限値に「3」を指定する必要があります。
(ここまでは分かりますよね?)

一方、UBound関数は、添字の最大値を返す関数なので、
  ReDim a(2)               '←これだと、a(0)〜a(2) しか使えない
  n = UBound(a)            '←この時、n には 2 という値が入る
  ReDim Preserve a(n + 1)  '←これにより、a(3) まで使えるようになる
のように処理されます。

そしてこれを、変数 n を使わずにまとめて書くと、
  ReDim a(2)
  ReDim Preserve a(UBound(a) + 1)
となりますね。


いな  2005-01-13 04:44:18  No: 118832

karaさん
そうですね。
どうやら、疲れてるようです。


じゃんぬねっと  URL  2005-01-13 05:29:42  No: 118833

> どうやら、疲れてるようです。
今日は至るところで、いなさんを見かけますからね(ぇ


ららら  2005-01-13 05:32:26  No: 118834

なんか静かな死闘を垣間見た気がしたぞw>(  ´Д`)
…で、もともとの質問もオモロイしw


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加