理解/澄清c中的代码逻辑

时间:2016-06-24 10:26:41

标签: c arrays algorithm initialization

以下是来自www.tutorialspoint.com的代码,我正在学习算法的基础知识。数据结构。本教程代码给出了一个例子。对数组的插入操作。

    #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]的逻辑。

我的理解是在c中你必须声明数组的大小。但在前。代码int LA[] = {1,3,5,7,8};括号[]为空。所以我不确定它是否可以将固定大小或更多元素添加到数组中。

现在j的值为n,即5(数组长度)。数组声明有5个元素,数组的索引是0到4。

(在while循环的第一次迭代中)LA[j + 1] LA[5 + 1]LA[6]。现在数组只有5个索引为0到4的元素。所以即使我假设可以将更多元素添加到数组之后,如何将LA[j]的值分配给LA[j + 1]。它说LA [6] = LA [5]但是索引5没有任何东西,因为最后一个索引是4。

我试图在谷歌搜索,但我不确定搜索除了代码或部分代码。用代码搜索并没有用。

请帮我理解。谢谢。

2 个答案:

答案 0 :(得分:3)

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

相当于:

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

空括号只是告诉编译器自动将元素数设置为数组的大小。

是的,你是对的,L[6]超出了界限,因为L的大小为5.所以,正如你所说,指数是[0,4],所以{ {1}}也不在界外!

这段代码错了!

详细了解未定义的行为Undefined, unspecified and implementation-defined behavior

答案 1 :(得分: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 )

考虑到C中没有参数的函数main应声明为

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;
}

它的输出可能看起来像

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

算法背后的逻辑很简单。如果您有一个包含N个元素的数组,并希望在pos小于N的位置插入一个值,那么您需要从位置pos开始向右移动所有元素,在索引为pos的元素中写入新值。原始数组中最右边的元素将丢失,因为它将被前面的元素覆盖。程序输出显示了这个结果。

正如您自己正确指出的那样,定义为在程序中使用5元素的数组的有效索引范围是[0, 4]

声明数组时没有其尺寸,如本例所示

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

然后编译器根据初始值设定项的数量确定其维度。因此,上述声明等同于

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