在函数的循环中输入数据,需要将数据传递到另一个函数中的另一个循环 [英] Entering data in a loop in a function, need to get the data to another loop in another function

查看:78
本文介绍了在函数的循环中输入数据,需要将数据传递到另一个函数中的另一个循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好再次Code Project!



这是交易,我有两个独立的函数叫做InputData和DisplayPlayerData。这些函数中的每一个都在其中具有循环。 InputData中的循环应该获得玩家的名字和玩家的分数,用哨兵打破循环,不超过100名玩家。没问题。



另一个函数DisplayPlayerData有一个循环来显示每个玩家的名字和分数。



我在想我可以使用状态控制的while循环。我真正需要知道的是如何将第一个函数的输入数据带入第二个函数。这个函数看起来像public static void DisplayPlayerData(){}还是需要在()中声明一些变量?



修正:



这是任务写一个程序来确定视频游戏锦标赛的统计数据。用户将输入所有锦标赛玩家的名字和分数。该程序将计算平均分数并显示得分低于平均水平的球员。



该计划将实施这些功能:



.Main():声明玩家数量和平均分数的变量,以及两个大小为100的数组:一个用于存储玩家名称,另一个用于存储各自的分数。按顺序调用以下函数,通过引用传递必要的参数:



.InputData():从用户那里获取玩家名称和分数,并将它们存储到两个数组中,用于未知数量的最多100个palyers。



.DisplayPlayerData():Disp列出每个球员的名字和得分。



。计算平均值():计算平均得分并按值返回。



.DisplayBelowAverage():显示得分低于平均水平的玩家的名字和分数。



这是一个控制台应用程序,应该用C#编写。这是我到目前为止(支撑自己很糟糕)



Hello again Code Project!

Here is the deal, I have two separate functions called InputData and DisplayPlayerData. Each of these functions have loops inside of them. The loop in InputData is supposed to get player's name and player's score, breaking the loop with a sentinel and not to exceed 100 players. No problem.

The other function, DisplayPlayerData, has a loop to display the name and score of each player.

I am thinking that I could use a state controlled while loop. What I really need to know is how to bring the input data from the first function into the second function. Would this function look like public static void DisplayPlayerData(){} or do I need to declare a few variable in the ()?

Amendment:

Here is the "mission" "Write a program to determine the statistics for a video game tournament. The user will input names and scores of all tournament players. The program will calculate the average score and display the players who scored below average."

"The program will implement these functions:

.Main(): Declares variables for the number of players and average score, and two arrays of size 100: one to store players names and the other to store their respective scores. Calls the following functions in sequence, passing necessary parameters by reference:

.InputData(): Gets players names and scores from the user and stores them into the two arrays for an unknown number of palyers up to 100.

.DisplayPlayerData(): Displays each players name and score.

.CalculateAverageScore(): Calculates the average score and returns it by value.

.DisplayBelowAverage(): Displays the names and scores of players who scored below average."

This is a console application, supposed to be written in C#. Here is what I have so far(brace yourself it is bad)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Week5Lab
{
    class Program
    {
        static void Main(string[] args)
        {
            int numberOfPlayers;
            double averageScores;
            string[] PlayerNames = new string[100];
            double[] PlayerScores = new double[100];
            //call the InputData function to populate the arrays
            //call the DisplayPlayerData function to


        }//end main

        public static void InputData(ref string playerName, ref int playerScore, int numberOfPlayers)
        {
            Console.Write("Please enter the name of the player. ");
            Console.Write("To exit, enter:");
            Console.Write(" Q");
            Console.WriteLine("Please Enter Name. ( Q to exit)");
            playerName = Console.ReadLine();
            Console.WriteLine("Please enter the player score");
            playerScore = Convert.ToInt32(playerScore); Console.ReadLine();
            while (playerName != "Q" || numberOfPlayers <= 100)
            {
                Console.WriteLine("Please Enter Name. ( Q to exit)");
                playerName = Console.ReadLine();
                Console.WriteLine("Please enter the player score");
                playerScore = Convert.ToInt32(playerScore); Console.ReadLine();
                numberOfPlayers++;
            }

        }//end Input

        public static void DisplayPlayerData(ref string playerName, ref int playerScore, int numberOfPlayers)
        {


                while( numberOfPlayers <= 100)
                    //Display the Player Name
                    //Display the Player Score
                    //Pass by reference to Main
        }//end display

        public static double CalculateAverageScore(double averageScore, int numberOfPlayers)
        {
            //while (numberOfPlayers <= 100)  loop
            //sum all scores
            //end loop
            //averageScore = scoreSum / numberOfPlayers
            //Pass averageScore back to Main by Value
        }// end calculate

        public static void DisplayBelowAverage()
        {
            //Loop (score < averageScore)
            //Console.WriteLine(" {0} , {1}", nameOfPlayer, averageScore);
        }
    }//end class
}//end namespace

推荐答案

哦,很多问题,但没有什么太愚蠢。我也明白,这主要是一个研究项目,而不是真实的。实际上,在一些简单的仅限控制台的示例中学习东西是个好主意。当你对OOP和其他一些话题充满信心时,我真的建议切换到GUI。



让我们开始吧。



首先,了解什么是静态的,什么是公共的。你的 public 是最简单的事情。你到处都需要 private ,因为你总是可以访问同一个类中的所有东西,为了能够访问程序集中的任何内容,你需要 internal ,而不是 public ,这只是从另一个程序集访问时才需要的。此外,OOP继承需要 internal internal protected



你需要在这里阅读所有内容:

http://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx [ ^ ],

http://msdn.microsoft.com/en-us/library/ms173121.aspx [ ^ ]。



顺便说一下,之后你对最简单的仅限控制台项目有点自信,我建议立即行使装配,引用和使用。汇编是.NET的核心概念。



至于静态与非静态(实例)成员,它需要深入理解OOP的一些初始部分:类型,实例和封装。在这一刻,忘记实例字段,属性,事件实例 - 它们应该很少是静态的(在良好的编程中),因为这非常危险(特别是对于线程)。相比之下,静态方法非常常见,如果它们主要不用于访问静态成员,而只是用于参数,那么它们就很好。非静态实例成员仅在您需要访问某些实例成员时使用。为此,对整个实例的引用作为隐式 this 参数传递。请看我过去的答案:

C#windows基于这个关键词及其在应用程序中的用途 [ ^ ],

是什么让静态方法可以访问? [ ^ ]。



无论如何,所有你的方法(或大多数)应该是非静态的。总有,为什么不使用它?这不是绝对必需的,但是您提出的问题的可能解决方案之一是将数据保存在类实例成员中,然后您可以从不同的方法访问它。这实际上是 this 的目的。



对于清晰代码,最好避免全部实现在唯一的课堂上。养成创建代表不同概念的类的习惯。 (但原则上,使用你的班级程序没有任何问题。例如,它可能是

Ooh, many problems, but nothing too stupid. I also understand that this is mostly a study project, not something real. Actually, this is a good idea to learn things on some simple console-only sample. I would really advise to switch to GUI when you get confident with OOP and a number of other topics.

Let's start.

First, learn what is static and what is public. Your "public" is the simplest thing. You really need "private" everywhere, because you always have access to everything in the same class, to give access to anything within your assembly, you will need "internal", not "public", which is needed only for the access from another assembly. Additionally, OOP inheritance will need "internal" and "internal protected".

You need to read about it all here:
http://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx[^],
http://msdn.microsoft.com/en-us/library/ms173121.aspx[^].

By the way, after you get a bit confident with simplest console-only projects, I would advise to exercise immediately the assemblies, their referencing and use. Assembly is the central concept of .NET.

As to static vs. non-static (instance) members, it need in depth understanding of some initial part of OOP: types, instances and encapsulation. For a this moment, forget instance fields, properties, event instances — they should very rarely be static (in good programming), as this is pretty dangerous (in particular, for threading). In contrast, static methods are very usual, and are good if they are used mainly not to access static members, but just to work only with parameters. Non-static, instance members are used only when you need to access some instance members. For this purpose, the reference to the whole instance is passed as the implicit "this" parameter. Please see my past answers:
C# windows base this key word related and its uses in the application[^],
What makes static methods accessible?[^].

Anyway, all your methods (or most of them) should be non-static. You have the class, always, why not using it? This is not absolutely required, but one of the possible solutions to the problem you formulated would be keeping data in your class instance member(s), then you can access it from different methods. This is actually the purpose of "this".

For clear code, it's better to avoid implementing it all in the only class. Develop a habit to create classes representing distinct concepts. (But in principle, there is nothing wrong with using your class Program. For example, it could be
static class Program {

   static void Main() {
       new PlayerLab().Run(); // for example
   }

}





这样,您可以专注于单独的类 PlayerLab ,这可能是非静态,其方法运行应该使用访问修饰符 internal (不是 public )。尝试只根据需要提供尽可能多的访问权限。



第二步是:避免立即常量之类的Q,Q等。想想如果您决定用E(退出)替换Q会发生什么。这是不可接受的。您将不得不把它变成几个,也许很多个地方。你怎么能保证你记得所有的地方。编译器不会帮助你。始终定义显式常量或只读表达式:



And, this way, you can concentrate on the separate class PlayerLab, which may be non-static, and its method Run should be with the access modifier internal (not public). Try to give only as much access as needed.

Second step is: avoid immediate constants like " Q", "Q", etc. Think what happens if you decide to replace "Q" with "E" (Exit). This is unsupportable. You will have to change it in several, maybe many places. How can you guarantee you remember all places. The compiler won't help you. Always define explicit constants or read-only expressions:

const string ExistKey = "Q";
readonly string ExitHint = string.Format("To exit, hit {0}", ExistKey);
//... and so on

我希望你得到了这个想法。



现在,输入和处理数据。首先,养成创建类型的习惯。如果输入内容,请为其命名和结构( struct / class ):

I hope you got the idea.

Now, input and processing data. First of all, get the habit of creating types. If you input something, give it a name and the structure (struct/class):

struct Player {
    internal Player(string name, int score, int numberOfPlayers) {
        Name = name;
        Score = score;
        NumberOfPlayer = numberOfPlayers;
    }
    internal Player(string name) {
        Name = name;
        Score = 0;
        NumberOfPlayer = 0;
    }
    bool IsValid { get { return Name != null; } } // we will discuss it below
    internal string Name;
    internal int Score;
    internal int NumberOfPlayers;
}

它将帮助您使输入法声音:

It will help you to make input method sound:

Player InputPlayer() { // see? no parameters
    // request name, score, etc.
    // ...
    return new Player(name, score, numberOfPlayers); 
}



现在,收集输入数据时的成员应该是一些集合。最简单的一个是


Now, the member when you collect the input data should be some collection. The simplest one would be

System.Collections.Generic.List<Player> players = new System.Collections.Generic.List<Player>();
// start learning generics already, maybe only at the user's level for now 



现在,您已准备好在循环中收集 Player 的实例。怎么样?首先,我们没有照顾退出。我们抽象出 Player 输入的方法,但没有考虑退出的可能性。它可以通过多种方式完成,但让我们通过播放器的无效实例来指示它,而这又可以通过null来完成。我们可以通过将播放器类型更改为可为空类型来实现,可以是播放器? class 而不是 struct 。但是我会通过指示它来显示它,只需要名称



注意物业 IsValid 我补充道。如果我们将null传递给构造函数,则该结构被视为无效(无名称)。请注意,可以来自用户输入的空名称有效。我们可以修改输入,并可以输入此null:


Now, you are ready to collect instances of Player in the loop. How? First of all, we did not take care of exit. We abstracted out the method of the Player input, but did not take into account the possibility of exit. It can be done in several ways, but let's indicate it by "invalid" instance of the player, which, in turn, can be done via null. We can do it by changing Player type to nullable type, which can be Player?, or class instead of struct. But I will demonstrate it by indicating it by having null Name.

Pay attention for the property IsValid I added. If we pass null to the constructor, the structure is considered invalid (no name). Note that empty name which can come from user input is valid. We can modify the input with the possibility to enter this null:

Player InputPlayer() { // see? no parameters
    // request name, score, etc.
    // ...
    bool exitRequested = //.. calculate it from input as you already do
    // ...
    if (exitRequested) name = null;
    return new Player(name, score, numberOfPlayers); 
}

现在我们可以编写循环:

Now we can write the cycle:

while (true) {
   Player player = InputPlayer();
   if (!player.IsValid) break;
   players.Add(player); // as simple as that
}

现在您可以处理稍后在播放器列表中累积的数据:

Now you can process the data accumulated in the player list later:

foreach(Player player in players)
    ProcessPlayer(player);



你只需要开发方法 ProcessPlayer 来做你想做的事情。



再次,你只分享一个类的不同方法之间的成员 PlayerLab ,这是玩家。它是可访问的,因为每个方法都传递给它的参数 this (你可能想要调用它 this.players ,这可能是解决方案所必需的,如果,由于一些奇怪的原因,你引入了局部变量,也称为玩家



我认为这已经足够了。我已经提出了许多重要的编程要点。



祝你好运,

-SA


You only need to develop the method ProcessPlayer to do what you want to do with each.

Again, you share just one member between different methods of your class PlayerLab, this is players. It is accessible because each of the methods gets the parameter "this" passed to it (you may want to call it this.players, which might be required for resolution, if, by some weird reason, you introduce local variable also called players.

I think that's enough. I already presented very many important points of programming.

Good luck,

—SA


您可以使用类变量(如List)来存储第一个方法中的数据。然后在第二个方法中访问它。
You can use a class variable such as List to store the data from the first method. Then access it in the second method.


嘿SG,



非常感谢上述解决方案。这比我一直在做的更有意义。我的脑袋受伤了墙上满洞:)。这是我在阅读你为我准备的内容之前所取得的成就。我会回去按照你给我的建议重新编写程序,但在此之前我想和你分享我的工作,因为你很慷慨地帮助像我这样的菜鸟。这是:



Hey SG,

Thank you very much for the above solution. This make much more sense than what I have been doing. My head is bruised and the wall full of holes :). Here is what I accomplished before I got to read what you laid out for me. I am going to go back and rework the program with the advice that you have given me, but before I do I would like to share my work with you, as you are gracious enough to help out a noob like myself. here it is:

//Week 5 iLab part A
//Programmer: Benjamin Cook
//Date Authored: 8/13/2013
//Objective: The objective of this program is to view the statistics of a video game tournament
// by adding the players names, and scores. Once the score is entered the scores are averaged.
//The program will also show the players who scored underneath the average score.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Week5Lab
{
    class Program
    {
        static void Main(string[] args)
        {
            int numberOfPlayers;
            double averageScore;
            string[] PlayerNames = new string[100];
            double[] PlayerScores = new double[100];
            string answer = "n";
            int position =0;

            while (answer != "Q";)
            {
                if (position >= PlayerNames.Length)
                    break;
                InputData(PlayerNames, PlayerScores, position);
                Console.Write("To exit, enter:( Q to exit)");
                answer = Console.ReadLine();
                position++;


            }

            averageScore = CalculateAverageScore(PlayerScores, position);
            DisplayBelowAverage(PlayerScores, PlayerNames, position, averageScore);



        }//end main

        public static void InputData( string[] names, double []scores, int position)
        {
            Console.Write("Please enter the name of the player.");

            names[position] = Console.ReadLine();
            Console.WriteLine("Please enter the player score");
            scores[position] = double.Parse(Console.ReadLine());


        }//end Input

        public static void DisplayPlayerData(string[] names, double []scores, int position)
        {
            for (int i = 0; i < position; i++)
            {
                Console.WriteLine(names[i]);
                Console.WriteLine(scores[i]);
            }


        }//end display

        public static double CalculateAverageScore( double[] playerScore, int numberOfPlayers)
        {
            double totalScore = 0;
            for (int i = 0; i < numberOfPlayers; i++)
             {
               totalScore += playerScore[i];
             }

            double averageScore = totalScore / numberOfPlayers;
            return averageScore;
        }// end calculate

        public static void DisplayBelowAverage(double[] playerScore,string [] playerName, int position, double avgScore)
        {
           
            int cntr=0;
            while (cntr < position)
            {
                if (playerScore[cntr] < avgScore)
                    Console.WriteLine(playerName[cntr] + " " + playerScore[cntr]);

                cntr++;
            }
        }
    }//end class
}//end namespace

Now I am tasked to turn this program into a GUI, which is what I working on currently. Thanks again SG. I look forward to keeping you updated on my progress!


这篇关于在函数的循环中输入数据,需要将数据传递到另一个函数中的另一个循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆