arrays - 如何修复 C 中的分段错误
问题描述
我正在编写一个程序来使用递归查找最大数量的数组。返回分段错误。我对此做了一些研究。事实证明,访问超出给定长度的数组是有问题的。我不知道如何解决这个错误。更具体地说,我不知道如何设置允许数组具有特定用户提供长度的参数。我也不知道如何表达它的论点。这是我的代码:
#include <stdio.h>
int findLargest(int, int[]);
int main() {
int n;
printf("Input the number of elements to be stored in the array: ");
scanf("%d", &n);
int arr[n];
printf("Input %d elements in the array: \n", n);
for (int i = 0; i < n; ++i) {
printf("element - %d: ", i);
scanf("%d", &arr[i]);
}
printf("Largest element of an array is: %d", findLargest(n, arr));
}
int findLargest(int n, int arr[]) {
static int i = 0;
int x = -9999999;
if (i < n) {
if (arr[i] > x)
x = arr[i];
printf("%d\n", i);
++i;
}
findLargest(n, arr);
}
解决方案
你的函数定义
int findLargest(int n, int arr[]) {
static int i = 0;
int x = -9999999;
if (i < n) {
if (arr[i] > x)
x = arr[i];
printf("%d\n", i);
++i;
}
findLargest(n, arr);
}
没有意义。
例如,用户可以为第一个参数传递一个非正数。其次,数组可以包含小于幻数的值-9999999
。
本次作业
x = arr[i];
没有效果,因为在函数的每次递归调用中,变量x
都由值重新初始化-9999999
int x = -9999999;
也因为静态变量i
只初始化一次
static int i = 0;
然后再次调用该函数会导致未定义的行为,因为变量未重置。
更重要的是,该函数没有返回语句。
该函数应声明为
size_t findLargest( const int a[], size_t n );
即第一个参数应具有限定符const
并表示在函数内未更改的传递数组。第二个参数应具有类型size_t
。
该函数返回传递数组的最大元素的索引。
这是函数定义。
size_t findLargest( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t n1 = 1 + findLargest( a + 1, n - 1 );
return a[0] < a[n1] ? n1 : 0;
}
}
为了减少函数的递归调用次数,您可以将传递的数组分成两部分并为每一部分调用函数。
这是一个演示程序。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
size_t findLargest( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t n1 = findLargest( a, n / 2 );
size_t n2 = n / 2 + findLargest( a + n / 2, n - n / 2 );
return a[n1] < a[n2] ? n2 : n1;
}
}
int main(void)
{
srand( ( unsigned int )time( NULL ) );
while ( 1 )
{
printf( "Input the number of elements to be stored in the array (0 - exit): " );
size_t n;
if ( scanf( "%zu", &n ) != 1 || n == 0 ) break;
int a[n];
for ( size_t i = 0; i < n; i++ ) a[i] = rand() % ( 2 * n );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
printf( "The largest element of the array is: %d\n", a[findLargest( a, n )] );
}
return 0;
}
程序输出可能看起来像
Input the number of elements to be stored in the array (0 - exit): 10
5 14 0 4 19 8 2 1 11 6
The largest element of the array is: 19
Input the number of elements to be stored in the array (0 - exit): 9
9 3 12 15 4 13 17 13 7
The largest element of the array is: 17
Input the number of elements to be stored in the array (0 - exit): 8
2 13 9 11 12 8 14 3
The largest element of the array is: 14
Input the number of elements to be stored in the array (0 - exit): 7
13 5 0 2 8 6 1
The largest element of the array is: 13
Input the number of elements to be stored in the array (0 - exit): 6
10 7 11 5 1 7
The largest element of the array is: 11
Input the number of elements to be stored in the array (0 - exit): 5
9 0 4 1 1
The largest element of the array is: 9
Input the number of elements to be stored in the array (0 - exit): 4
2 0 6 5
The largest element of the array is: 6
Input the number of elements to be stored in the array (0 - exit): 3
1 1 2
The largest element of the array is: 2
Input the number of elements to be stored in the array (0 - exit): 2
1 0
The largest element of the array is: 1
Input the number of elements to be stored in the array (0 - exit): 1
0
The largest element of the array is: 0
Input the number of elements to be stored in the array (0 - exit): 0
下面显示了可以为任何类型的数组调用的这种通用递归函数的外观
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
size_t findLargest( const void *base,
size_t nmemb,
size_t size,
int cmp( const void *, const void * ) )
{
if ( nmemb < 2 )
{
return 0;
}
else
{
size_t nmemb1 = findLargest( base, nmemb / 2, size, cmp );
size_t nmemb2 = nmemb / 2 +
findLargest( ( const char * )base + nmemb / 2 * size,
nmemb - nmemb / 2, size, cmp );
return cmp( ( const char * )base + nmemb1 * size,
( const char * )base + nmemb2 * size ) < 0
? nmemb2 : nmemb1;
}
}
int cmp( const void *a, const void *b )
{
int left = *( const int * )a;
int right = *( const int * )b;
return ( right < left ) - ( left < right );
}
int main(void)
{
srand( ( unsigned int )time( NULL ) );
while ( 1 )
{
printf( "Input the number of elements to be stored in the array (0 - exit): " );
size_t n;
if ( scanf( "%zu", &n ) != 1 || n == 0 ) break;
int a[n];
for ( size_t i = 0; i < n; i++ ) a[i] = rand() % ( 2 * n );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
size_t i = findLargest( a, n, sizeof( *a ), cmp );
printf( "The largest element of the array is: %d\n", a[i] );
}
return 0;
}
同样,程序输出可能是
Input the number of elements to be stored in the array (0 - exit): 10
6 2 5 5 3 1 4 1 10 9
The largest element of the array is: 10
Input the number of elements to be stored in the array (0 - exit): 9
9 7 1 11 5 16 8 2 8
The largest element of the array is: 16
Input the number of elements to be stored in the array (0 - exit): 8
4 8 1 0 10 15 9 1
The largest element of the array is: 15
Input the number of elements to be stored in the array (0 - exit): 7
13 0 4 9 3 4 4
The largest element of the array is: 13
Input the number of elements to be stored in the array (0 - exit): 6
10 1 0 6 2 2
The largest element of the array is: 10
Input the number of elements to be stored in the array (0 - exit): 5
5 4 3 4 5
The largest element of the array is: 5
Input the number of elements to be stored in the array 4
(0 - exit): 3 4 3 5
The largest element of the array is: 5
Input the number of elements to be stored in the array (0 - exit): 3
0 5 5
The largest element of the array is: 5
Input the number of elements to be stored in the array (0 - exit): 2
0 0
The largest element of the array is: 0
Input the number of elements to be stored in the array (0 - exit): 1
0
The largest element of the array is: 0
Input the number of elements to be stored in the array (0 - exit): 0
推荐阅读
- discord.js - client.commands.get('kickembed').execute //无法读取属性'execute'未定义//
- php - 使用 PHP 和 Mysql、Laravel 自定义消息/模板内容
- laravel - 实例化模型与查找模型之间的区别
- r - Rshiny:在数据帧比较期间选择“两者”选项时如何显示标题?
- php - 如果未找到连接,如何使用 DB::table 和 orderBy 可连接属性集 0 连接
- c# - Unity 中的 Google 持久云锚点:错误缺少 API 密钥
- c++ - 将指针作为函数参数传递与非类型模板参数之间的区别
- c - 将整数重新加载到数组中
- python - Dask 从单个 hdf5 文件加载多个“表”
- coap - 通过 lwm2m 发送不同长度的文件