C# Use of un-assigned variable [duplicate] - c#

This question already has answers here:
What does "Use of unassigned local variable" mean? [duplicate]
(11 answers)
Closed 8 years ago.
Hmmmm, I wonder why isn't this working...It gives an error stating "Use of unassigned local variable max". So, what is wrong with this code? I cant figure it out.
namespace ConsoleApplication1
{
class Program
{
public int CalculateHighestNum(int value1, int value2, int value3)
{
int max;
if (value1 > (value2 & value3))
{
max = value1;
}
else if(value2 > (value1 & value3))
{
max = value2;
}
else if(value3 > (value1 & value2))
{
max = value3;
}
return max;
}
static void Main(string[] args)
{
Console.Write("Enter first NUM : ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter second NUM : ");
int b = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter third NUM : ");
int c = Convert.ToInt32(Console.ReadLine());
Program p = new Program();
int highestnum = p.CalculateHighestNum(a, b, c);
Console.WriteLine(highestnum + " = Highest Number");
}
}

You need to set an initial value to max, or any other local variable, before you can use it.
int max = 0;
The reason for this is to reduce the chance of using a variable without assigning it a sensible default, and because the variable needs to be assigned to something before being returned. (In this case, if your if statements are all false)
The compiler will not show this error if you assign a value to the variable in all cases, such as in an else statement.
Also, as #Partha explained in the comments, you could simplify your logic to just:
return Math.Max(value1, Math.Max(value2, value3));

Related

Dividing 2 integer without using / operator using c#. Can anyone convert this to for loop [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Can I ask for this question to be deleted? To help me recover my account. Thank you
int[] numbers = { 200, 100, 50, 3, 1 };
int count = int.Parse(txtNumber.Text);
double number = 0;
double number1 = 0;
double number2 = 0;
double number3 = 0;
double number4 = 0;
if (count == 0)
{
MessageBox.Show("Can't Divide 0");
return;
}
while (count >= numbers[0])
{
count = count - numbers[0];
number++;
}
txt200.Text = number.ToString();
label1.Text = count.ToString();
while (decimal.Parse(label1.Text) >= numbers[1])
{
label1.Text = (int.Parse(label1.Text) - numbers[1]).ToString();
number1++;
}
txt100.Text = number1.ToString();
Can somebody help me to vote this for deletion??
You can do it with an empty for loop, where all the operations occur in the loop's condition and the iterator:
int result = 1;
for (int numCopy = numerator; numCopy > denominator; numCopy -= denominator, result++);
Here's a sample method:
public static int Divide(int numerator, int denominator)
{
int result = 0;
for (; numerator >= denominator; numerator -= denominator, result++) ;
return result;
}
Note that I'm working only with integers here. Converting strings to integers and then back to strings again inside a loop is not very efficient. Now we can convert the Text properties once, pass the integers to our method, and then convert the result once.
Here's a sample usage (using a Console application):
static void Main()
{
int numerator = GetIntFromUser("Please enter the numerator: ");
int denominator = GetIntFromUser("Please enter the denominator: ");
int result = Divide(numerator, denominator);
Console.WriteLine($"{numerator} / {denominator} = {result}");
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output
Oh, and these are the helper methods I'm using:
private static int GetIntFromUser(string prompt)
{
int input;
do
{
Console.Write(prompt);
} while (!int.TryParse(Console.ReadLine(), out input));
return input;
}
private static ConsoleKeyInfo GetKeyFromUser(string prompt)
{
Console.Write(prompt);
var key = Console.ReadKey();
Console.WriteLine();
return key;
}
A typical while-loop looks like this:
// Initialize loop variable
int i = 0;
while (i < count) // Test loop condition
{
//TODO: Do some work.
// Increment loop variable
i++;
}
The for-loop allows you to initialize, test and increment the loop variable at one spot
for (int i = 0; i < count; i++) {
//TODO: Do some work.
}
But while-loops seem appropriate here. If you extract the calculation into a function, you can reuse it. This is better than copy-pasting the code to apply it to several inputs.
private static int Divide(int dividend, int divisor)
{
int result = 0;
int remainder = dividend;
while (remainder >= divisor) {
remainder -= divisor;
result++;
}
Console.WriteLine($"{dividend} / {divisor} = {result}, remainder = {remainder}");
return result;
}
Don't assign the label text inside the loop, as the label will only keep the last assignment. Also, labels are not a good place to store numbers.
Convert all the numbers that are in labels and textboxes to integers before you start any calculation.
Do the calculations without referencing any UI controls.
Convert and assign the result of the calculations to labels and textboxes.
Mixing UI stuff and calculations makes the code unnecessarily complicated and difficult to read.
Give speaking names to controls and variables. Nobody knows what a textbox named txt3, a label named label1 or a variable named number2 are supposed to represent. Good names are txtDividend, txtResult or dividend and result for the respective variables.

Scope issue in function, local variable not defined [duplicate]

This question already has answers here:
C#: Use of unassigned local variable, using a foreach and if
(6 answers)
Closed 4 years ago.
I am getting an error for dateClose.closing, "use is unassigned local variable". I declared dateClose outside of the for loop and defined the value inside the for loop. How can I make that value available outside of the for loop?
public class SMA
{
public Models.DateClose SMAMethod (Queue<Models.DateClose> queue, int period)
{
decimal average, sum=0;
Models.DateClose dateClose;
for (int i = 0; i < period; i++)
{
dateClose = queue.Dequeue();
sum += dateClose.Close;
}
average = sum/period;
dateClose.Close = average; <--- error
return dateClose;
}
}
you can simply fix the error by doing
Models.DateClose dateClose = null;
however you would also want to add a null check to make sure you don't run into null ref exception if queue has no item.
You can do this. If your period variable is greater than the queue count than dateClose.Close will throw an exception.
public Models.DateClose SMAMethod (Queue<Models.DateClose> queue, int period)
{
decimal average, sum=0;
Models.DateClose dateClose = null;
for (int i = 0; i < period; i++)
{
dateClose = queue.Dequeue();
if(dateClose != null)
sum += dateClose.Close;
}
average = sum/period;
dateClose.Close = average;
return dateClose;
}
Why do you get this error:
if you have the class, member variables neednot be initialized:
public class Test
{
private int temp; // this is okay.
..
}
However, if you have a local variable, then you need to initialize them:
public void Method()
{
int variabl;
sum += variable; // error.
}
So, local variables need to be initialized but member variables neednt be.

Member cannot be accessed with an instance reference; qualify it with a type name [duplicate]

This question already has answers here:
Member '<member name>' cannot be accessed with an instance reference
(11 answers)
Closed 5 years ago.
Today I was working on c sharp and I'm trying out static classes, but it doesn't seem to work for me and I would love to know the solution.
I have been browsing around the web for a while now but I can't seem to find the answer.
Here is my code:
class Count
{
public static int sum(int add1, int add2)
{
int result = add1 + add2;
return result;
}
}
class Program
{
static void Main(String[] args)
{
Console.WriteLine("Adding: \nPlease enter the first number");
int num1 = int.Parse(Console.ReadLine());
Console.WriteLine("Please enter the second number");
int num2 = int.Parse(Console.ReadLine());
Count add = new Count();
int total = add.sum(num1, num2);
Console.WriteLine("The sum is {0}.", total);
Console.ReadLine();
}
}
sum is not an instance method, it must be accessed via its type. Replace this:
Count add = new Count();
int total = add.sum(num1, num2);
With this:
int total = Count.sum(num1, num2);
If you're trying to use static classes - mark the Count class as static - like so:
public static class Count
and then use the following in your code:
int total = Count.sum(num1, num2);
And it should work as expected.

Return multiple values from one method C# [duplicate]

This question already has answers here:
Return multiple values to a method caller
(28 answers)
Closed 7 years ago.
Apologies on the duplicate question, I viewed similar Qs and just got confused. I have a method that is prompting a user to enter 5 different attribute values and would like to return the values chosen to be used for later decisions in the program.
while (true)
{
Console.Write("Please enter a value between 0-10 for ingenuity: ");
inputIngenuity = Console.ReadLine();
if (!UInt32.TryParse(inputIngenuity, out validIngenuity))
{
Console.WriteLine();
Console.WriteLine("Input was not a valid value for ingenuity.");
}
else if (validIngenuity < 0 || validIngenuity > 10)
{
Console.WriteLine();
Console.WriteLine("Input was not a valid value for ingenuity.");
}
else if (validIngenuity > (attributePoints - validStrength - validIntelligence - validPersonality - validSpeed))
{
Console.WriteLine();
Console.WriteLine("You do not have enough attribute points remaining.");
}
else break;
}
Console.WriteLine();
Console.WriteLine("You have " + (attributePoints - validStrength - validSpeed - validPersonality - validIntelligence - validIngenuity) + " attribute points remaining");
Console.WriteLine();
Console.WriteLine(String.Format("Strength Value = {0}", validStrength));
Console.WriteLine(String.Format("Speed Value = {0}", validSpeed));
Console.WriteLine(String.Format("Intelligence Value = {0}", validIntelligence));
Console.WriteLine(String.Format("Personaility Value = {0}", validPersonality));
Console.WriteLine(String.Format("Ingenuity Value = {0}", validIngenuity));
Console.WriteLine();
Console.WriteLine("These are your attributes!");
while (true)
{
Console.Write("Do you accept these? Type 1 for Yes, Type 2 for No. If No then choose again: ");
areYouHappyWithChoices = Console.ReadLine();
if (!UInt32.TryParse(areYouHappyWithChoices, out validChoices))
Console.WriteLine("Please try again. Enter 1 for Yes and 2 for No");
else if (validChoices > 2 || validChoices < 1)
Console.WriteLine("Please try again. Enter 1 for Yes and 2 for No");
else if (areYouHappyWithChoices == "2")
chooseAttributePoints(); //this method contains the whole routine
else
Console.WriteLine("We may now begin the game!");
break;
}
UInt32[] attributePointArray = new UInt32[5] { validStrength, validSpeed, validIntelligence, validPersonality, validIngenuity };
return attributePointArray;
The while statement for ingenuity is repeated in the method for the other 4 attributes and works without issues. I'm envisioning later code that would have different results based on how strong the user is for example. Am I going in the right direction by trying to put the values into an array? Thank you.
That would be one way to do it, however I think you'd be better off having a class or struct created to represent the data. This way you'll keep the "strong typey ness" and context of what your data is, rather than simply an array index.
example:
public class Person
{
public int Strength { get; private set; }
public int Speed { get; private set; }
public int Intel { get; private set; }
public int Personality { get; private set; }
public int Ingenuity { get; private set; }
public Person (int strength, int speed, int intel, int personality, int ingenuity)
{
this.Strength = strength;
this.Speed = speed;
this.Intel = intel;
this.Personality = personality;
this.Ingenuity = ingenuity;
}
}
Then your assignment to array:
UInt32[] attributePointArray = new UInt32[5] { validStrength, validSpeed, validIntelligence, validPersonality, validIngenuity };
return attributePointArray;
Gets updated to:
return new Person(validStrength, validSpeed, validIntelligence, validPersonality, validIngenuity);
and your return type needs to be changed from uint[] to Person
This way, rather than having to remember that returnedArray[1] is Speed (or whatever) - you would simply use returnedPerson.Speed.
You should create an object type that wraps the attributes you want to return. The return type of your method will be your newly-created object type.

inputs in methods at visual c# 2005

I am facing a problem in creating a console application in Visual Studio c# 2005
I created the following program in which a method (to sum 2 predefined values) is called in the program
here is the code of it
class program
{
static void Main()
{
program a;
a = new program();
Console.WriteLine(a.am1(1,2));
Console.ReadLine();
}
int sum;
public int am1(int num1, int num2)
{
sum = num1 + num2;
return sum;
}
}
Now here is the main problem I am facing, well in this program two integers (num1 and num2) are predefined, I wanted those 2 numbers to be taken from user, means user input the two numbers and then the same program goes on like above. How it should be done?
P.S remember everything should be done in methods
i hope i got your requirements ... if not, please elaborate!
public sealed class Program
{
private readonly int _number1;
private readonly int _number2;
public Program(int number1, int number2)
{
this._number1 = number1;
this._number2 = number2;
}
public int Sum()
{
return this._number1 + this._number2;
}
public static void Main(string[] args)
{
// this one here is really brutal, but you can adapt it
int number1 = int.Parse(args[0]);
int number2 = int.Parse(args[1]);
Program program = new Program(number1, number2);
int sum = program.Sum();
Console.WriteLine(sum);
Console.ReadLine();
}
}
sry, this is not my main coding style ... pfuh ... really ugly!
edit:
don't give blind trust in int.Parse(). the params are coming from the user, you better double check them!
you better triple check them, as you are doing a sum ... thankfully c# compiles with unchecked - this code may fail with an OverflowException if compiled in vb - remember ranges of int
why do you want to do a simple addition in an extra class?
you should elaborate your style (regarding your comment): separate ui-code from business-layer code!
you do not need to create an instance variable for each task - you can do that with scope variables too...!
...
Use console application command line arguments. If it suites you. Below is an example from MSDN.
public class Functions
{
public static long Factorial(int n)
{
// Test for invalid input
if ((n < 0) || (n > 20))
{
return -1;
}
// Calculate the factorial iteratively rather than recursively:
long tempResult = 1;
for (int i = 1; i <= n; i++)
{
tempResult *= i;
}
return tempResult;
}
}
class MainClass
{
static int Main(string[] args)
{
// Test if input arguments were supplied:
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
System.Console.WriteLine("Usage: Factorial <num>");
return 1;
}
// Try to convert the input arguments to numbers. This will throw
// an exception if the argument is not a number.
// num = int.Parse(args[0]);
int num;
bool test = int.TryParse(args[0], out num);
if (test == false)
{
System.Console.WriteLine("Please enter a numeric argument.");
System.Console.WriteLine("Usage: Factorial <num>");
return 1;
}
// Calculate factorial.
long result = Functions.Factorial(num);
// Print result.
if (result == -1)
System.Console.WriteLine("Input must be >= 0 and <= 20.");
else
System.Console.WriteLine("The Factorial of {0} is {1}.", num, result);
return 0;
}
}
// If 3 is entered on command line, the
// output reads: The factorial of 3 is 6.

Categories

Resources