
No.3ベストアンサー
- 回答日時:
他の回答は読みました。
そのうえで。unsafeモードにした時点で、そこはCの世界です。
ポインタアクセスと配列アクセスについても同様で、
ただ1つの要素にアクセスするだけなら処理速度に差はないでしょうが、
forループで回し続けたりすれば、indexerを見るよりもポインタアクセスのほうが速いでしょう。
また、indexerの値チェックはされません(これもCと同じ)。
>unsafeモードにした時点で、そこはCの世界です。
明快な回答、ありがとうございます。
となると、
>forループで回し続けたりすれば、indexerを見るよりもポインタアクセスのほうが速いでしょう。
が理解できなくなりました。
byte* pp = (byte*)Buffer;
byte[] buf = (byte []) Buffer;
for(int i=0; i<n; i++) {
pp[i]=i;
}
for(int i=0; i<n; i++) {
buf[i]=i;
}
は全く同じコードに翻訳されると思うのですが・・・
No.4
- 回答日時:
>for(int i=0; i<n; i++) {
> pp[i]=i;
>}
>for(int i=0; i<n; i++) {
> buf[i]=i;
>}
>は全く同じコードに翻訳されると思うのですが・・・
そりゃ同じでしょう。
処理速度の違いは定義じゃなくアクセスの仕方によります。
逆に
for(int i=0; i<n; i++, pp++) {
*pp=i;
}
for(int i=0; i<n; i++, buf++) {
*buf=i;
}
も、pp, bufの定義に関係なく速度は同じでしょう。
繰り返しますが、処理速度の違いは定義じゃなくアクセスの仕方によります。
>繰り返しますが、処理速度の違いは定義じゃなくアクセスの仕方によります。
つまり
bufとppでは同じ
アクセスの違いとしてbuf[i]と*buf では、*bufのほうが速い(場合がある)
ということですね。
今回の
>pp[i], buf[i] で同じデータにアクセスできると思うのですが、違いはどこにありますか?
>処理速度的に違いはあるのでしょうか?
の直接の回答ではなく、おまけ情報ですね。ちょっと混乱しましたが、回答の意味、理解できました。
ありがとうございました。
No.2
- 回答日時:
>エッ? どちらも参照も代入もできますけど?
恐らくポインタの意味自体を理解されていませんね。
ポインタというのはそのデータの格納されているメモリのアドレスを引き渡す機能です。
一方配列というのは言語による違いはありますがC#の場合、配列の長さ、データを格納する領域、及び、チェックロジックから成立しています。
ポインタはその場所を参照に必要なデータをもっているのに対し、配列はデータそのものが代入されています。
ポインタの場合は先頭のアドレスのみを受け渡せばよい為、パフォーマンス面では有利です。
一方でポインタの場合、予約された領域外にもアクセスできてしまいバグの原因になるばかりか、最悪の場合突然OSにプロセスKillされる事になります。
C#の場合ref(参照渡し)や、readonly ref(参照読み取り専用渡し)と言う事が可能です。
refを利用する事で、ポインタの様なパフォーマンスの良さと配列の予約外の領域へのアクセスを未然に防げるという両方が可能になります。
readonly refを利用する事で、refの利点に加えて、値渡しの様に予期せぬ元データの書き換え阻止ができます。
C#2.0まではパフォーマンスの都合でどうしてもポインタを使わざるおえないところがありました。
ですが今のC#では適切な参照渡しを行えばポインタと同程度に高速で、ポインタを使った場合よりも安全なソースコードを記述することができます。
代替機能の完成度が高く、ポインタを使っても碌な事になりません。
unsafeのキーワードが出てきた時点で何かおかしな事をしようとしていると思ってください。
回答ありがとうございます
>恐らくポインタの意味自体を理解されていませんね。
説明いただいた内容はすべて承知しています。その上での質問です。
>unsafeのキーワードが出てきた時点で何かおかしな事をしようとしていると思ってください。
「添え字チェックを省略する」というある意味「おかしな事」を実現しようとするプログラムですが、それは作者が意図したことです。
繰り返しになりますが質問では、
unsafeモードで配列とポインタの違い
です。
配列の場合、unsafeモードにしても、添え字チェックが行われるということでしょうか?
作者の意図とおり、添え字チェックが行われないのであれば、ポインタとの違いはどこにあるのでしょうか?
C言語のように、ポインタと配列は同一と思ってよいのでしょうか?
という質問です。
よろしくお願いします。
<おまけ>
以下のことを理解したうえで作成されたプログラムです。
for(int i = 0; i < a.Length; i++)
{
a[i] = i; // これは添え字チェックされない
}
for(int i = 0; i < n; i++)
{
a[i] = i; // これは添え字チェックされる
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
ExcelVBAでのkernel32(64bit)
-
ハンドルはポインタか
-
init関数の意味
-
C言語のポインタに直接アドレス...
-
LPSTR型の初期化について
-
fopne で失敗する原因
-
C言語についてです。 独学で進...
-
構造体のアドレス渡し
-
ファイルポインタのヘッダーフ...
-
どうしてエラーになるかわかり...
-
戻り値で構造体を返すことは可...
-
Run-Time Check Failure #3とい...
-
ダイアログから、ドキュメント...
-
無効なポインタ操作のエラー
-
C#,C++/CLI,MFCにおけるデータ...
-
別のDLLのダイアログを・・・
-
関数内、ファイルのstatic変数
-
ReadFileの読み込みエラーについて
-
VB.NET DLL【API関数(コールバ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
セグメントエラー
-
Run-Time Check Failure #3とい...
-
ExcelVBAでのkernel32(64bit)
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
参照型で受け取った引数をポイ...
-
トリプルポインタが必須!とな...
-
ハンドルはポインタか
-
LPSTR型の初期化について
-
ポインターの使用法や利点
-
ポインタについて
-
c言語で任意のファイルから読み...
-
基本アルゴリズムの『返す』の...
-
コンストラクタでnewを失敗した...
-
ハンドル、アドレス、ポインタ...
-
アプリを32bitから64bit移行
-
デバイスハンドルとは?
-
NULLとブランクの違い
おすすめ情報