C# Recursive Increment Decrement not working as parameters - c#

I am using recursion to add two numbers together, By adding 1 to the first input one at a time until I have reached the value of the second.
Why does this work...
private static int AddMethod(int input1, int input2)
{
if (input2 == 0)
{
Console.WriteLine(input1);
return (input1);
}
else
{
input1++;
input2--;
return AddMethod(input1, input2);
}
}
But not this..
private static int AddMethod(int input1, int input2)
{
if (input2 == 0)
{
Console.WriteLine(input1);
return (input1);
}
else
{
return AddMethod(input1++, input2--);
}
}
I am using Visual Studio 2010 and .Net 4.0

Because return AddMethod(input1++, input2--); first passes your inputs, and THEN increments and decrements.
Try
return AddMethod(++input1, --input2);

Post fix increment works by first "assigning" the value, then incrementing the value.
Compare:
int a = 1;
int b = 1;
int x = a++;
int y = ++b;
So in your case, the value you pass to AddMethod is the unchanged value, it modifies the value of input1 and input2 after they are passed.

Because the ++ and -- operators are executed after passing the values as parameters to the function.
Your code:
return AddMethod(input1++, input2--);
Is equal to:
int result AddMethod(input1, input2);
input1++;
input2--;
return result;
Instead of all this, you could use:
return AddMethod(++input1, --input2);

Related

How to make a counter based on user response?

I'm trying to make a counter that will increment based on the response of the user. Here's the code I got so far:
string ok = "";
int z = 0;
test(ok, z);
test1(ok, z);
Console.WriteLine(z);
}
static void test(string ok, int z)
{
bool estok = false;
while (!estok)
{
ConsoleKeyInfo saisie = Console.ReadKey(true);
if (saisie.Key == ConsoleKey.A || saisie.Key == ConsoleKey.B)
{
estok = true;
if (saisie.Key == ConsoleKey.A)
{
z++;
}
if (saisie.Key == ConsoleKey.B)
{
z--;
}
}
else
{
estok = false;
Console.WriteLine("Error");
}
}
}
static void test1(string ok, int z)
{
bool estok = false;
while (!estok)
{
ConsoleKeyInfo saisie = Console.ReadKey(true);
if (saisie.Key == ConsoleKey.A || saisie.Key == ConsoleKey.B)
{
estok = true;
if (saisie.Key == ConsoleKey.A)
{
z++;
}
if (saisie.Key == ConsoleKey.B)
{
z--;
}
}
else
{
estok = false;
Console.WriteLine("Error");
}
}
}
I got 2 functions (test and test1) that both increment the int z. The Console.WriteLine(z) will return me 0, in place of the 2 i'm waiting for (when the user has 2 correct answers).
I figured that the increment won't happen since it's in the function and that the Console.WriteLine(z) can't reach the z++. How can I change that ?
How can I get the result from these?
int and other primitive types are passed by value by default where as reference types (think instances of a class) are passed by reference; this is what allows changes to the parameter to be persisted after the method returns. The way you are updating the value of the parameter, you'll need to pass z by reference.
static void test(string ok, int z)
becomes
static void test(string ok, ref int z)
and the call test(ok, z); becomes test(ok, ref z);
You can learn more about passing values by reference from the C# Language Reference
method parameters for int are of value types and not reference type, as far as I understood from your question, you may need to use out keyword in the method call or return from the method you have.
int z1= z;
test(ok, out z1);
int z2=z;
test1(ok, out z2);
and the method declaration also will have to be changed to
static void test(string ok, out int z)
static void test1(string ok, out int z)
OR you can simply put a Console.WriteLine(z) in the method test and test1 directly.

Not all code paths return a value with a while loop [duplicate]

This question already has answers here:
.NET compiler and "Not all code paths return a value"
(5 answers)
Closed 4 years ago.
The compiler is complaining that the following code snippet won't always return. I have inspected it and don't see an issue.
private int MyFunction(int b)
{
int result = -1;
while (result != 1)
{
result = MySmallFunction(out var x);
if (result == 1)
{
return x;
}
}
}
private int MySmallFunction(out int x)
{
x = 1;
return 1;
}
MySmallFunction does stuff and returns a code, 1 meaning success, and the rest is an error code.
If it returns 1, that means that the out int x has a value.
If the return value is not 1 (error code), then I want to retry.
If MySmallFunction never returns 1, the application should just be stuck in a loop forever. That shouldn't be a problem for the compiler.
I rewrote the function to this:
private int MyFunction()
{
int result = -1;
int x = int.MinValue;
while (result != 1)
{
result = MySmallFunction(out x);
}
return x;
}
private int MySmallFunction(out int x)
{
x = 1;
return 1;
}
Now x will only be returned if MySmallFunction returns a status code of 1.
In the case that your while loop doesn't trigger, there is not return instruction, you need a return at the bottom of your function outside the while loop.
As per the signature of the method MyFunction() it should return a value to the calling method in all conditions. but in your case, you are returning a value only if (result == 1) in all other case it is invalid, so you have to add a return at the end, which will return an integer. So you have to change something like this:
private int MyFunction(int b)
{
int result = -1;
while (result != 1)
{
result = MySmallFunction(out var x);
if (result == 1)
{
return x;
}
}
return 0;
}

"not all code paths return a value" Can anybody point me in the right direction?

I am pretty new to coding and I am getting this error ("not all code paths return a value") with the code below. Any help will be appreciated. Thanks
private int SelectCourse(string message)
{
int len = _courses.Count;
int index = -1;
if (len > 0)
{
for (index = 0; index < len; ++index)
{
Console.WriteLine($"{index + 1}. {_courses[index].Title}");
}
Console.Write(message);
string selection = Console.ReadLine();
while (!int.TryParse(selection, out index) || (index < 1 || index > len))
{
Console.Write("Please make a valid selection: ");
selection = Console.ReadLine();
}
--index;
}
--index;
}
When you define a method, you basically declare the elements of its structure. The syntax for defining a method in C# is as follows:
<Access Specifier> <Return Type> <Method Name>(Parameter List)
{
Method Body
}
Return type: A method may return a value. The return type is the data
type of the value the method returns. If the method is not returning
any values, then the return type is void.
In your example method looks like this:
private int SelectCourse(string message)
as you can see access specifier is private, and return type is an integer, so that basically means that your method needs/must to return a value of type int.
So to solve your issue, you need to put a :
return --index;
just before last curly bracket, because index is type of int as your method return type is, and there will be no issues anymore.
You never return in your function and it should return an int. An option would be to set the return type to void so you don't have to return anything. But if your function really needs to return something then you have to fix your code and decide where you want to return (and what).
If index is the value you want to return, this will do it:
private int SelectCourse(string message)
{
int len = _courses.Count;
int index = -1;
if (len > 0)
{
for (index = 0; index < len; ++index)
{
Console.WriteLine($"{index + 1}. {_courses[index].Title}");
}
Console.Write(message);
string selection = Console.ReadLine();
while (!int.TryParse(selection, out index) || (index < 1 || index > len))
{
Console.Write("Please make a valid selection: ");
selection = Console.ReadLine();
}
return --index;
}
return --index;
}
Refer to:
c# returning error "not all code paths return a value"
Every way the code can possible "go" it must eventually return some value. If you do not want it to return a value change your header from
private int SelectCourse(string message)
to
private void SelectCourse(string message)
When you write the signature of the function as follows:
private int SelectCourse(string message), you are making an agreement with the compiler that this function is guaranteed to return an integer. Given that there are no return statements in your function implementation, the compiler is complaining because you have broken the agreement.
Two suitable solutions are either return the index at some point (IE return index at appropriate places in your code) OR make the function a void type which does not allow any data to be returned at all (IE private void SelectCourse(string message))
As simple as, you have mentioned a return type in the method signature but in the method code, one/more paths not doing/giving any return value. So make sure you have specified "return something;" in all the execution paths possible in your method's code.
You should have return value.
private int SelectCourse(string message)
{
int len = _courses.Count;
int index = -1;
if (len > 0)
{
for (index = 0; index < len; ++index)
{
Console.WriteLine($"{index + 1}. {_courses[index].Title}");
}
Console.Write(message);
string selection = Console.ReadLine();
while (!int.TryParse(selection, out index) || (index < 1 || index > len))
{
Console.Write("Please make a valid selection: ");
selection = Console.ReadLine();
}
--index;
}
--index;
//you should have a return value here
}
This part of code does not return a type int variable. So you have to add the return command Like this return --index; in every possible returning of the index value. In case you don't want to return something you have to change the declaration of your method from:
This---->private int SelectCourse(string message)
to
This ---->private void SelectCourse(string message)

How to use static methods in c#

Why do the following codes return 1,1,1 instead of 1,2,3? I'd like to keep the int tempvalue so that I can use it somewhere else. And It works if I call Console.WriteLine(count()) directly.
class Program
{
private static int start = 0;
static void Main(string[] args)
{
int temp = count();
Console.WriteLine(temp);
temp = count();
Console.WriteLine(temp);
temp = count();
Console.WriteLine(temp);
}
static int count()
{
return start + 1;
}
}
If you expect the count to return a value that increments at each call, you should store the modified value back in the variable :
static int count()
{
start = start + 1;
return start;
}
Ndech's code will perform the desired output from your (modified) question, the reason you're seeing 1,1,1 each time is due to:
static int count()
{
return start + 1;
}
When start = 0, if you return start + 1 each time you call count(), then each time it's going to be 0+1. the code example provided by Ndech will do:
start = 0; // before first console.write
count();
start = 1; // first console.write
count();
start = 2;
etc...
another way this could be written is:
static int count()
{
return ++start; // take the current value of start, and add one to it.
}

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