こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

p->next(ポインタ)的なことをC#で

環境:VisualStudio2005 .Net C# FrameWork 2.0

プログラムを作成してみましたが、
どこが間違っているのかもわかりにくい上に
思うような結果が得られませんでした。
もっとスマートで美しい解法はないでしょうか。
お知恵をお貸しください。
---
No, Class, ChildNo, Status からなるクラス Info があり、
Info 型の配列 info には以下のデータが格納されているとします。
なお、PrimaryKey=No+Classで、配列 info は、No+Classの昇順に並んでいるとします。

class Info
{
byte no;
byte class;
byte childno;
byte[] status= new byte[256];
public Info()
{
for (int i = 0; i < 256; i++)
{
this.status[i] = 0;
}
}
}

Info []info = new Info[8];

No,Class,ChildNo,Status
1, 1, 2, ___
1, 2, 3, ___
1, 3, 4, ___
2, 1, 5, ___
3, 1, 6, ___
4, 1, 7, ___
5, 1, 8, ___
5, 2, 9, ___

まず、No=1,Class=1をキーとしてChildNo=2を取得し、
見つかったChildNoをNoとしNo=2,Class=1をキーとしてChildNo=5を取得、
次に、No=5,Class=1をキーとしてChildNo=8を取得、
次に、No=8,Class=1をキーとしてデータが見つからないので終了
最終的に、No=1,Class=1のStatusの[2][5][8]に1をセットしたいと思います(残りは0)。
同様に、No=2,Class=1からは5,8のデータを
No=5,Class=1からは8のデータを取得したいです。

for (int i = 0; i < info[i].Length; i++)
{
Func(info[i].No, info[i].Class);
}

private byte Func(byte no, byte class)
{
byte cno = 0;
byte tmpno = 0;
byte ret = 0;

for (int i = 0; i < info.Length; i++)
{
if (info[i].no == no && info[i].class == class)
{
cno = info[i].childno;
tmpno = info[i].childno;
info[i].status[childno] = 1;

while ((ret = SetNearFlag(tmpno, class)) != 0)
{
info[i].status[ret] = 1;
tmpno = ret;
}
info[i].status[tmpno] = 1;
break;
}
}
return cno;
}

よろしくお願いいたします。

投稿日時 - 2010-01-12 13:46:07

QNo.5587426

困ってます

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

C#では、classは参照型になっています。
参照型、というのは、変数に代入されるのが、そのもの自体ではなく、それへの参照(かなり乱暴な言い換えをすればポインタ)になる型です。

なので
Infoクラスの変数 infoA があるとして
C#でInfoクラスの変数infoAの宣言
Info infoA ;
は C++での
Info * infoA ;
にあたり

C/C++での
p->next = infoA ;
はC#では
p.next = infoA ;
です。

詳しくは「C# 参照型」で検索してみてください

投稿日時 - 2010-01-12 21:14:55

特定の方法について、ではなく結果同じになればいいよね?

面倒だ、という理由により仕様の勝手な変更や、省略を行いました。
1.俺は本当はメンバ変数をpublicにするのが好きではなく、大抵はプロパティにしている。
2. ソースコード中にデータ書きこむのもあれなので、外部のファイルから読み込んでいる。

3.元のソースコードのクラスのメンバがbyte型であるため文字列をバイト配列にする(場合によっては整数として読み込む)必要があるのだが、string型でいいやと。

4. C#においてclassは予約語なので、先頭に@をつけないとメンバにできない。いちいち@つけるのが面倒くさかったのでメンバー名をざっくりinfoclassと変更
===============xxx.txt=================
1
1
2
0
1
2
3
0
1
3
4
0
2
1
5
0
3
1
6
0
4
1
7
0
5
1
8
0
5
2
9
0
===================Q5587426.cs=======================
using System;



namespace Q5587426

{



class Info

{

public string no;

public string infoclass;

public string childno;

public string status;



public Info(string tmpno,string tmpinfoclass,string tmpchildno)

{

this.no = tmpno;

this.infoclass= tmpinfoclass;

this.childno = tmpchildno;

this.status = "";



}

}



class MainClass

{

public static void Main (string[] args)

{

System.Collections.Generic.List<Info> source = new System.Collections.Generic.List<Info>();

System.Collections.Generic.List<string> dest = new System.Collections.Generic.List<string>();







System.IO.StreamReader sw = new System.IO.StreamReader("xxx.txt",System.Text.Encoding.UTF8);



while(!sw.EndOfStream){

source.Add(new Info(sw.ReadLine(),sw.ReadLine(),sw.ReadLine()));

sw.ReadLine();

}



Info target = new Info("1","1","");

while(true){

int index = source.FindIndex(

delegate(Info info){return (info.no == target.no) && (info.infoclass == target.infoclass);}

);

if (index < 0){

break;

}

dest.Add(source[index].childno);

target.no = source[index].childno;

target.infoclass = source[index].infoclass;

}

dest.ForEach(delegate(string s){ System.Console.WriteLine(s);});

}

}

}
==============出力結果===========
2
5
8
==============その他の感想=======
再帰使った方が楽かなーと思ったけど、件数が多くなったときに階層が深くなってスタック消費してやばいかな、と思ったので取りやめ。関数型言語なんかではこちらの路線で行くだろう。

投稿日時 - 2010-01-12 15:57:22

あなたにオススメの質問