Code:
BOOL CCreateReportDlg::CanSwapBrothers()
{
BOOL b1in2 = FALSE, b2in1 = FALSE;
CStringArray aryStrNames;
// Must have valid data
if (!IsSwapBrotherInit())
return FALSE;
// Get cell pointers
auto pCell1 = GetSwapBrotherCell(1);
auto pCell2 = GetSwapBrotherCell(2);
if (pCell1 != nullptr && pCell2 != nullptr)
{
// Look for brother (cell 1) in cell 2 array
auto strName = pCell1->GetText();
pCell2->GetOptions(aryStrNames);
const auto iNumNames = aryStrNames.GetSize();
for (auto iName = 0; iName < iNumNames; iName++)
{
if (aryStrNames[iName] == strName)
{
b1in2 = TRUE;
break;
}
}
if (b1in2)
{
// Look for brother (cell 2) in cell 1 array
auto strName = pCell2->GetText();
pCell1->GetOptions(aryStrNames);
const auto iNumNames = aryStrNames.GetSize();
for (auto iName = 0; iName < iNumNames; iName++)
{
if (aryStrNames[iName] == strName)
{
b2in1 = TRUE;
break;
}
}
}
}
return b1in2 && b2in1;
}
The line of interest is the return statement:
return b1in2 && b2in1;
I am getting a code analysis warning:
lnt-logical-bitwise-mismatch
Using logical && when bitwise & was probably intended.
As far as I am concerned my code is correct. Why is this being raised?
The compiler sees && applies to integer operands and an implicit conversion of the result to an integer type. BOOL has multiple bits; it isn't the same as the built-in type bool.
As noted in the page you linked to, "A logical operator was used with integer values" will cause this warning and that condition is certainly present here.
"MFC" coding styles violate modern recommendations in a lot of ways, using a non-standard boolean type is just one of the smaller issues. CStringArray is also a code smell, modern C++ uses templated containers and has powerful algorithms for manipulating them, you never should be writing search code yourself.
I want to make coding about the final score display. If someone has done 10 multiple choice questions and he clicks on the final score button, then his final score will appear along with the description. The score will be made in a range according to the category, namely 1-59 = Under Average, 60-79 = Average, and 80-100 = Above Average.
I've tried coding it but I found error 1176 on line 7 and 11.
Can you help me fix it?
finalscorebutton.addEventListener(MouseEvent.CLICK, finalscore);
function finalscore(event:MouseEvent):void
{
multiplechoicefinalscore.text = sumofscores;
var finalscore:String = finalscore.toString;
finalscore = multiplechoicefinalscore..text;
if(finalscore.toString < 60){
description.text =
"UNDER AVERAGE.";
}
else if(finalscore.toString >= 60 && finalscore.toString <=79){
description.text =
"AVERAGE.";
}
else{
description.text =
"ABOVE AVERAGE.";
}
}
There are multiple syntax and logic errors.
Something.toString is a reference to a method, you probably mean Something.toString() which calls the said method and returns a text representation of whatever Something is.
You don't need a text representation because you want to compare numbers, you need a numeric representation (which is either int, uint or Number).
There are 2 dots in multiplechoicefinalscore..text, what does it even mean?
There is function finalscore and then you define var finalscore, defining things with the same names is a bad idea in general.
You should keep your script formatted properly, otherwise reading it and understanding would be a pain.
So, I assume you have the user's result is in sumofscores. I'm not sure if the script below will actually work as is, but at least it is logically and syntactically correct:
finalscorebutton.addEventListener(MouseEvent.CLICK, onFinal);
function onFinal(e:MouseEvent):void
{
// Ok, let's keep this one, I think you are putting
// the score result into some kind of TextField.
multiplechoicefinalscore.text = sumofscores;
// Get a definitely numeric representation of the score.
var aScore:int = int(sumofscores);
// In terms of logic, putting the complicated condition case
// under the "else" statement will simplify the program.
if (aScore < 60)
{
description.text = "UNDER AVERAGE.";
}
else if (aScore > 79)
{
description.text = "ABOVE AVERAGE.";
}
else
{
description.text = "AVERAGE.";
}
}
int is_ter(int x)
{
//it is not a TWOs nor a FIVEs and not 1.0
g:
if(x%2 !=0 && x%5 !=0 && x!=1 )
return 0;
// make sure it is 1.0
if(x%2 !=0 && x%5 !=0 && x==1 )
return 1;
//check if it is a two
if(x%2==0){
x/=2;
goto g;
}
if(x%5==0)
{
x/=5;
goto g;
}
}
From the looks of it, you want to check whether 1/x is terminating or not.
Your code looks somewhat confusing. You'll want to check whether all your primefactors are 2 or 5:
int is_ter(unsigned int x)
{
while (x>1)
{
if (x%2==0) x=x/2;
else if (x%5==0) x=x/5;
else return 0;
}
return 1;
}
should do the trick (ok, it says 1/0 is terminating, whatever that means. It's going to terminate the program, so it's not exactly wrong...)
No, not at all.
First of all, your decimal is an int. Second, you should probably be multiplying instead of dividing. Third, when working with decimals, rounding errors occur all the time, so you need to take that into account when comparing decimals to something.
And most importantly, all decimals stored on a computer are 'terminating', because in a computer, a decimal fraction is not much more than a rational number M/N, with N being a power of 2.
You should do some reading about floating point numbers.
bool? x = true;
if (x == true)
looks awkward.
But sometimes that is exactly what is needed.
Is there a better way?
EDIT:
Thank you all for the attempts, but so far I have not found a way that would beat the original. I guess I will just need to deal with awkwardness, perhaps comment it.
Depending on your situation, you may want to use the null coalescing operator, which lets you specify the default value you'll use if the bool? is not set. It's not shorter than your conditional, but I think it's useful:
if(x ?? true) //defaults to true if x is not set
Or, to directly replicate your case (and due to popular demand):
if(x ?? false) //defaults to false if x is not set
if (x) is equivalent to if (x == true). There is no need to make an extra comparison since x is a boolean value.
Edit: Missed that is was nullable. In that case, it really is the best you can get unless you want to make a simple helper function.
bool isTrue(bool? value) {
return value == true;
}
But if (isTrue(x)) isn't much cleaner.
bool? x = true;
if (x.HasValue && x.Value)
{ /* Other code here */ }
or use GetValueOrDefault(), but this is no terser...
bool? x = true;
if (x.GetValueOrDefault(false))
{ /* Other code here */ }
Does C# 4.0 allow optional out or ref arguments?
No.
A workaround is to overload with another method that doesn't have out / ref parameters, and which just calls your current method.
public bool SomeMethod(out string input)
{
...
}
// new overload
public bool SomeMethod()
{
string temp;
return SomeMethod(out temp);
}
If you have C# 7.0, you can simplify:
// new overload
public bool SomeMethod()
{
return SomeMethod(out _); // declare out as an inline discard variable
}
(Thanks #Oskar / #Reiner for pointing this out.)
As already mentioned, this is simply not allowed and I think it makes a very good sense.
However, to add some more details, here is a quote from the C# 4.0 Specification, section 21.1:
Formal parameters of constructors, methods, indexers and delegate types can be declared optional:
fixed-parameter:
attributesopt parameter-modifieropt type identifier default-argumentopt
default-argument:
= expression
A fixed-parameter with a default-argument is an optional parameter, whereas a fixed-parameter without a default-argument is a required parameter.
A required parameter cannot appear after an optional parameter in a formal-parameter-list.
A ref or out parameter cannot have a default-argument.
No, but another great alternative is having the method use a generic template class for optional parameters as follows:
public class OptionalOut<Type>
{
public Type Result { get; set; }
}
Then you can use it as follows:
public string foo(string value, OptionalOut<int> outResult = null)
{
// .. do something
if (outResult != null) {
outResult.Result = 100;
}
return value;
}
public void bar ()
{
string str = "bar";
string result;
OptionalOut<int> optional = new OptionalOut<int> ();
// example: call without the optional out parameter
result = foo (str);
Console.WriteLine ("Output was {0} with no optional value used", result);
// example: call it with optional parameter
result = foo (str, optional);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
// example: call it with named optional parameter
foo (str, outResult: optional);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
}
There actually is a way to do this that is allowed by C#. This gets back to C++, and rather violates the nice Object-Oriented structure of C#.
USE THIS METHOD WITH CAUTION!
Here's the way you declare and write your function with an optional parameter:
unsafe public void OptionalOutParameter(int* pOutParam = null)
{
int lInteger = 5;
// If the parameter is NULL, the caller doesn't care about this value.
if (pOutParam != null)
{
// If it isn't null, the caller has provided the address of an integer.
*pOutParam = lInteger; // Dereference the pointer and assign the return value.
}
}
Then call the function like this:
unsafe { OptionalOutParameter(); } // does nothing
int MyInteger = 0;
unsafe { OptionalOutParameter(&MyInteger); } // pass in the address of MyInteger.
In order to get this to compile, you will need to enable unsafe code in the project options. This is a really hacky solution that usually shouldn't be used, but if you for some strange, arcane, mysterious, management-inspired decision, REALLY need an optional out parameter in C#, then this will allow you to do just that.
ICYMI: Included on the new features for C# 7.0 enumerated here, "discards" is now allowed as out parameters in the form of a _, to let you ignore out parameters you don’t care about:
p.GetCoordinates(out var x, out _); // I only care about x
P.S. if you're also confused with the part "out var x", read the new feature about "Out Variables" on the link as well.
No, but you can use a delegate (e.g. Action) as an alternative.
Inspired in part by Robin R's answer when facing a situation where I thought I wanted an optional out parameter, I instead used an Action delegate. I've borrowed his example code to modify for use of Action<int> in order to show the differences and similarities:
public string foo(string value, Action<int> outResult = null)
{
// .. do something
outResult?.Invoke(100);
return value;
}
public void bar ()
{
string str = "bar";
string result;
int optional = 0;
// example: call without the optional out parameter
result = foo (str);
Console.WriteLine ("Output was {0} with no optional value used", result);
// example: call it with optional parameter
result = foo (str, x => optional = x);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
// example: call it with named optional parameter
foo (str, outResult: x => optional = x);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
}
This has the advantage that the optional variable appears in the source as a normal int (the compiler wraps it in a closure class, rather than us wrapping it explicitly in a user-defined class).
The variable needs explicit initialisation because the compiler cannot assume that the Action will be called before the function call exits.
It's not suitable for all use cases, but worked well for my real use case (a function that provides data for a unit test, and where a new unit test needed access to some internal state not present in the return value).
Use an overloaded method without the out parameter to call the one with the out parameter for C# 6.0 and lower. I'm not sure why a C# 7.0 for .NET Core is even the correct answer for this thread when it was specifically asked if C# 4.0 can have an optional out parameter. The answer is NO!
For simple types you can do this using unsafe code, though it's not idiomatic nor recommended. Like so:
// unsafe since remainder can point anywhere
// and we can do arbitrary pointer manipulation
public unsafe int Divide( int x, int y, int* remainder = null ) {
if( null != remainder ) *remainder = x % y;
return x / y;
}
That said, there's no theoretical reason C# couldn't eventually allow something like the above with safe code, such as this below:
// safe because remainder must point to a valid int or to nothing
// and we cannot do arbitrary pointer manipulation
public int Divide( int x, int y, out? int remainder = null ) {
if( null != remainder ) *remainder = x % y;
return x / y;
}
Things could get interesting though:
// remainder is an optional output parameter
// (to a nullable reference type)
public int Divide( int x, int y, out? object? remainder = null ) {
if( null != remainder ) *remainder = 0 != y ? x % y : null;
return x / y;
}
The direct question has been answered in other well-upvoted answers, but sometimes it pays to consider other approaches based on what you're trying to achieve.
If you're wanting an optional parameter to allow the caller to possibly request extra data from your method on which to base some decision, an alternative design is to move that decision logic into your method and allow the caller to optionally pass a value for that decision criteria in. For example, here is a method which determines the compass point of a vector, in which we might want to pass back the magnitude of the vector so that the caller can potentially decide if some minimum threshold should be reached before the compass-point judgement is far enough away from the origin and therefore unequivocally valid:
public enum Quadrant {
North,
East,
South,
West
}
// INVALID CODE WITH MADE-UP USAGE PATTERN OF "OPTIONAL" OUT PARAMETER
public Quadrant GetJoystickQuadrant([optional] out magnitude)
{
Vector2 pos = GetJoystickPositionXY();
float azimuth = Mathf.Atan2(pos.y, pos.x) * 180.0f / Mathf.PI;
Quadrant q;
if (azimuth > -45.0f && azimuth <= 45.0f) q = Quadrant.East;
else if (azimuth > 45.0f && azimuth <= 135.0f) q = Quadrant.North;
else if (azimuth > -135.0f && azimuth <= -45.0f) q = Quadrant.South;
else q = Quadrant.West;
if ([optonal.isPresent(magnitude)]) magnitude = pos.Length();
return q;
}
In this case we could move that "minimum magnitude" logic into the method and end-up with a much cleaner implementation, especially because calculating the magnitude involves a square-root so is computationally inefficient if all we want to do is a comparison of magnitudes, since we can do that with squared values:
public enum Quadrant {
None, // Too close to origin to judge.
North,
East,
South,
West
}
public Quadrant GetJoystickQuadrant(float minimumMagnitude = 0.33f)
{
Vector2 pos = GetJoystickPosition();
if (minimumMagnitude > 0.0f && pos.LengthSquared() < minimumMagnitude * minimumMagnitude)
{
return Quadrant.None;
}
float azimuth = Mathf.Atan2(pos.y, pos.x) * 180.0f / Mathf.PI;
if (azimuth > -45.0f && azimuth <= 45.0f) return Quadrant.East;
else if (azimuth > 45.0f && azimuth <= 135.0f) return Quadrant.North;
else if (azimuth > -135.0f && azimuth <= -45.0f) return Quadrant.South;
return Quadrant.West;
}
Of course, that might not always be viable. Since other answers mention C# 7.0, if instead what you're really doing is returning two values and allowing the caller to optionally ignore one, idiomatic C# would be to return a tuple of the two values, and use C# 7.0's Tuples with positional initializers and the _ "discard" parameter:
public (Quadrant, float) GetJoystickQuadrantAndMagnitude()
{
Vector2 pos = GetJoystickPositionXY();
float azimuth = Mathf.Atan2(pos.y, pos.x) * 180.0f / Mathf.PI;
Quadrant q;
if (azimuth > -45.0f && azimuth <= 45.0f) q = Quadrant.East;
else if (azimuth > 45.0f && azimuth <= 135.0f) q = Quadrant.North;
else if (azimuth > -135.0f && azimuth <= -45.0f) q = Quadrant.South;
else q = Quadrant.West;
return (q, pos.Length());
}
(Quadrant q, _) = GetJoystickQuadrantAndMagnitude();
if (q == Quadrant.South)
{
// Do something.
}
What about like this?
public bool OptionalOutParamMethod([Optional] ref string pOutParam)
{
return true;
}
You still have to pass a value to the parameter from C# but it is an optional ref param.
void foo(ref int? n)
{
return null;
}