以下是来自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。
我试图在谷歌搜索,但我不确定搜索除了代码或部分代码。用代码搜索并没有用。
请帮我理解。谢谢。
答案 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 };