2016-06-24 15 views
2

以下は、アルゴリズム&データ構造の基礎を学んでいるwww.tutorialspoint.comのコードです。このチュートリアルコードでは、ex。配列への挿入操作cのコードの理解/明確化のロジック

#include <stdio.h> 
    main() { 
     int LA[] = {1,3,5,7,8}; 
     int item = 10, k = 3, n = 5; 
     int i = 0, j = n; 

     printf("The original array elements are :\n"); 

     for(i = 0; i<n; i++) { 
      printf("LA[%d] = %d \n", i, LA[i]); 
     } 

     n = n + 1; 

     while(j >= k){ 
      LA[j+1] = LA[j]; 
      j = j - 1; 
     } 

     LA[k] = item; 

     printf("The array elements after insertion :\n"); 

     for(i = 0; i<n; i++) { 
      printf("LA[%d] = %d \n", i, LA[i]); 
     } 
    } 

私は、配列のインデックスとしてkの与えられた値で新しい項目を追加するというコードを理解しています。そして、コンパイル時にエラーなしで正常に動作します。&が実行されます。私に混乱を招くのはwhileループの行LA[j+1] = LA[j]の論理です。

私の理解では、配列のサイズを宣言する必要があります。しかし、ex。コードint LA[] = {1,3,5,7,8};ブラケット[]が空です。だから私はそれが固定サイズであるか、またはより多くの要素が配列に追加できるかどうかわからない。

nの値は5(配列の長さ)です。配列宣言の要素数は5であり、配列のインデックスは0〜4です。

LA[j + 1]LA[6]です。したがって、LA[j + 1]はです。配列は0から4までの5つの要素しか持っていません。したがって、配列にさらに要素を追加できると仮定しても、LA[j]の値はどのようにしてLA[j + 1]になりますか? LA [6] = LA [5]と言っていますが、最後のインデックスが4であるため、インデックス5には何もありません。

Googleで検索しようとしましたが、コードまたはコードの一部。コードで検索するのは役に立たなかった。

ご理解ください。ありがとうございました。

+2

と同等です。いくつかのコードを理解していないときは、デバッガを使用してそのステップを実行することができます。ロジックをもっと明確にするのに役立ちます。 –

+0

www.tutorialspoint.comはこれを実際に良いコードの例として提供していますか、それともあなたが修正するはずの非常に悪いコードの例ですか?このコードが良いコードの例として提供されているなら、私は 'c'を学ぶ別の場所を見つけることを提案します。 – 4386427

+0

私はアルゴリズムとデータ構造を学んでいます。それらによって提供されるコードが実行され、配列にもう1つの要素が追加されます。私はコードをコンパイルして実行しました。私はまだCコードをデバッグする方法を知らない。 googleとしよう –

答えて

3
int LA[] = {1,3,5,7,8}; 

と等価である:

int LA[5] = {1,3,5,7,8}; 

空のブラケットだけ自動配列のサイズなどの要素の数を設定するようにコンパイラーに指示します。


LそうL[5]が外にもある、あなたがうまく言ったように、インデックスが[0,4]であるので、5の大きさを有しているのではい、あなたが正しい、L[6]は、境界アクセスの外にあります境界!

このコードは間違っています。 未定義の動作


読む:Undefined, unspecified and implementation-defined behavior

+0

はい。それが私の混乱の理由です。しかし、コードが範囲外である場合、コードが正しい出力を与えるのはなぜですか?それは私が把握しようとしているものです。私の質問に答える時間を与えてくれてありがとう。 –

+0

@JVLJewels未定義の動作は、プログラムが期待どおりに動作するかどうかを示します。たとえば、今日のマシンで期待通りに動作するかもしれませんが、明日では動作しません。私のマシンでは、あなたが今日期待しているように動作しないかもしれません。私は自分の答えを編集しました。 – gsamaras

+0

ありがとうございます。私はコードを無視します。 –

1

まず第一に、それは非常に弱いプログラマによって書かれており、未定義の動作をしている非常に悪いコードです。

例えばLA

int LA[] = {1,3,5,7,8}; 

アレイは、5つの要素を有しています。

しかしこれらのループ

while(j >= k){ 
     LA[j+1] = LA[j]; 
     ^^^^^^^ 
     j = j - 1; 
    } 

for(i = 0; i<n; i++) { 
       ^^^^ n is already set to 6 
     printf("LA[%d] = %d \n", i, LA[i]); 
    } 

にアレイを越えてメモリへの書き込みしようとする試みがあります。 また、例えばn = 5のようないくつかの魔法の値があります。少なくとも

n = sizeof(LA)/sizeof(*LA) 

int main(void) 

プログラムは、例えば次のよう

#include <stdio.h> 

int main(void) 
{ 
    int a[] = { 1, 3, 5, 7, 9 }; 
    const size_t N = sizeof(a)/sizeof(*a); 

    while (1) 
    { 
     printf("The original array elements are:"); 
     for (size_t i = 0; i < N; i++) printf(" %d", a[i]); 
     printf("\n"); 

     printf("\nEnter a number to insert in the array (0 - exit): "); 
     int value; 

     if (scanf("%d", &value) != 1 || value == 0) break; 

     printf("Enter a position in the array where to insert: "); 
     size_t pos; 

     if (scanf("%zu", &pos) != 1) break; 

     size_t j = N; 

     if (pos < N) 
     { 
      while (--j != pos) a[j] = a[j-1]; 
      a[j] = value; 
     }   

     printf("\nThe array elements after insertion:"); 

     for (size_t i = 0; i < N; i++) printf(" %d", a[i]); 
     printf("\n\n"); 
    } 

    return 0; 
} 
を見ることができるように宣言されなければならないCのパラメータなしのメイン機能を考慮してください書くことがはるかに良いだろう

出力は

The original array elements are: 1 3 5 7 9 

Enter a number to insert in the array (0 - exit): 2 
Enter a position in the array where to insert: 1 

The array elements after insertion: 1 2 3 5 7 

The original array elements are: 1 2 3 5 7 

Enter a number to insert in the array (0 - exit): 6 
Enter a position in the array where to insert: 4 

The array elements after insertion: 1 2 3 5 6 

The original array elements are: 1 2 3 5 6 

Enter a number to insert in the array (0 - exit): 0 
のようになります3210

アルゴリズムの背後にあるロジックは単純です。 N要素の配列を持ち、posの値をNより小さい値に挿入する場合は、すべての要素を位置posから右に移動し、インデックスposの要素に新しい値を書き込む必要があります。元の配列の右端の要素は、前の要素によって上書きされるため、失われます。プログラムの出力はこの結果を示します。

あなたが正しく指摘したように、プログラムで使用されている5要素を持つ配列のインデックスの有効範囲は[0, 4]です。アレイは、この例のように、その寸法なしで宣言され

int a[] = { 1, 3, 5, 7, 9 }; 

次いでコンパイラは、初期化子の数から、その寸法を決定基。したがって、上記の宣言は

int a[5] = { 1, 3, 5, 7, 9 }; 
+0

私の質問に答える時間を与えていただきありがとうございます。答えは洞察力があり、Cプログラミングの知識も豊富です。あなたはなぜそれが実行され、それが外れているときに正しい出力を出すのか知っていますか? –

+0

@JVLJewels動作が定義されていないので、結果は正しい出力を含んでいる可能性があります:)これは、配列を超えてメモリを上書きしても出力できないことを意味します。 –