11

K&R の配列演算に関するセクションを読んでいて、興味深いことに出会いました。コンテキストのために段落全体を投稿しましたが、主に太字の部分に焦点を当てています.

p と q が同じ配列のメンバーを指している場合、==、!=、<、>= などの関係は適切に機能します。たとえば、p が q より前の配列メンバーを指している場合、p < q は true です。任意のポインタは、ゼロと等しいか等しくないかを意味のある形で比較できます。ただし、同じ配列のメンバーを指していないポインターとの演算または比較の動作は未定義です。(例外が 1 つあります。配列の終わりの後の最初の要素のアドレスは、ポインター演算で使用できます。)

この例外の理由は何ですか? サイズが定義されている場合、配列の最後に余分なメモリが割り当てられていますか? もしそうなら、どのような目的で?配列をヌル文字で終わらせるのですか?

4

4 に答える 4

6

サイズが定義されている場合、配列の最後に余分なメモリが割り当てられていますか?

いいえ。あなたが引用した文脈は重要です。太字の例外は、ポインター演算 (および関係) に関するものです。同じ配列のメンバーを指していないポインター間のポインター関係を行うと、 udbが得られると言っています。ただし、これには例外が 1 つあります。それは、いずれかのポインターが配列の末尾を超えた最初の要素を指している場合です。

もしそうなら、どのような目的で?

nullそれは誤った前提を推定しているので答えてください。

配列をヌル文字で終わらせるのですか?

いいえ。

この理由は、配列の末尾との比較、つまり配列の&a[sizeof a]whenaとの比較が有効になるようにするためです。&a[sizeof a]は、配列の最後を過ぎた最初の要素であることに注意してください。pが の要素へのポインタであるaか、配列の末尾を超えた最初の要素である場合、pと比較できます&a[sizeof a]

C99 仕様のセクション 6.5.8.5から引用します。

2 つのポインターを比較すると、結果は、指しているオブジェクトのアドレス空間内の相対位置によって異なります。オブジェクト型または不完全型への 2 つのポインターが両方とも同じオブジェクトを指している場合、または両方が同じ配列オブジェクトの最後の要素の 1 つ後ろを指している場合、それらは等しく比較されます。指しているオブジェクトが同じ集約オブジェクトのメンバーである場合、後で宣言された構造体メンバーへのポインターは、構造体で以前に宣言されたメンバーへのポインターよりも大きく、添字値が大きい配列要素へのポインターは、同じ配列の要素へのポインターよりも大きくなります。より低い添字値で。式Pが配列オブジェクトの要素をQ指し、式が同じ配列オブジェクトの最後の要素を指している場合、ポインター式はQ + 1より大きいと比較されます。P. それ以外の場合、動作は未定義です。

于 2013-06-18T15:42:40.173 に答える
1

配列の最後に割り当てられる余分なメモリはありません。以下の「End」でマークされたアドレスをポインター演算で取得できると言っているだけです。Begin は、配列の最初の要素を指します。Endは、配列の最後を過ぎた最初の要素を指します。

-----------------
|   |   |   |   |
-----------------
^               ^
Begin           End
于 2013-06-18T15:42:20.977 に答える