一个数组越界的C++程序

简介:   学生给我发了私信,一个程序运行了好久,在OJ就是提交不了。  题目是:Description输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写三个函数; ①输入10个数;②进行处理;③输出10个数。Input10个整数Output整理后的十个数,每个数后跟一个空格(注意最后一个数后也有空格)Sample Input2 1 3 4 5 6 7 8 10 9Sam

  学生给我发了私信,一个程序运行了好久,在OJ就是提交不了。

  题目是:

Description
输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写三个函数; ①输入10个数;②进行处理;③输出10个数。

Input
10个整数

Output
整理后的十个数,每个数后跟一个空格(注意最后一个数后也有空格)

Sample Input
2 1 3 4 5 6 7 8 10 9
Sample Output
1 2 3 4 5 6 7 8 9 10 
HINT
  主函数已给定如下,提交时不需要包含下述主函数

/*  C/C++代码  */
int main()
{
    const int n=10;
    int a[n];
    input(a,n);
    handle(a,n);
    output(a,n);
    return 0;
}


  学生的解答:

#include<iostream>
#include<cstdio>
using namespace std;
void input(int a[],int);
void handle(int a[],int);
void output(int a[],int);
int main()
{
    const int n=10;
    int a[n];
    //freopen("input.txt","r",stdin);
    input(a,n);
    handle(a,n);
    output(a,n);
    return 0;
}
void input(int a[],int n)
{
    for(int i=0;i<n;i++)
    cin>>a[i];
}
void handle(int a[],int n)
{
    int max,i=0,t,min,z,zd,zx;
    max=a[i];
    min=a[i];
    for(i=0;i<n;i++)
    {
        if(max<a[i])
        {
            max=a[i];
            zd=i;    //记录最大值的位置
        }
        if(min>a[i])
        {
            min=a[i];
            zx=i;    //记录最小值的位置
        }
    }
    t=a[9];
    a[9]=max;
    a[zd]=t;           //进行值交换
    z=a[0];
    a[0]=min;
    a[zx]=z;

}
void output(int a[],int n)
{
    for(int i=0;i<n;i++)
    {
        cout<<a[i]<<" ";
    }
}
  这个解答在CodeBlocks中编译通过,屡经测试数据,没有异常,然而,提交后提示“Runtime error”,具体是:

  Runtime Error:Segmentation fault
  辅助解释:Segmentation fault:段错误,检查是否有数组越界,指针异常,访问到不应该
访问的内存区域

  这不科学!由“一定是我错了”的思维,转向了“可能是机器错了”,利用管理员帐号,看了测试数据,也没有问题。

  再逐句看程序,一个地方引起我的注意,会是25、26行引用a[i],但 i 没有赋值吗?不是,i 的初值是0,于算法没有问题。就在第24行,zd、zx两个变量,也应该是同步赋值的,它们表示最大、最小的数的下标,后面循环中,也及时对这两个数做了更新。

  问题逐渐明白了,在24行不给zd、zx赋初值的情况下,如果29和34行的if条件有一个始终未能为真,zd、zx就不会赋值,40行开始的交换,就会出现数组越界。

  在这个程序上小修改的办法有了:第24行,加上给zd、zx赋初值,即:int max,i=0,t,min,z,zd=0,zx=0;

  这个程序,没有用上单步执行。对这种小几率的问题,单步可能也不管用,思维要严密。

  这个程序写得稍显罗嗦,下面给出一个改写版。

#include<iostream>
#include<cstdio>
using namespace std;
void input(int a[],int);
void handle(int a[],int);
void output(int a[],int);

int main()
{
    const int n=10;
    int a[n];
    //freopen("input.txt","r",stdin);
    input(a,n);
    handle(a,n);
    output(a,n);
    return 0;
}

void input(int a[],int n)
{
    for(int i=0;i<n;i++)
    cin>>a[i];
}
void handle(int a[],int n)
{
    int i,t,zd=0,zx=0;//默认第0个为最大、最小
    for(i=1;i<n;i++)  //从第1个开始
    {
        if(a[zd]<a[i])
            zd=i;    //记录最大值的位置
        if(a[zx]>a[i])
            zx=i;    //记录最小值的位置
    }
    t=a[n-1];  //比用含有“神秘数”的a[9]好
    a[n-1]=a[zd];
    a[zd]=t;           //进行值交换
    t=a[0];
    a[0]=a[zx];
    a[zx]=t;
}

void output(int a[],int n)
{
    for(int i=0;i<n;i++)
    {
        cout<<a[i]<<" ";
    }
}





目录
相关文章
|
2月前
|
搜索推荐 编译器 C语言
【C++核心】特殊的元素集合-数组与字符串详解
这篇文章详细讲解了C++中数组和字符串的基本概念、操作和应用,包括一维数组、二维数组的定义和使用,以及C风格字符串和C++字符串类的对比。
78 4
|
3月前
|
C++
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
43 0
|
1月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
91 21
|
2月前
|
C++
【C++基础】程序流程结构详解
这篇文章详细介绍了C++中程序流程的三种基本结构:顺序结构、选择结构和循环结构,包括if语句、三目运算符、switch语句、while循环、do…while循环、for循环以及跳转语句break、continue和goto的使用和示例。
43 2
|
2月前
|
C++
C++(十一)对象数组
本文介绍了C++中对象数组的使用方法及其注意事项。通过示例展示了如何定义和初始化对象数组,并解释了栈对象数组与堆对象数组在初始化时的区别。重点强调了构造器设计时应考虑无参构造器的重要性,以及在需要进一步初始化的情况下采用二段式初始化策略的应用场景。
|
3月前
|
算法 C++
c++学习笔记04 数组
这篇文章是C++学习笔记4,主题是数组。
42 4
|
3月前
|
PHP C++ Python
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
60 0
|
3月前
|
C++ 索引
C++数组、vector求最大值最小值及其下标
C++数组、vector求最大值最小值及其下标
111 0
|
4月前
|
C++ 索引 运维
开发与运维数组问题之在C++中数组名和指针是等价如何解决
开发与运维数组问题之在C++中数组名和指针是等价如何解决
29 6
|
4月前
|
存储 安全 C++
开发与运维数组问题之声明一个数组如何解决
开发与运维数组问题之声明一个数组如何解决
44 6