4

int array[] = {2,33,4,56,7,8}; を考えてみましょう。//ケースA

sizeof() が '\0' を char[] 配列の末尾としてチェックした場合! sizeof(array) は int 配列の終わりを見つけるためにセンチネル値として何をチェックしますか?したがって、A の場合の配列のサイズは?

sizeof (intArray) を実装した場合、センチネル値情報にアクセスする自由はありませんか?

4

3 に答える 3

14

sizeof何もチェックしません。関数呼び出しのように見えますが、実際には演算子であり、コンパイル時にコンパイラに認識されているサイズを挿入するコンパイラのトリックです。

が C 配列とどのようにsizeof相互作用するかを次に示します。配列を宣言するときは、そのサイズを定数として、実行時の整数式として、または配列に入れる特定の数の値を指定することによって暗黙的に指定します。

コンパイル時に要素数がわかっている場合、コンパイラはsizeof(array)実際の数に置き換えます。実行時まで要素数がわからない場合、コンパイラは実装固有の特別な格納場所を用意し、そこにサイズを格納します。実行中のプログラムは、スタックのクリーンアップのためにこの情報を必要とします。また、コンパイラは、この非表示の情報をsizeof実装のランタイム部分に認識させ、正しい値を返します。

于 2013-10-19T02:08:58.953 に答える
6

'\0'最後に(null-terminator)を持つ文字列リテラルと一般的な配列を混同していると思います。配列には、コンパイラが認識しているコンパイル時の長さがあります1。配列の長さと配列の基本型に基づいてサイズを与えるsizeof演算子です。

そのため、誰かがint a[] = {1, 2, 3};最後にヌル終了文字を追加することはなく、要素の数はコンパイラによって 3 と推定されます。sizeof(int)= 4のプラットフォームではsizeof(a)、12 になります。

混乱するのはchar b[] = "abc";、すべての文字列リテラルが'\0'自動的に配置されるため、要素数が 4 になるためです。つまり、自動的にnull で終了します。これをsizeofチェックするのはオペレーターではありません。4 * sizeof(char)重要なのはコンパイル時の配列の長さであり、これは 4 = 1 + C の文字列リテラルの性質により、sizeof文字列リテラルで明示的に指定された文字数です。

ただし、文字列リテラルではなく文字リテラルで初期化された文字配列には、この癖はありません。したがって、 ifchar c[] = {'a', 'b', 'c'};sizeof(c)文字列リテラルではなく、null 終了文字がないため、3 と NOT 4 を返します。ここでも sizeof 演算子 (関数ではない) は、コンパイル時にこの推定を行います2

最後に、これを行うために sizeof 演算子自体をどのように実装するかは、標準で義務付けられていない実装の詳細です。標準は、条件と結果について話します。実装によってそれらがどのように達成されるかは、標準の関心事ではありません (または、それを実装する開発者以外の誰にとっても)。


1 C99 では、配列の動的サイズを可能にする可変長配列 (VLA) が導入されました。

2 VLA の場合のみ、sizeof演算子とそのオペランドは実行時に評価されます

于 2013-10-19T02:16:18.123 に答える