2016-03-30 12 views
0

私はint型の配列の値を出力したいとしましょう。
割り当てられた配列を経由する

int *num = malloc(5 * sizeof(int)); 

どうすればよいですか?私が置いたすべての価値観を辿った後、私は明らかにそれを止めたいと思うでしょう。そこには5つの価値があります。私は私が与えた例で何が起こるかknwoたい

for (int i=0;i<5;i++) 

:私のような何かを見ていないよ

注意。

while(*num) { 
    printf("%d", *num); 
    num++; 
} 

OR

while(num != NULL) { 
     printf("%d", *num); 
     num++; 
    } 
+1

5つの値または4つの値を保存しようとしていますか?なぜならば、配列の終わりを示すためにセンチネルを使用する場合は、センチネルのスペースを割り当てる必要があるからです。また、センチネルとして使うには "違法な"価値が必要です。 –

+0

** '5' **回繰り返すループを書くのに問題がありますか? – Olaf

+1

厳密には、最初の要素へのポインタを使用して配列のように扱うメモリを割り当てます。 'int'は配列ではなくポインタです。あなたは 'malloc'から得たものと同じ**アドレスを使って、この割り当てられたブロックを後で解放しなければなりません。だからあなたは**このアドレスを失ってはいけません!別のポインタを使用して繰り返します。 – Olaf

答えて

1

Cでの配列は、その長さを有していません。配列と一緒に長さを渡す必要があります。

最も簡単な方法は、変数である:終わるNUL

int i; 
for (i = 0; i < 5; ++i) 
    printf("%d ", num[i]); 

トリックが正常に文字列だけのために使用され、文字列の最後には、NUL CHAR('\0')が付いています。もちろん、自分で配列を作成して消費しているのであれば、同様の規則を作ることはできません。あなたが方法であなたが次に

int *num = malloc(5 * sizeof(int)); 

終わりを知るための唯一の方法を示しているに割り当てられた配列を使用している場合は

int *num = malloc(5 * sizeof(int)); 
num[4] = -1; 
int *p; 
for (p = num; *p != -1; ++p) 
    printf("%d ", *p); 
+0

私は知っています。私はそれをするつもりはない。 – SomeoneWithAQuestion

+0

@SomeoneWithAQuestion:あなたが望むのは、ポインタだけで配列の長さを知ることであれば、標準Cではそのような方法はありません。 – rodrigo

1

:あなたは、例えば、-1を持つ配列の終わりをマークすることができます配列の割り当てに使用するサイズを使用することです。同様

int i = 0; 
while(i < 5) // 5 here is the size used wile allocating 
{ 
    printf("%d", num[i]); 
    i++; 
} 
+0

..またはさらに単純です: 'num [i]'。初心者にとってなぜそれは難しいのですか? –

+0

@PaulOgilvie、True。ありがとう。 :) – Haris

-1
while(*num) { 
    printf("%d", *num); 
    num++; 
} 

*numがゼロになるまでまあ、これは継続します。有効なエントリにゼロが含まれず、最後のエントリ(または最初の無効なエントリ)をゼロに設定していれば、これは問題なく動作します。これはセンチネル値と呼ばれます。

while(num != NULL) { 
     printf("%d", *num); 
     num++; 
    } 

これは機能しません。 numをインクリメントすると、それはNULLになりません。それはなぜだろう?

特定の値の値を出力する場合は、基本的に2つの選択肢があります。出力コードに出力する値の数を渡すことができ、その数の値を出力するときにカウントするだけです。または、 "センチネル"値を使用して最後をマークすることもできます。ゼロが有効な値でない場合は、印刷したいと思うでしょう。ゼロをセンチネルとして使うことができます。センチネルにスペースを割り当てることを忘れないでください。

+0

この解決策を使うと、 'malloc'で割り当てられたメモリの開始アドレスが失われます。 –

+0

なので、for(struct temp * current = array; current!= NULL; current ++)はうまくいかないでしょうか? (現在!= NULLは私が対処しているものです) – SomeoneWithAQuestion

+0

@PaulOgilvie申し訳ありませんが、どのような解決策ですか? –

0

配列の長さをどこかに保存する必要があります。(その値が実際のコンテンツに対して有効ではありませんが)いくつかの他の戦略は、配列の末尾にターミネータまたはセンチネル価値を置いています

その最初として
int *num = calloc(6, sizeof(int)); 
num[5] = -1; 
int i; 
for (i = 0; num[i] != -1; i++) { 
    //... 
} 

または配列の長さを埋め込みます要素:

int *num = malloc(6 * sizeof(int)); 
int len = num[0]; 
int i; 
for (i = 1; i < len; i++) { 
    // ... 
} 

(注、Flexible arraysが第二の例を表現する良い方法である)

の長さを格納する方法上記表示両方この目的のために余分な要素を利用しています。

+1

配列には、同じ意味のデータのみが含まれている必要があります。サイズの最初の要素を使うのは悪い考えです。代わりに_flexible配列member_を持つ 'struct'を使用しなければなりません。 – Olaf

+0

「アレイ」が物理的にメンバー以上のものをどのように含んでいるのかを実証することが多かったし、CでOPがかなり新しいと思われるので、フレキシブルな配列メンバーを混乱させることになりました。実際のフレキシブルな配列メンバは、C99かC89のどちらが使われるかに応じて '[0]'または '[1]'のどちらでもかまいません... –

+0

FAMはC標準の一部です(しかしC11はオプションです) 。セマンティクスはよく定義されています(サイズはなく、 'struct'は1要素を追加しません)。gccのゼロ長配列や上限を超えてアクセスする単一要素配列のような独自の拡張は、実際UBと考えるかもしれません。どちらもFAMであり、もう使用しないでください(gccは標準モードでFAMをサポートしています)。 – Olaf

関連する問題