• ベストアンサー

c# でoutとrefの機能以外の違い

 こんにちはc#初心者です。  メソッドに値を渡す時に「outキーワード」と「refキーワード」が使えますが、これらは書き込み専用と、読み書き両用の機能差以外にデータの渡し方などの差はあるのでしょうか?    intを渡したときの時間を比較してみましたが、差は0.5%未満、誤差の範囲内でした。  差がないのなら余計な心配なのですが、どなたか詳しい方がいらっしゃいましたら教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.3

以下にoutとrefそれぞれの解説がありますが、「コンパイル時には同等に扱われる」と明記されています。ですから差は無いと思っていいのではないかと。 http://msdn.microsoft.com/ja-jp/library/14akc2c7(v=vs.80).aspx http://msdn.microsoft.com/ja-jp/library/t3c3bfhx(v=vs.80).aspx 一応キーワードの意味づけとしてはrefが「参照をメソッドに渡す」であるのに対してoutは「メソッドから出力を受け取る」であるという違いはありますが、やってることは殆ど一緒です。

koumei000
質問者

お礼

そうなのですね。勉強になりました。ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • oboroxx
  • ベストアンサー率40% (317/792)
回答No.2

推測もありますが、受け渡し方はどちらも参照受け渡しです。 outがついたものは、その変数が渡される前に値が設定されていなくても、コンパイルの時に警告などの表示はないですが、 refに関しては、その関数の中で値が使用されようがされまいが、受け渡す前に値が設定されていなければ警告などがコンパイルの時に表示されます。 以上のことから、主に開発者がバグを発見しやすくするためのキーワードと思っております。 また、その関数を再利用する人から見ると、refなら値を設定しないといけないと思い、outなら特に気にする必要がないのだなということが見ただけで読み取れるので便利かなと思います。

koumei000
質問者

お礼

なるほど、確かにそれは便利です。

全文を見る
すると、全ての回答が全文表示されます。
  • axsies
  • ベストアンサー率64% (38/59)
回答No.1

int add(int x, int y) {  return x + y; } メソッドに値型を渡す場合、通常は値渡しになります。 上記addメソッドの仮引数x, yには呼び出したときに値がコピーされて渡されるということです。 引数にrefキーワードを付けると、参照渡しになり、このコピーが回避できます。 int型では差はでないと思いますが、巨大な構造体を頻繁にメソッドに渡さなければならない場合は差がでるはずです。(C#の構造体は値型です) ただC#では、こうした値渡しのコピーを回避する目的で参照渡しにする、というのはあまり見たことがないです。

koumei000
質問者

補足

……あの、質問は「outキーワード」と「refキーワード」の違いについてなのですが……。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • c# メソッド名について

    こんにちは。c#初心者です。  現在メソッドの命名について尋ねたいことがあります。  戻り値をもつタイプのメソッド「SampleMethod」があったのですが、そこにほぼ同じ動作で戻り値を持たない代わりに「out」キーワードで値を取得させるメソッドを追加しました。  そこで命名しなければならないのですが、「SampleMethod2」のような語尾に数字をつけるような命名は好ましくないのでしょうか?  しっかりと区別したいのでオーバーロードするつもりはありませんが、インテリセンスで互いにすぐ近くに出てくれたほうが何かと助かります。  初心者なので細かい命名規定などは分かりませんのでどなたか詳しい方、分かる方がいらっしゃればご意見を伺わせてもらえませんか?

  • C#での自作DLL(C言語)の並列化

    C言語で自作したDLLをC#で使いたいと考えております。 このDLLの計算量は多くて、値を返すまでに時間がかかります。 そのためにC#のフォームが応答なしになってしまうので並列化したいと思ったのですがうまくいきませんでした。 このDLLは ・int型の戻り値 ・6個の引数 ・上の引数のうち、1つはoutキーワード(ポインタ渡し) です。 どのようにすれば、うまく並列化できるでしょうか。 ご教授お願いいたします。

  • VS2010C#からのDLL使用について

    VS2010 C#からVC6で作成したDLLへint配列を引数として渡したい。 VC++6で作成されたDLLがあります。 ここで定義されている int test(char*fname,int* x,int* y); ファイルのフルパスを渡すと 返り値が関数の成否のコードを返す。 処理内で x,y にファイルから読み込んだ値が それぞれ上限100個としてセットして返す といったような関数を C#から呼び出したいのですが 1 [DllImport("dll名", EntryPoint = "test", CallingConvention = CallingConvention.Cdecl)] public unsafe static extern int test(IntPtr fname, ref int* x,ref int* y); 2 [DllImport("dll名", EntryPoint = "test", CallingConvention = CallingConvention.Cdecl)] public unsafe static extern int test(IntPtr fname, ref IntPtr x,ref IntPtr y); と2種類の呼び出し方法をこころみました。 ファイルのフルパスは IntPtr fnamePtr = Marshal.StringToHGlobalAnsi(string型ファイルフルパス); としております。 1の場合は int[] resX = new int[100]; int[] resY = new int[100]; fixed(int* x= resX) fixed(int* x= resY) として呼び出そうとすると : エラー CS1657: '固定変数' であるため、'x' を ref または out 引数として渡せません となり失敗してしまいます。 2 で試みた場合 int size = sizeof(int)*100; IntPtr x = Marshal.AllocHGlobal(size); IntPtr y = Marshal.AllocHGlobal(size); と引き渡したところ ビルドは通りますが 実行時に System.AccessViolationException' のハンドルされていない例外が 発生しました。 追加情報: 保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。 となってしまいます。 どのようにすれば思惑通りの結果を得られますでしょうか。

  • 初歩的なことなのですが(メソッドについて)

    こんにちわ。 最近、javaの勉強を始めました。 今、掛け算を求めるメソッドと、そのメソッド結果を表示するためのメソッドをつくっています。 掛け算を求める方は class Rensyu { public int Kakezan (int atai1,int atai2,int atai3) { int seki = atai1 * atai2 * atai3; return seki;          } と作ったのですが、 この後ろに      public void Show(){ System.out.println(); } という形でKakezanメソッドの値を出力するメソッドを加えたいのですが、書き方がわかりません。説明がわかりづらいと思いますが、よろしければ、回答(ソースの書き方)をお願いします。

    • ベストアンサー
    • Java
  • 大学数学

    √26の値を0.000001未満の許容誤差の範囲で求めよ ヒント テイラーの定理 a=25 h=1

  • クラスやメソッドが理解できません

    今javaを勉強中なのですが、クラスやメソッドで生きず待ってしまいました。 メソッドの定義は 戻り値の型 メソッド名(引数リスト) {  文;  ・・・ return 式;  } ですが、メソッドから返されえる値を戻り値といますよね?呼び出し元に値を返すってどういうことなのでしょうか? int getNum() { System.out.println("調べました") return num; } たとえば、上記のようなものですが。もしも、このメソッドを呼び出すと、”戻り値”が戻ってくるわけですが、これはgetNumという変数のなかに計算式が入っている?という考え方でいいのでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • Java
  • 多次元配列について質問

    以下はあるJavaの参考書の問題文とその解答ソースコードです。 疑問点があるので、質問に答えてくだされば幸いです! 問題文:じゃんけんゲームを作成します。ジャンケンは次の図のように数値で表します。勝敗表も示します。(『次の図』と『勝敗表』は、Upした画像を参考にしてください。) 次のメソッドを持つクラスを作成します。 A.rand3メソッド ・乱数を使って1,2,3のどれかの値を作成して返す(グー、チョキ、パーにあたる) B.jankenメソッド ・人が入力したじゃんけんの種類(1,2,3のどれか)を仮引数nに受け取り、次の処理を行う。 1:rand3メソッドでコンピューター側のじゃんけんの値を変数mに得る 2:mとnを比較して次のどれかの値を返す ・人が勝ちなら 1・コンピューターが勝ちなら2 ・引き分けなら0 C. isJankenメソッド ・int の値を仮引数nに受け取り、nが1,2,3のどれかであるときtrue、そうでなければfalseを返す D.mainメソッド ・キーボードをタイプして1,2,3のどれかの値を入力し、それを実引数としてjankenメソッドを呼び出し、勝敗を表示する。   1:isJankenメソッドを使って、人が入力した数値が1,2,3のどれかであるかどうか検査し、もしも1,2,3以外なら「入力した値が正しくない」と表示して直ちに処理を終了します。 2:入力値が正しければ、jankenメソッドを実行する。   3:結果は、「勝ち」「負け」「引き分け」のどれかの文字列を表示する。 ------解答ソースコード------- package 第16章; import lib.Input; public class 通過テスト2 { public static void main(String[]arg){ int n=Input.getInt(); if(isJanken(n)){ System.out.print(n+":"); switch(janken(n)){ case 0: System.out.println("引き分け"); break; case 1: System.out.println("勝ち"); break; case 2: System.out.println("負け"); break; } }else{ System.out.println("入力した値が正しくない"); } } public static int rand3(){ int com=(int)(Math.random()*3+1); return com; } public static boolean isJanken(int n){ if(n==1||n==2||n==3){ return true; }else{ return false; } } // public static int janken(int n){ int[][]tb1={ {9,9,9,9}, {9,0,1,2}, {9,2,0,1}, {9,1,2,0} }; int m=rand3(); System.out.println(m+" "); return tb1[n][m]; } } -----解答ソースコード終----------- 質問:Jankenメソッドの2次元配列について、その意味が全然わかりません。Upした画像の「勝敗表」を表してるのはわかるのですが、その勝敗表とどのような対応関係にあるのかわかりません。 具体的な疑問点は以下の2点です  1点目:何故「9」という数字があるのかわかりません。  2点目:何故2次元目の要素数が「4つ」あるのかわかりません。1次元目の要素数も4つありますが、それもわかりません。 ごめんなさい、、ほんとに何もかもわからない。手取り足取り教えていただきたいです。。

    • ベストアンサー
    • Java
  • EPSILONとMIN_VALUEの違い

    Number.EPSILON とNumber.MIN_VALUEは、何が違うのでしょうか。 以下のURLの「同等なことをテストする」では、EPSILONと数値の差を比較し、浮動小数点の計算誤差を確認していますが、EPSILONをMIN_VALUEにするとequalはfalseになります。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON MIN_VALUEとEPCILONとで値が違うので、結果も異なってくるのだとは思うのですが、そもそもどのように使い分ければよいのかが理解できませんでした。 MIN_VALUEは「JavaScriptで表せる0に最も近い最小の値」、EPCILONは、「1より大きい最小の値の差」で、結局、どちらも表現できる最小の値に見えるのですが、何が違うのでしょうか。

  • t検定の有意水準

    標本誤差についてわかりやすく説明する場合、例えば信頼区間95%の場合、 「同じ条件で調査を100回やったとしたら、 95回は+-〇〇%の誤差の範囲に収まります」 等と説明します。 ではt検定により、2つの比率の差を5%の有意水準で計算した場合には、 その結果はどのように説明するのでしょうか。 「2つの比率に有意な差がない、又は有意な差が見られる」 と言う部分 はさておき、 何が5%なんでしょうか。 元々100回のうち5回は誤差の範囲に収まらない可能性のある 2つのデータなのだから、 その2つを比較する時点で誤差の範囲に 収まらない可能性が5%ではないのではないか  と思うと訳が分からなくなりました。 当方知識が乏しいので、できるだけやさしくお願いします。

  • アドミタンスの周波数特性(理論値との比較)

    物理の実験でアドミタンスの周波数特性をRC直列回路について調べました。 片対数表を用いてアドミタンスの振幅と位相差を求めました。理論値はそれぞれ wc/√1+(wcR)^2 tan^(-1)1/wcR を用いて計算して理論値を出しました。この値と実験のデータのグラフを比較するとグラフの形は似ているのですが値はあまり一致していないです。wの範囲は10Hzから10000Hz,C=1μF,R=1kΩで実験しました。 位相差についてはオシロスコープに表示されるリサージュ図形により求めました。 この誤差の原因は何なんでしょうか?目盛りを読み取るのときの誤差のような小さな誤差ではないと思います。またオシロスコープなどの抵抗など考えなければならないのでしょうか?ご回答よろしくお願いします。