2011-08-27 19 views
11

Cの本では、配列num[7]の場合、numという語は&num[0]に相当します。このコンセプトは私のためにうまくいきましたが、私がこのプログラムを書いたときに私は再び混乱しました。`num num [7]`を指定すると、 `num`、`&num [0] `、`&num`はどのように違いますか?

#include<stdio.h> 
#include<conio.h> 
int main() 
{ 
    int num[]={21,22,23,24,25,26,27}; 
    int *x,*y,*z; 
    x=&num; 
    y=num; 
    z=&num[0]; 
    printf("%d %d %d\n",sizeof(x),sizeof(y),sizeof(z)); 
    printf("%d %d %d\n",sizeof(&num),sizeof(num),sizeof(&num[0])); 
    printf("%d %d %d",*(&num),*(num),*(&num[0])); 
    getch(); 
    return 0; 
} 

出力は次のようになります。

 4 4 4 
     4 28 4 
     2293536 21 21 

num&num[0]と同じであれば、その大きさに差がある理由は?そして、この第3の種類の用語は何ですか&num?私はそれがゴミ値を示していることを知っていますが、このタイプの用語は意味をなさないでしょうか? z=&num[0]私はすでに理解しています。コンパイラは、割り当てx=&numの警告を表示しますが、y=num;の場合、コンパイラには問題はありません。 numのサイズが28の場合、なぜタイプ変換なしで整数ポインタyに割り当てられましたか?

その後、私は2次元配列にこの方法を試してみました:

#include<stdio.h> 
#include<conio.h> 
int main() 
{ 
    int s[4][2]={{1234,56},{1235,57},{1236,58},{1237,59}}; 
    int i 
    printf ("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s), 
     sizeof(s[0][0]),sizeof(&s)); 
    getch(); 
    return 0; 
} 

今、出力はここ

8 4 32 4 4 

sizeof(s[i])では8です。 s[i]は1次元配列であり、2つの要素を持っているので大丈夫です。しかし、私は、用語&s[i]&sが何を意味するのか全く分かりません。そして私はss[0][0]と同じではないことを再び見ることができます。私はすべてのプログラムを実行するためにDev C++ 4.9.9.2バージョンを使用しました。私はこれらの3つのタイプの用語で明確になりたい。

+2

この問題に専念セクション全体持つCよくあるご質問お読み:初心者のためのhttp://c-faq.com/aryptr/index.html – AnT

+0

@good質問!バディ – niko

答えて

2

うわー、それが1回で多くの質問です:P

まず、私はあなたに、この出力を説明しようとするでしょう:

4 4 4 
    4 28 4 
    2293536 21 21 

sizeof()は、cで単項演算子です。コードがコンパイルされると、実行時ではなく整数に置き換えられます。したがって、コンパイラはあなたのprintfsを文字どおりに変更します:

printf("%d %d %d\n", 4, 4, 4); 
printf("%d %d %d\n", 4, 28, 4); 
printf("%d %d %d",*(&num),*(num),*(&num[0])); 

コンパイルの非常に初期段階です。

コンパイラは、sizeof(num)を書くときに、配列全体のサイズを与えるのに十分親切です。これは、sizeofが配列で動作するように定義されている方法です。他のすべての要素はsizeof(& num)を除いて(int **)のサイズを与えます(int **はint *と同じサイズです)。

  • & numが使用しているアレイ
  • NUMへのポインタのメモリ位置であり、& NUM [0]は、あなたの第二のために使用しているアレイ

に最初INTのメモリ・ロケーションであります質問;

printf("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s),sizeof(s[0][0]),sizeof(&s)); 

 

sizeof(s[i]) - size of an array (int[2]) == 8 
sizeof(&s[i]) - size of a pointer to an int array sizeof(int **) == 4 
sizeof(s) - size of a 2D array containing 8 ints == sizeof(int[8]) == 32 
sizeof(s[0][0]) - size of an int === 4 
sizeof(&s) - size of a pointer to an array == 4 
3

あなたの矛盾は有効です。 ではないnum&num[0]に相当する場合。それは単に偽です。配列はポインタとは別の型であり、numは、ではなく、int[7]のオブジェクトを参照します。そのため、サイズが異なるのは、たとえば1つが連続した7つの整数のコレクションであるためです。

numint*に変換され、値が&num[0]であることに注意してください。もちろん、変換は等価と同じではありません。配列とポインタの間の混乱は、人がポインタがポインタであるという誤った言い方を繰り返し続けるため、奇妙にも目立ちます。彼らはそうではありません。

3

numは& NUMと同じであれば今、私の質問は、[0]、そこのサイズの 違いがありますされてなぜですか?

numは配列である。 sizeofは、実際の配列を渡すと配列全体の記憶領域サイズがわかりますが、配列内の要素へのポインタのサイズだけを渡すと、配列全体の記憶領域サイズがわかりますそのような要素のアドレス。これは、配列名が関数呼び出しのポインタに劣化するため、混乱を招く可能性があります。

だから、答えはnum&num[0]と同一ではないということである - 後者を除去し、アレイの合計サイズに関する情報と、numの最初のエレメントのアドレスです。これらの2つの事柄は、実際の関数を呼び出すなどの多くの状況で交換可能ですが、sizeof(関数ではなく、コンパイラによって処理される特別なキーワード)を呼び出すときではありません。

6

ここに良い質問があります。うまくいけば、私たちは皆あなたのためにこれらの問題を説明することができます。

  • numその後

    int num[]={21,22,23,24,25,26,27}; 
    

    を考えると

    は、メモリの場所に割り当てられている整数の宣言された配列であるため、int[]を入力しています。 ではなく、のタイプがint*であることに注意してください。これは、それをmallocした場合です。

  • sizeof(num)は、numが7つの整数の配列なので、28です。これはマシン上では4バイトのサイズです。整数は8バイトの場合は56、2バイトの場合は14ですが、整数あたり4バイトが最も一般的です。
  • &num[0]は、タイプint*のポインタであり、の値numの最初の要素のアドレスです。
  • xとフレンドのサイズはポインタとして宣言されているため4です。これはマシン上でCコンパイラのポインタが4バイトで割り当てられているためです。

パラメータとして渡されたような特定のコンテキストで配列が使用される場合、配列はint*に変換されます。だからあなたは*numと言うことができ、21を得ることができます。難しいですが、それはそうです。そのため、普通はnum&num[0]を交換できますが、気づいたようにsizeofの値が異なるため、実際に区別しておく必要があります。

変換はなぜy = numが理にかなっています。 yのタイプはint*で、Cではint[]からint*への自動変換が行われます。 &numの型が「int配列へのポインタ」であるため、x = &numを実行することはできません。 int*(intへのポインタ)に割り当てることはできません。以下の場合

INT S [4] [2] = {{1234,56}、{1235,57}、{1236,58}、{1237,59}}。 (s[i]はint配列であるため)

我々はint[][]としてsの種類、pointer to int[][]として&sの種類及びint[]へのポインタとして&s[i]のタイプを持っています。 Cがあなたにポインターに配列を代入/引き渡すことができる方法のために、あなたの最初の例と同じ種類のゲームをプレイすることができます。

あなたが同じメモリ位置にそのs&s[0]&s[0][0]すべてのポイントをわかります、しかし、あなたが気づいたとして、sizeof値が異なることになります。

+0

@pst、右、私はあまりにも多くの仮定をしました。これには7つの4バイト整数が含まれています。はい、OPは異なるサイズのintを持つマシン上にある可能性があります。 –

+0

より良い、そして+1:p –

関連する問題