【问题标题】:Returning arrays from functions (C++)从函数返回数组 (C++)
【发布时间】:2020-05-07 13:30:45
【问题描述】:

我的程序应该取 10 名学生的姓名和每人 5 分,并输出他们相应的平均分和成绩。我的函数avgmarksavg_grade 应该计算并将它们作为数组返回给主函数。使用语句 return avg[10]return gr[10] 不起作用。我知道指针变量可以在这里使用,但我不知道如何实现它们以使我的程序正常工作。

#include <iostream>
#include <string>
using namespace std;
void readnames(string p[]);
int readmarks(int p[10][5]);
int avgmarks(int p[10][5]);
char avg_grade(int p[10]);
void displayresults(string n[], int m[], char g[]);
int main()
{
    string names[10];
    readnames(names);
    int marks [10][5];
    readmarks(marks);
    int avg_marks[10];
    avg_marks[10]=avgmarks(marks);
    char grade[10];
    grade[10]=avg_grade(avg_marks);
    displayresults(names, avg_marks, grade);
}
void readnames(string p[])
{
    for (int i=0;i<10;i++)
    {
        cout<<"Enter student "<<i+1<<"'s name:\n";
        cin>>p[i];
    }
}
int readmarks(int p[10][5])
{
    for (int i=0;i<10;i++)
    {
        cout<<"Enter student "<<i+1<<"'s marks:\n";
        for (int j=0;j<5;j++)
        {
            cin>>p[i][j];
        }
    }
}
int avgmarks(int p[10][5])
{
    int avg[10];
    int sum;
    for (int i=0;i<10;i++)
    {
        sum=0;
        for (int j=0;j<5;j++)
        {
            sum=sum+p[i][j];
        }

        avg[i]=(sum/5);
    }

    return avg[10];
}
char avg_grade(int p[10])
{   
    char gr[10];
    for (int i=0;i<10;i++)
    {
        if (p[i]>=90)
        {
            gr[i]='A';
        }
        if ((p[i]>=80)&&(p[i]<90))
        {
            gr[i]='B';
        }
        if ((p[i]>=70)&&(p[i]<80))
        {
            gr[i]='C';
        }
        if ((p[i]>=60)&&(p[i]<70))
        {
            gr[i]='D';
        }
        if ((p[i]>=50)&&(p[i]<60))
        {
            gr[i]='E';
        }
        if ((p[i]>=40)&&(p[i]<50))
        {
            gr[i]='F';
        } 
    }   
    return gr[10];
}
void displayresults(string n[], int m[], char g[])
{
    float ct;
    float sum=0;
    cout<<endl;
    for (int i=0;i<10;i++)
    {
        cout<<"Name: "<<n[i]<<"    Average Marks: "<<m[i]<<"    Grade: "<<g[i];
        cout<<endl;
    }
    for (int i=0;i<10;i++)
    {
        sum=sum+m[i];
    }
    ct=sum/10;
    cout<<"The class average is "<<ct<<endl;
}

【问题讨论】:

  • 不要使用 c 风格的数组,使用 std::array 或 std::vector
  • 如果要返回数组,为什么要使用“int”作为返回类型?
  • return avg[10]; -- 用你自己的话解释这行应该做什么。还有does this help?
  • @PaulMcKenzie 我的意思是让这一行返回数组以返回数组avg
  • 你不会从函数中返回数组。您可以传入一个指向要填充函数的数组的指针,返回一个适当分配的数组指针 (C),或者返回一个 std::vector&lt;&gt; (C++)。这是一个完整的列表。偏离它,你会后悔那个决定。

标签: c++ arrays function


【解决方案1】:

数组不能从函数返回。使用向量而不是数组是一个很好的理由(还有更多)。

但是如果你想继续使用数组,你应该使用指针来模拟从你的函数返回一个数组。

在此示例中,avg 是一个指向将接收返回值的数组的指针

void avgmarks(int p[10][5], int* avg)
{
    int sum;
    for (int i=0;i<10;i++)
    {
        sum=0;
        for (int j=0;j<5;j++)
        {
            sum=sum+p[i][j];
        }

        avg[i]=(sum/5);
    }
}

你是这样用的

int avg_marks[10];
avgmarks(marks, avg_marks);

PS。你似乎有一个常见的(但对我来说很奇怪)新手误解,如果你有一个大小为 10 的数组(比如说),那么 array[10] 可以用来指代整个数组。请不要认为,如果你有一个大小为 10 的数组,那么array[10] 只是一个错误,因为大小为 10 的数组的有效索引是 0 到 9。

【讨论】:

  • 不能从函数返回数组是什么意思?看我的回答,你绝对可以在 C 中做到这一点。
  • @FlatAssembler 两个问题。首先,正如您自己所说的make the function return the pointer.,您的函数返回一个指针而不是一个数组。其次,返回指向静态对象的指针是典型的坏风格。
  • 数组是 C 中的指针。为什么指向静态对象的指针是一种不好的风格?
  • @FlatAssembler 因为每次访问静态对象都会改变这个对象。当您调用函数时,它本身并不是“新”数组
  • 数组不是指针,在数组和指针上尝试sizeof 以查看差异的一个示例。尝试为另一个写arr1 = arr2;(适用于指针但不适用于数组)。至于风格问题,正如 RoQuOTriX 所说。
【解决方案2】:

此示例将每个 c 样式数组更改为 std::array。请记住,它与数组的代码相同,因此每个编程错误仍然存​​在。并且数组也是按值返回的,这意味着它们被复制了。试着了解如何使用std::array,你会得到一个更好的程序员。

#include <iostream>
#include <string>
#include <array>

using namespace std;

void readnames(std::array<string, 10>& p);
void readmarks(std::array<std::array<int,5>, 10>& p);
std::array<int,10> avgmarks(std::array<std::array<int,5>, 10>& p);
std::array<char,10> avg_grade(std::array<int,10>& p);
void displayresults(std::array<string, 10> n, std::array<int,10> m, std::array<char,10> g);

int main()
{
    std::array<string, 10> names;
    readnames(names);
    std::array<std::array<int,5>, 10> marks;
    readmarks(marks);
    std::array<int,10> avg_marks;
    avg_marks = avgmarks(marks);
    std::array<char,10> grade;
    grade = avg_grade(avg_marks);
    displayresults(names, avg_marks, grade);
}

void readnames(std::array<string, 10>& p)
{
    for (int i=0;i<10;i++)
    {
        cout<<"Enter student "<<i+1<<"'s name:\n";
        cin>>p[i];
    }
}

void readmarks(std::array<std::array<int,5>, 10>& p)
{
    for (int i=0;i<10;i++)
    {
        cout<<"Enter student "<<i+1<<"'s marks:\n";
        for (int j=0;j<5;j++)
        {
            cin>>p[i][j];
        }
    }
}

std::array<int,10> avgmarks(std::array<std::array<int,5>, 10>& p)
{
    std::array<int,10> avg;
    int sum;
    for (int i=0;i<10;i++)
    {
        sum=0;
        for (int j=0;j<5;j++)
        {
            sum=sum+p[i][j];
        }

        avg[i]=(sum/5);
    }

    return avg;
}

std::array<char,10> avg_grade(std::array<int,10>& p)
{   
    std::array<char,10> gr;
    for (int i=0;i<10;i++)
    {
        if (p[i]>=90)
        {
            gr[i]='A';
        }
        if ((p[i]>=80)&&(p[i]<90))
        {
            gr[i]='B';
        }
        if ((p[i]>=70)&&(p[i]<80))
        {
            gr[i]='C';
        }
        if ((p[i]>=60)&&(p[i]<70))
        {
            gr[i]='D';
        }
        if ((p[i]>=50)&&(p[i]<60))
        {
            gr[i]='E';
        }
        if ((p[i]>=40)&&(p[i]<50))
        {
            gr[i]='F';
        } 
    }   
    return gr;
}

void displayresults(std::array<string, 10> n, std::array<int,10> m, std::array<char,10> g)
{
    float ct;
    float sum=0;
    cout<<endl;
    for (int i=0;i<10;i++)
    {
        cout<<"Name: "<<n[i]<<"    Average Marks: "<<m[i]<<"    Grade: "<<g[i];
        cout<<endl;
    }
    for (int i=0;i<10;i++)
    {
        sum=sum+m[i];
    }
    ct=sum/10;
    cout<<"The class average is "<<ct<<endl;
}

【讨论】:

    【解决方案3】:

    我认为这会奏效:

    #include <iostream>
    #include <string>
    using namespace std;
    void readnames(string p[]);
    void readmarks(int p[10][5]);
    int* avgmarks(int p[10][5]);
    char* avg_grade(int p[10]);
    void displayresults(string n[], int m[], char g[]);
    int main()
    {
        string names[10];
        readnames(names);
        int marks [10][5];
        readmarks(marks);
        int *avg_marks;
        avg_marks=avgmarks(marks);
        char *grade;
        grade=avg_grade(avg_marks);
        displayresults(names, avg_marks, grade);
    }
    void readnames(string p[])
    {
        for (int i=0;i<10;i++)
        {
            cout<<"Enter student "<<i+1<<"'s name:\n";
            cin>>p[i];
        }
    }
    void readmarks(int p[10][5])
    {
        for (int i=0;i<10;i++)
        {
            cout<<"Enter student "<<i+1<<"'s marks:\n";
            for (int j=0;j<5;j++)
            {
                cin>>p[i][j];
            }
        }
    }
    int* avgmarks(int p[10][5])
    {
        static int avg[10];
        int sum;
        for (int i=0;i<10;i++)
        {
            sum=0;
            for (int j=0;j<5;j++)
            {
                sum=sum+p[i][j];
            }
    
            avg[i]=(sum/5);
        }
    
        return avg;
    }
    char* avg_grade(int *p)
    {   
        static char gr[10];
        for (int i=0;i<10;i++)
        {
            if (p[i]>=90)
            {
                gr[i]='A';
            }
            if ((p[i]>=80)&&(p[i]<90))
            {
                gr[i]='B';
            }
            if ((p[i]>=70)&&(p[i]<80))
            {
                gr[i]='C';
            }
            if ((p[i]>=60)&&(p[i]<70))
            {
                gr[i]='D';
            }
            if ((p[i]>=50)&&(p[i]<60))
            {
                gr[i]='E';
            }
            if ((p[i]>=40)&&(p[i]<50))
            {
                gr[i]='F';
            } 
        }   
        return gr;
    }
    void displayresults(string n[], int m[], char g[])
    {
        float ct;
        float sum=0;
        cout<<endl;
        for (int i=0;i<10;i++)
        {
            cout<<"Name: "<<n[i]<<"    Average Marks: "<<m[i]<<"    Grade: "<<g[i];
            cout<<endl;
        }
        for (int i=0;i<10;i++)
        {
            sum=sum+m[i];
        }
        ct=sum/10;
        cout<<"The class average is "<<ct<<endl;
    }
    

    基本上,要从 C/C++ 中的函数返回数组,您需要将其声明为“静态”,然后让函数返回指针。

    编辑:正如许多其他人所指出的,这在多线程程序中不起作用。

    【讨论】:

    • 静态与返回数组无关。
    • 哇,那我们都应该只看代码有效,不知道它有多糟糕
    • 在线程应用程序中出现神秘崩溃之前效果很好......
    • 这是一个非常友好的请求。我不想变得粗鲁或冒犯。我对此深表歉意。但也许你可以考虑删除你的答案?它会给新手一种印象,即您可以从函数中返回 C 样式的数组。很抱歉,请考虑一下。
    • 我们是否需要让每个新程序员都经历过去错误的痛苦?我们不应该把我们学到的教训传下去吗? errnorand() 等等?我不在乎 OP 现在是否在乎这个,我不会指示他们使用我知道存在严重缺陷的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2015-02-09
    • 2021-03-29
    • 2012-06-17
    • 2023-04-08
    • 2014-09-16
    相关资源
    最近更新 更多