そろそろ学年末考査らしい。試験開始は20時間後…
作業はいつも通り通常運行。
年度が替わる頃に、何かしらの発表が出来たらいいなーとか思いつつ、
日々C#とモデリングソフトと格闘しております(勉強は?
C#でオブジェクトのディープ・コピーの方法に悩まされていた日々はどこへいったのやら。
普通に書いても最大15行級の実装ではあるけど、標準で実装してくれないかなぁ…
2009年9月30日水曜日
Visual Studioで日本語を使おう!
文字コードの関係で、Visual Studioでは変数名などに日本語が使えるのです。
(理由が文字コードなので、ハングルとかも使える…かも?対応は未確認ですが…
気持ち悪いかどうかは個人の感覚の問題ですが、本当の意味での初心者(英語すらも分からないような人)にはある程度使いやすい…かもしれません。
ということで、サンプルコードを。
//staticとかpublicとか書き出すと止まらなくなるので一部省略。
//よって、このコードをVC#に食わせてもコンパイルできません。
void 表示する(string 表示する文字列)
{
Console.WriteLine(表示する文字列);
}
void main()
{
表示する()
}
こんなのが見事に通るわけで。
VC#とかのコード自動補完だと、[if]やら[for]等に混じって[表示する]も出てきます(当然か
Twitterにも書いたことですが、「void hyouzisuru()」なんて書かれるよりは潔く「void 表示する()」って書いてくれたほうが見やすいですね。
これでプログラミング界の敷居が若干下がる…と思ったら、これ日本語用の関数ラッパー作らなきゃ駄目じゃん…orz
まあ部の新入生用に、ある程度は作っておいてもいいかも知れないですね。
(理由が文字コードなので、ハングルとかも使える…かも?対応は未確認ですが…
気持ち悪いかどうかは個人の感覚の問題ですが、本当の意味での初心者(英語すらも分からないような人)にはある程度使いやすい…かもしれません。
ということで、サンプルコードを。
//staticとかpublicとか書き出すと止まらなくなるので一部省略。
//よって、このコードをVC#に食わせてもコンパイルできません。
void 表示する(string 表示する文字列)
{
Console.WriteLine(表示する文字列);
}
void main()
{
表示する()
}
こんなのが見事に通るわけで。
VC#とかのコード自動補完だと、[if]やら[for]等に混じって[表示する]も出てきます(当然か
Twitterにも書いたことですが、「void hyouzisuru()」なんて書かれるよりは潔く「void 表示する()」って書いてくれたほうが見やすいですね。
これでプログラミング界の敷居が若干下がる…と思ったら、これ日本語用の関数ラッパー作らなきゃ駄目じゃん…orz
まあ部の新入生用に、ある程度は作っておいてもいいかも知れないですね。
2009年9月3日木曜日
コメントの重要性
いつか何かの記事でちょこっと触れた気がしますが、今回は若干本格的に。
自分が書いたソースコードを他人に理解してもらううえで最も重要なのは、やはり適度なコメントの記述だと私は思うのです。
「適度に」というのは若干あいまいな表現かもしれませんが、それは即ち「他人が関数名・引数名その他を見て、瞬時にその内容が分かりそう」なものでなければ、ということです。
では、3つの例をあげて説明していきます。(例の中の「GetPingdly()」は、関数内で定義されているサーバーにpingを送信し、それが帰ってくるまでの時間を計測、それを戻り値とする関数とします)
まずは1つ目。
------------------------------
void main() //戻り値を返さない関数main、エントリポイント
{
Console.WriteLine("●●●●");//コンソール上に●●●●と表示する
Console.Beep();//ビープ音を鳴らす
Console.WriteLine("△▽△▽");//コンソール上に△▽△▽と表示する
Thread.Sleep(3000);//3000ミリ秒の間動作を休止する
Console.WriteLine(GetPingdly());//pingを送信し、それが帰ってくるまでの時間を計測し表示する
}
------------------------------
明らかにやりすぎです。プログラム初心者向けにソースコードを書くのであれば、ここまでコメントしてもいいかもしれませんが・・・
それでは2つ目。
------------------------------
void main()
{
Console.WriteLine("●●●●");
Console.Beep();
Console.WriteLine("△▽△▽");
Thread.Sleep(3000);
Console.WriteLine(GetPingdly());
}
------------------------------
仲間内で、かつ関数GetPingdlyの存在がはっきりと認知されている場合はこれでもいいかも知れません。
今回はプログラムの内容が簡単すぎるので、「これで十分」という人もいるとは思いますが、ここでDirectXの描画やらIronPythonスクリプトの読み込みやら・・・色々面倒なものがかかわってくると、これで分かってもらえる確率は低くなってくるでしょう。まして赤の他人に公開する複雑なコードがこんな状態では、完全に内容を理解してくれる人は殆どいないも同然の状態になるでしょう。
そこで3つ目。
------------------------------
void main()
{
Console.WriteLine("●●●●");
Console.Beep();
Console.WriteLine("△▽△▽");
Thread.Sleep(3000);
Console.WriteLine(GetPingdly());//pingを送信し、それが帰ってくるまでの時間を計測し表示する
}
------------------------------
自作した関数GetPingdlyにのみコメントをつけているので、①に比べて非常に(コメント的な意味で)すっきりとまとまっています。また、この状態であればGetPingdlyの存在を認知していない人でもその関数の内容を把握できるため、「他人が見てわかるソースコード」でもあるわけですね。
このようなコメントの記述方法だと、②の最後に触れたように「面倒なもの」がかかわってきた場合でも「他人に分かりやすい」ソースコードになるわけです。また、自分が書いたソースコードを後から見返すときにも、コードの内容を一目でつかみやすく、大変便利になります。
ちなみに、③の方法を、「DLLImportを多用するソースコード」に使うと・・・
場合によっては、コードの量が3~4倍になってしまいます(^^;
VC#だと、summaryの部分はまとめて折りたためるので・・・ある程度は良さそうなんですがね(ホントカオイ
2009.9.3 AM10:52 一部表記を修正しました。指摘してくださった方ありがとうございます。
自分が書いたソースコードを他人に理解してもらううえで最も重要なのは、やはり適度なコメントの記述だと私は思うのです。
「適度に」というのは若干あいまいな表現かもしれませんが、それは即ち「他人が関数名・引数名その他を見て、瞬時にその内容が分かりそう」なものでなければ、ということです。
では、3つの例をあげて説明していきます。(例の中の「GetPingdly()」は、関数内で定義されているサーバーにpingを送信し、それが帰ってくるまでの時間を計測、それを戻り値とする関数とします)
まずは1つ目。
------------------------------
void main() //戻り値を返さない関数main、エントリポイント
{
Console.WriteLine("●●●●");//コンソール上に●●●●と表示する
Console.Beep();//ビープ音を鳴らす
Console.WriteLine("△▽△▽");//コンソール上に△▽△▽と表示する
Thread.Sleep(3000);//3000ミリ秒の間動作を休止する
Console.WriteLine(GetPingdly());//pingを送信し、それが帰ってくるまでの時間を計測し表示する
}
------------------------------
明らかにやりすぎです。プログラム初心者向けにソースコードを書くのであれば、ここまでコメントしてもいいかもしれませんが・・・
それでは2つ目。
------------------------------
void main()
{
Console.WriteLine("●●●●");
Console.Beep();
Console.WriteLine("△▽△▽");
Thread.Sleep(3000);
Console.WriteLine(GetPingdly());
}
------------------------------
仲間内で、かつ関数GetPingdlyの存在がはっきりと認知されている場合はこれでもいいかも知れません。
今回はプログラムの内容が簡単すぎるので、「これで十分」という人もいるとは思いますが、ここでDirectXの描画やらIronPythonスクリプトの読み込みやら・・・色々面倒なものがかかわってくると、これで分かってもらえる確率は低くなってくるでしょう。まして赤の他人に公開する複雑なコードがこんな状態では、完全に内容を理解してくれる人は殆どいないも同然の状態になるでしょう。
そこで3つ目。
------------------------------
void main()
{
Console.WriteLine("●●●●");
Console.Beep();
Console.WriteLine("△▽△▽");
Thread.Sleep(3000);
Console.WriteLine(GetPingdly());//pingを送信し、それが帰ってくるまでの時間を計測し表示する
}
------------------------------
自作した関数GetPingdlyにのみコメントをつけているので、①に比べて非常に(コメント的な意味で)すっきりとまとまっています。また、この状態であればGetPingdlyの存在を認知していない人でもその関数の内容を把握できるため、「他人が見てわかるソースコード」でもあるわけですね。
このようなコメントの記述方法だと、②の最後に触れたように「面倒なもの」がかかわってきた場合でも「他人に分かりやすい」ソースコードになるわけです。また、自分が書いたソースコードを後から見返すときにも、コードの内容を一目でつかみやすく、大変便利になります。
ちなみに、③の方法を、「DLLImportを多用するソースコード」に使うと・・・
場合によっては、コードの量が3~4倍になってしまいます(^^;
VC#だと、summaryの部分はまとめて折りたためるので・・・ある程度は良さそうなんですがね(ホントカオイ
2009.9.3 AM10:52 一部表記を修正しました。指摘してくださった方ありがとうございます。
2009年8月31日月曜日
定数化の重要性を訴えてみる
「ゲームのプログラミングの上で、知っていると非常に楽になれる」初心者向けの記事です。
例えば、以下のようなコードがあったとします。
(関数Data CreateData(string name)は、引数nameを参照し、そのデータから別のデータを生成してそれを戻り値として返す関数とします)
---------------------------------------
void Main()
{
Data dat1 = null;
Data dat2 = null;
Data dat3 = null;
dat1 = CreateData("hoge.txt");
dat2 = CreateData("hoge.txt");
dat3 = CreateData("hoge.txt");
}
---------------------------------------
(まあ、こんなコードを実際に使う例はないと思いますが…w
ここで、CreateData()の引数となっているhoge.txtの名前が「hoge2.txt」になったとします。このとき、上記の方法だと、hoge.txtとなっている部分全てをhoge2.txtに置き換える、すなわち3回の置換の必要が出てくるわけです。
しかしながら、以下のようにソースコードを書き変えると…
---------------------------------------
void Main()
{
const string data_path = "hoge.txt"
Data dat1 = null;
Data dat2 = null;
Data dat3 = null;
dat1 = CreateData(data_path);
dat2 = CreateData(data_path);
dat3 = CreateData(data_path);
}
---------------------------------------
元となっている定数「data_path」の値を書き変える、すなわち1回の置換だけで、1つ目のソースコードと同様の置換ができるわけです。
マジックナンバーは、いつどのように変わるか予測できないものです。たとえば、仕様変更で画面の大きさを640*480から800*600にしたとき、それに関わる全ての数値を全て置換するには膨大な労力がかかるでしょう。ですが、定数方式をとっていれば、この面倒な置換処理などとは別れられるわけです。
この通り、非常に便利な定数化。使わない手はないでしょう。
---------------------------------------
9/1 AM1:06追記。2つ目のソースのCreateData()の引数が文字列そのままになってました。正しくは「""」を抜いた状態です。(修正済み)
指摘してくださったsle様、ありがとうございましたm(_ _)m
例えば、以下のようなコードがあったとします。
(関数Data CreateData(string name)は、引数nameを参照し、そのデータから別のデータを生成してそれを戻り値として返す関数とします)
---------------------------------------
void Main()
{
Data dat1 = null;
Data dat2 = null;
Data dat3 = null;
dat1 = CreateData("hoge.txt");
dat2 = CreateData("hoge.txt");
dat3 = CreateData("hoge.txt");
}
---------------------------------------
(まあ、こんなコードを実際に使う例はないと思いますが…w
ここで、CreateData()の引数となっているhoge.txtの名前が「hoge2.txt」になったとします。このとき、上記の方法だと、hoge.txtとなっている部分全てをhoge2.txtに置き換える、すなわち3回の置換の必要が出てくるわけです。
しかしながら、以下のようにソースコードを書き変えると…
---------------------------------------
void Main()
{
const string data_path = "hoge.txt"
Data dat1 = null;
Data dat2 = null;
Data dat3 = null;
dat1 = CreateData(data_path);
dat2 = CreateData(data_path);
dat3 = CreateData(data_path);
}
---------------------------------------
元となっている定数「data_path」の値を書き変える、すなわち1回の置換だけで、1つ目のソースコードと同様の置換ができるわけです。
マジックナンバーは、いつどのように変わるか予測できないものです。たとえば、仕様変更で画面の大きさを640*480から800*600にしたとき、それに関わる全ての数値を全て置換するには膨大な労力がかかるでしょう。ですが、定数方式をとっていれば、この面倒な置換処理などとは別れられるわけです。
この通り、非常に便利な定数化。使わない手はないでしょう。
---------------------------------------
9/1 AM1:06追記。2つ目のソースのCreateData()の引数が文字列そのままになってました。正しくは「""」を抜いた状態です。(修正済み)
指摘してくださったsle様、ありがとうございましたm(_ _)m
2009年8月20日木曜日
この関数は何のために?#01
.Netなどについて色々調べていると、何やら用途の良く分からない関数が。
http://dobon.net/vb/dotnet/system/isleapyear.html
このDateTimeクラスのIsLeapYearメソッドなのですが、日にちも含めた時計機能を内部で実装するプログラムでもない限り、まず使う機会がないような気がするんですよねぇ…
折角だ、ちょっとこれ使って妙なプログラムでも組んでみますかw
http://dobon.net/vb/dotnet/system/isleapyear.html
このDateTimeクラスのIsLeapYearメソッドなのですが、日にちも含めた時計機能を内部で実装するプログラムでもない限り、まず使う機会がないような気がするんですよねぇ…
折角だ、ちょっとこれ使って妙なプログラムでも組んでみますかw
2009年2月19日木曜日
いろいろなDLL読み込み方法@C#
Cで書かれたDLL(test.dll)内の以下の関数を呼び出してみましょう。
関数の中身は非常にアレですが、決して気にしないでください(何
bool IsLoli(int num)
{
if (num == 21)
{
return true;
}
return false;
}
では、実際にこの関数をC#で呼び出してみましょう。
方法1.
[DllImport("test.dll", EntryPoint = "IsLoli")
public static extern bool IsLoli(int num);
この方法はかなり一般的なものではないでしょうか。
MSDNのデベロッパーセンターの解説もこんな具合でしたし、ね。
しかし、これでは「関数を呼び出す」動作に比較的長い時間がかかってしまいます。
そこで「SuppressUnmanagedCodeSecurity」を使うのですが、これは「セキュリティチェックを殆ど行わない代わりに、呼び出し速度を上げる」というものです。
方法2.
[DllImport(DLL_NAME, EntryPoint = "IsLoli"), SuppressUnmanagedCodeSecurity]
public static extern bool IsLoli(int num);
この方法はセキュリティチェックが初めの1回しか行われないので、MSDNのサイトにも書いてある通りセキュリティホールから悪意のあるコードが関数呼び出しを行うことも十分考えられるわけです。
速度にばかり気を取られ、セキュリティ面が疎かになっていては(かなり)まずいですから、くれぐれも慎重に使っていきたいものですね。
……と良いつつ、自分は方法2をばんばん使ってますが・・・^^;
関数の中身は非常にアレですが、決して気にしないでください(何
bool IsLoli(int num)
{
if (num == 21)
{
return true;
}
return false;
}
では、実際にこの関数をC#で呼び出してみましょう。
方法1.
[DllImport("test.dll", EntryPoint = "IsLoli")
public static extern bool IsLoli(int num);
この方法はかなり一般的なものではないでしょうか。
MSDNのデベロッパーセンターの解説もこんな具合でしたし、ね。
しかし、これでは「関数を呼び出す」動作に比較的長い時間がかかってしまいます。
そこで「SuppressUnmanagedCodeSecurity」を使うのですが、これは「セキュリティチェックを殆ど行わない代わりに、呼び出し速度を上げる」というものです。
方法2.
[DllImport(DLL_NAME, EntryPoint = "IsLoli"), SuppressUnmanagedCodeSecurity]
public static extern bool IsLoli(int num);
この方法はセキュリティチェックが初めの1回しか行われないので、MSDNのサイトにも書いてある通りセキュリティホールから悪意のあるコードが関数呼び出しを行うことも十分考えられるわけです。
速度にばかり気を取られ、セキュリティ面が疎かになっていては(かなり)まずいですから、くれぐれも慎重に使っていきたいものですね。
……と良いつつ、自分は方法2をばんばん使ってますが・・・^^;
2009年2月14日土曜日
シリアライズに関して
C#の「シリアライズ」。
これは「クラスや構造体等のオブジェクトの中身を丸ごとバイナリ化して保存する」というものです。勿論そのようにして保存されたバイナリファイルを読み込むことで、簡単に保存した情報を復元できるのです(^^)
自分はこれをC#でのデータ保存(最近になってからですが)に用いているのですが、どうやらこれには大きな問題点があるそうです。
それは、「C#のバージョン毎に、シリアライズの互換性が保障されていない」ということです。
自分自身はVC#2008即ちC#3.0しか使ったことがないため、まだその問題には直面していません。ですが、今後C#4.0がリリースされる時に備えて、シリアライズではない(かつ、ある程度平易な)データの保存方法を学んでおく方がいいかもしれませんね(^^;
これは「クラスや構造体等のオブジェクトの中身を丸ごとバイナリ化して保存する」というものです。勿論そのようにして保存されたバイナリファイルを読み込むことで、簡単に保存した情報を復元できるのです(^^)
自分はこれをC#でのデータ保存(最近になってからですが)に用いているのですが、どうやらこれには大きな問題点があるそうです。
それは、「C#のバージョン毎に、シリアライズの互換性が保障されていない」ということです。
自分自身はVC#2008即ちC#3.0しか使ったことがないため、まだその問題には直面していません。ですが、今後C#4.0がリリースされる時に備えて、シリアライズではない(かつ、ある程度平易な)データの保存方法を学んでおく方がいいかもしれませんね(^^;
2008年11月16日日曜日
C#
この度、使用言語をC++からC#に移行しました。
勿論、開発環境はVisual Studioのままです^^;
C#は楽ですよ~(本当
例えば、以下のようなC++のコードがあったとします。
----------------------------------------------------------------
int n = 3;
string m = "Hello,World!";
----------------------------------------------------------------
一々intやらstringやらを書いていたら、いくつもの型の変数をたくさん用意する際には不便です。
ですが、C#では……
----------------------------------------------------------------
var n = 3;
var m = "Hello,World!";
----------------------------------------------------------------
型の宣言の部分をvarに置き換えることで、右辺の値から自動的に型を決めてくれるのです。
これは(実際に使ってみると)かなり便利なものですよ~(^^)
勿論、開発環境はVisual Studioのままです^^;
C#は楽ですよ~(本当
例えば、以下のようなC++のコードがあったとします。
----------------------------------------------------------------
int n = 3;
string m = "Hello,World!";
----------------------------------------------------------------
一々intやらstringやらを書いていたら、いくつもの型の変数をたくさん用意する際には不便です。
ですが、C#では……
----------------------------------------------------------------
var n = 3;
var m = "Hello,World!";
----------------------------------------------------------------
型の宣言の部分をvarに置き換えることで、右辺の値から自動的に型を決めてくれるのです。
これは(実際に使ってみると)かなり便利なものですよ~(^^)
登録:
投稿 (Atom)
