【问题标题】:Store returned array from a function [closed]存储从函数返回的数组[关闭]
【发布时间】:2014-02-12 15:11:28
【问题描述】:

我只是想制作一个简单的两人游戏。第一个玩家进入电影,第二个玩家使用一些基本的 C++ 猜测它。

movie[] = entered by player 1.
movie_temp[]= a temp array with '_' in it. It updates after every guess by player 2.

我的问题:请参考我调用函数movie_check()的主要函数。 这会在每次猜测后更新生活。我希望我的movie_temp array 也能发生同样的事情。 当我运行这个程序时,只有生命值被正确更新,正确猜测的生命值不会减少,但接下来array_temp 不会更新,并且在每次加油后一次又一次地显示相同的数组。

请帮助我创建一个有助于返回数组并将其保存在movie_temp 中的函数(就像我一生所做的那样)。

IDE:代码::块 编译器:GCC 编译器

#include<iostream.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#include<conio.h>

void display_movie(char movie_temp[], int);
void display_life(int);
int win_player2(char movie_temp[]);
int check_life(char movie[], char, int);


void display_movie(char movie_temp[], int len)
{
    for(int i=0 ; i<len ; i++)
        cout<<movie_temp[i];
}

void display_life(int life)
{
    for(int i=0 ; i<=life ; i++)
        cout<<"\3";
}


int check_life(char movie[], char ch, int life)
{
    int count1=0;
    for(int i=0 ; movie[i]!='\0' ; i++)
    {
        if(movie[i]==ch)
            count1++;
    }
    if(count1==0)
        return --life;
    else
        return life;
}

int win_player2(char movie_temp[])
{
    int count=0;
    for(int i=0 ; movie_temp[i]!='\0' ; i++)
   {
       if(movie_temp[i]=='_')
           count++;
   }
   if(count==0)
        return 0;
   else
        return 1;
}


int main()
{
    char movie[100], movie_temp[100], ch;
    cout<<"Enter the movie: ";
    cin.getline(movie,100);
    int len= strlen(movie);
    system("cls");


    for(int i=0 ; movie[i]!='\0' ; i++)
    {
        if(movie[i]=='a' || movie[i]=='e' || movie[i]=='i' || movie[i]=='o' ||
        movie[i]=='u' || movie[i]==' ')
            movie_temp[i]= movie[i];
        else
            movie_temp[i]='_';
    }

    int life=9;
    cout<<"\nLives left: ";
    display_life(life);


    while(life!=0 || win_player2(movie_temp)!=0)
    {
        cout<<"\n";
        display_movie(movie_temp, len);
        cout<<"\nEnter your guess: ";
        cin>>ch;
        life=check_life(movie, ch, life);
        cout<<"\n\nLives left: ";
        display_life(life);

    }
    getch();
    return 0;
}

enter code here

【问题讨论】:

  • 使用std::string 会容易得多。
  • 如果您使用 conio.h,为什么不直接使用 clrscr() 而不是 system("cls")
  • 看起来更像是 C 趋向于 C++。除了coutcin 之外,一切似乎都是C。使用C++ 结构让你的生活更轻松。
  • 紧跟在return life; 之后的count1=0; 是无法访问的代码(它也是多余的,因为它只在count1 == 0 首先执行)。一定要提高你的警告级别来捕捉这样的东西。
  • @lazygeek 如果你所学习的任何东西都没有提到 std::string,我建议你 pick up a good book 并学习如何使用你正在使用的语言的特性。

标签: c++ arrays function return-value


【解决方案1】:

你犯了通常的错误:

            movie_temp[i]==movie[i];

应该是

            movie_temp[i]=movie[i];

你的编译器应该对你发出警告......我的做了:

note: use '=' to turn this equality comparison into an assignment
                movie_temp[i]==movie[i];

上下文(以防您找不到线路):

    if(movie[i]==ch)
        {
            movie_temp[i]==movie[i];   // <<<<<<<<<< this is the line that doesn't copy!
            count1++;
        }

更新 只是在编译器给我的警告之后,我对你的代码做了一些小改动,现在它可以工作了。大多数情况下,我注意到“你没有返回值!”警告类型(当您没有显式返回值时,编译器会编造一些东西 - 而且很可能您不会发现结果有用)。

关键是移动线

return movie_temp;

check_movie2 中的for 循环之外:

char* check_movie2(char movie[], char movie_temp[], char ch)
{
    for(int i=0 ; movie[i]!='\0' ; i++)
    {
        if(movie[i]==ch)
            {
                movie_temp[i]=movie[i];
            }
    }
    return movie_temp;
}

还有其他问题 - 但这是最​​让你痛苦的问题。

经验教训:如果您的编译器警告您,请听。

为了您的娱乐,这里是我必须运行的代码(并且“大部分都有效”。它目前无法正确打印出生命值,并且在我猜到标题后它会要求输入。您也可以考虑进行比较不区分大小写,因为您目前对正确的大小写敏感)。

更新在您的代码中添加了一些 cmets 和其他修复。

#include<iostream>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

using namespace std;  // <<<< if you want to use 'cout' instead of 'std::cout' etc, you need this

void display_movie(char movie_temp[], int);
void display_life(int);
int win_player2(char movie_temp[]); 
int check_movie(char movie[], char movie_temp[], char, int);
void display_movie(char movie_temp[], int len)
{
    for(int i=0 ; i<len ; i++)
    cout<<movie_temp[i];
}

void display_life(int life) //displays lives left after each guess
{
    for(int i=0 ; i<=life ; i++)
    cout<<"+";     // <<<<< I don't know what you are hoping to print with "\3"
                   // <<<<< Remember that `\` has a special meaning inside a string!
}


int check_movie(char movie[], char movie_temp[], char ch, int life)
{
    int count1=0;
    for(int i=0 ; movie[i]!='\0' ; i++)
    {
        if(tolower(movie[i])==tolower(ch))    // <<<<< consider case insensitive match 
            {
                movie_temp[i]=movie[i];
                count1++;
            }
    }
    if(count1==0)
        {
            life--;
            return life;    //if none of the character is found, life is reduced by 1.
            count1=0;
        }
    return life; // <<<<<< return life here    
}

int win_player2(char movie_temp[])
{
    int count=0;
    for(int i=0 ; movie_temp[i]!='\0' ; i++)
    {
        if(movie_temp[i]=='_')
            count++;
    }  
    return (count==0)?0:1;
}

char* check_movie2(char movie[], char movie_temp[], char ch)
{
    for(int i=0 ; movie[i]!='\0' ; i++)
    {
        if(movie[i]==ch)
            {
                movie_temp[i]=movie[i];
            }
    }
    return movie_temp;
}

int main()
{
    char movie[100], movie_temp[100], ch;
    cout<<"Enter the movie: ";
    cin.getline(movie,100);
    int len= strlen(movie);
    int life=9;
    system("cls");


    for(int i=0 ; movie[i]!='\0' ; i++)
    {
        if(movie[i]=='a' || movie[i]=='e' || movie[i]=='i' || movie[i]=='o' ||
        movie[i]=='u' || movie[i]==' ')
        movie_temp[i]= movie[i];
    else
        movie_temp[i]='_';
    }    //initially displays the movie to player 2 and shows only vowels.

    cout<<"\nLives left: ";
    display_life(life);


    while(life!=0 && win_player2(movie_temp)!=0)  // <<<<< change || to &&
    {
        cout<<"\n";
        display_movie(movie_temp, len);
        cout<<"\nEnter your guess: ";
        cin>>ch;
        life=check_movie(movie, movie_temp, ch, life); 

        /*I need to update the life after each round, or else the initially declared              
         life is passed. */

        cout<<"\n\nLives left: ";
        display_life(life);

    }
    return 0;
}

UPDATE - “从函数返回指针”

要“返回一个值的数组”,你需要实现一些事情:

  1. 函数只能“返回”一个简单的值(int、float、pointer...)
  2. 如果在函数内创建数组,则需要确保 返回后分配的空间仍然有效
  3. 您可以将指针传递给函数,并让函数更新空间指针中的值

关于不同方法的简单示例 (C)(包括一种不起作用的方法):

不起作用:

   int * foo() {
     int A[]={1,2,3,4,5};
     return A;
   }

int main(void) {
  int *X;
  X = foo();
  printf("%d", X[0]);  // UNDEFINED BEHAVIOR
  return 0;
}

这不起作用,因为数组A 在函数返回时停止存在(“超出范围”)。访问X 指向的内存会导致未定义的行为。

有效,但只能在单线程环境中使用:

   int * foo() {
     static int A[]={1,2,3,4,5};
     return A;
   }

这是有效的,因为数组是static,所以它的分配方式不同,并且在函数返回后“存活”。不推荐。

传递数组的指针和大小:(示例递增数组)

void foo(int *a, int n) {
  int ii;
  for(ii=0;ii<n;ii++) a[ii]++;
}

int main(void) {
  int n=5;
  int X[5] = {1,2,3,4,5};
  foo(X, 5);  // values in X will be incremented in-place

在另一个数组中返回值:

void foo(int *A, int *B, int n) {
  int ii;
  for(ii=0; ii<n; ii++) B[ii] = 2 * A[ii];
}

int main(void) {
  int a[5] = {1,2,3,4,5};
  int b[5];
  foo(a, b, 5);
  printf("%d\n", b[0]);  // returns a value of 2
  return 0;
}

这开始变得更加明智。最后,如果你想通过函数创建一个数组,你可以这样做

int *foo(int n) {
  int *X, ii;
  X = malloc(n * sizeof *X);
  for(ii = 0; ii < n; ii++) X[ii] = 2 * ii;
  return X;
}

int main(void) {
  int *a;
  a = foo(5);
  printf("%d", a[4]); // will print 8
  free(a);  // remember to do this after you finished using the array or you get a memory leak!
  return 0;
}

我希望这些额外的例子和它们的解释能稍微提高你对这些技术的理解。

【讨论】:

  • 哦,是的。我想通了。傻我。但是当我应用那个赋值符号时,会有无限循环打印无尽的心(“\3”)
  • 请帮我用函数返回一个数组。
  • 感谢@floris 的建议。我期待着考虑不区分大小写。
  • 我做了一些改动。请再次检查代码。
  • 我不知道你为什么做出这些改变——你现在比以前离目标更远了。您是否尝试运行我上面发布的代码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
相关资源
最近更新 更多