Double scripted array as an lvalue - c++

I was wondering, how would i express it in code?
rand() % 2 == 0 ? map[x][y] = 'm' : map[x][y] = 'M';
when I compile that line in g++, it doesn't give an error. However gcc tells me I need an lvalue left of the assignment statement. I thought maybe I should give them an integer
int i = rand() % 2 ? .......
but that also gives me an error. Can someone please help? Thanks

(See here)
From the accepted answer in that post, you can see in C it would evaluate as:
((rand() % 2 == 0) ? map[x][y] = 'm' : map[x][y]) = 'M';
And the statement on the left is not a proper L-value.
You could rewrite this as:
map[x][y] = rand() % 2 == 0 ? 'm' : 'M';
rand() % 2 == 0 ? (map[x][y] = 'm') : (map[x][y] = 'M'); // This should work in C, but I do not have gcc handy to verify

You need a lvalue to use the expression the way you did. It's used for assignment like:
bool isFull= (candiesEaten>10) ? true : false;
What you wrote is:
if(rand() % 2 == 0){
=map[x][y] = 'm';
}else{
=map[x][y] = 'M';
}
I hope you get the point. The more general format would be:
lvalue= (statement)? val1 : val2;
and it would actually be:
if(statement){
lvalue= val1;
}
else{
lvalue= val2;
}

Related

What does this C++ for-loop expression mean?

I am working through the "Add Binary" problem on leetcode and a solution which I found online is the following:
#include <string>
using std::string;
class Solution {
public:
string addBinary(string a, string b) {
string ret;
bool carry{false};
for (auto apos=a.size(), bpos=b.size(); apos || bpos || carry; ) {
bool abit{apos && a[--apos] == '1'};
bool bbit{bpos && b[--bpos] == '1'};
ret = (abit ^ bbit ^ carry ? "1" : "0") + ret;
carry = abit + bbit + carry >= 2;
}
return ret;
}
};
My question is regarding the for loop above. I understand that two iterations are being instantiated with the first two expressions that are separated by a comma. However, I don't understand how the three units being or'd (ie: ||) is supposed to behave. I'm also curious why it's ok to exclude the iterator expression in this instance, ie the final expression in the for-loop.
Please help me to understand how this code functions.
basically the for loop consist of 3 parts separted by ';'(semi-colon)
1)first part, this part is about initialization of variables, again you can leave it if you want
2)second part, it defines the condition on basis of which for loop will keep running, again you can leave it if you want
3) third part, this is the part where you want to do some operations, conventially iteration value is increment, but again you can leave it if you want
so if you go with this model, I think you can easily break down what is happening in the for loop that you mentioned.
Sometimes it helps to consider the equivalent while loop:
for (auto apos=a.size(), bpos=b.size(); apos || bpos || carry; /*no increment*/) {
// ...
}
->
{
auto apos = a.size();
auto bpos = b.size();
while( apos || bpos || carry ) {
bool abit{apos && a[--apos] == '1'};
bool bbit{bpos && b[--bpos] == '1'};
ret = (abit ^ bbit ^ carry ? "1" : "0") + ret;
carry = abit + bbit + carry >= 2;
/* increment would be here*/
}
}
The loop initializes apos and bpos and continues to loop as long as the condition apos || bpos || carry yields true, ie as long as apos, bpos and carry are not all 0 (0 is converted to false any other number to true).

Trying to use a conditional and return at the same time but it doesn't work

I'm trying to do this:
(number % 2 == 0) ? return 1 : return 0;
But it doesn't work, does someone know why?
You should write this way:
return (number % 2 == 0) ? 1 : 0;

shorthand c++ if else statement

So I'm just curious if there is a short hand statement to this:
if(number < 0 )
bigInt.sign = 0;
else
bigInt.sign = 1;
I see all these short hand statements for if a < b and such.
I'm not sure on how to do it properly and would like some input on this.
Thanks!
I actually just figured it out right before you guys had answered.
The shortest solution is bigInt.sign = (number < 0) ? 0 : 1
The basic syntax for using ternary operator is like this:
(condition) ? (if_true) : (if_false)
For you case it is like this:
number < 0 ? bigInt.sign = 0 : bigInt.sign = 1;
try this:
bigInt.sign = number < 0 ? 0 : 1
Yes:
bigInt.sign = !(number < 0);
The ! operator always evaluates to true or false. When converted to int, these become 1 and 0 respectively.
Of course this is equivalent to:
bigInt.sign = (number >= 0);
Here the parentheses are redundant but I add them for clarity. All of the comparison and relational operator evaluate to true or false.
Depending on how often you use this in your code you could consider the following:
macro
#define SIGN(x) ( (x) >= 0 )
Inline function
inline int sign(int x)
{
return x >= 0;
}
Then you would just go:
bigInt.sign = sign(number);
you can also try this :
bigInt.sign = (number<0)*0 + (number>=0)*1;
If we need to assign another value other than 0 and 1 then this code can be used like :
bigInt.sign = (number<0)*(replacement_of_0) + (number>=0)*(replacement_of_1);

Equality comparison in if-statement

Sorry about this question, this is my first C++ project and I'm a little confused. I'm asking the user to input 3 separate things. For example, I'm starting off with a number, 80. I'm asking the user 3 questions. 1) Do you like blue or yellow? Type 1 for blue, 2 for yellow. If the user enters 1 for blue, multiply the number 80 by 2. If they enter 2 for yellow, multiply 80 by 3.
Can somebody let me know if this looks like it's on the right track? Thanks and sorry again for the beginner question.
cout << "Please enter a color blue or yellow. Type 1 for Blue, 2 for Yellow";
cin >> bp1;
// Multiply by 2 if Blue is chosen, 3 if Yellow is chosen.
if (bp1 = 1)
num = num*2;
if (bp1 = 2)
num = num*3;
There is a problem in your if statement
it must be like this :
if (bp1 == 1)
num = num*2;
if (bp1 == 2)
num = num*3;
Welcome to the world of C++! You're definitely on the right track, but there a couple of problems. First, the operator you use in your if statements is the assignment operator, so your statements will always return true. This should actually be the comparison operator (==). Second, I recommend the use of an if-else if statement here, as you may not need to check both times. The following should be sufficient:
if(bp1 == 1)
{
num = num * 2;
}
else if(bp1 == 2)
{
num = num * 3;
}
you meant to write compare operator ==
if (bp1 == 1)
if (bp1 == 2)
// ^^
if (bp1=1) will always be evaluated to true from operator=
Even simpler:
Instead of:
if(bp1 == 1)
num = num * 2;
else if (bp1 == 2)
num = num * 3;
you can write this
num = num * (bp + 1)
or even
num *= (bp + 1)

Multiple conditions in if statement

No matter what number is generated here I always get the first option (penguins). I can't seem to see any problem with my code, anyone else see what's wrong?
{
srand(time(0));
prand = (rand() % 20);
if (prand == 1,5,9,10,14,15,19,20){
entity = "penguins";
srand(time(0));
pquantity = (rand() % 8) + 2;
}
else if (prand == 2,6,11,16,18){
entity = "troll";
pquantity = 1;
}
else if (prand == 3,7,12,17){
entity = "goblin";
pquantity = 1;
}
else if (prand == 4,8,13){
entity = "wizard";
pquantity = 1;
}
}
The code fragment prand == 1,5,9,10,14,15,19,20 is a sequence of expressions (the , is usually know as the comma operator), where the result of the first (or last — depending on language) expression only is used as a condition for the if statement. The remaining expressions are evaluated and their value is forgotten (please note this may lead to serious side effects in more complex situations.)
It's not very clear what language you are using, but in, say, C# you could use a switch statement to achieve what you want:
switch (prand)
{
// first set of options
case 1:
case 5:
…
case 20:
// your code here
break;
// second set of options
case 2:
case 6:
…
case 18:
// your code here
break;
default:
// all other options not listed above
break;
}
Most languages have such a statement. See this wikipedia article for a general description.
You're misusing the comma operator. The expression in the first
if is:
if ( (prand == 1), (5), (9), (10), (14), (15), (19), (20) )
with each of the commas a comma operator. The definition of
a comma operator is to evaluate the first expression (for
possible side effects), then evaluate the second; the value of
the expression is the value of the second expression. So your
if becomes the exact equivalent of:
if ( 20 )
And 20 is implicitly converted to a bool, resulting in
true.
Your compiler should have warned you about this. Something to
the effect of a useless expression.
if (prand == 1,5,9,10,14,15,19,20)
Although this is valid C++ and will compile, it does not do what you expect. You need to compare the variable to each value in turn:
if (prand == 1 || prand == 5 || prand == 9 || prand == 10 || prand == 14 || prand == 15 || prand == 19 || prand == 20)
This is because == is a binary operator which takes two values of compatible types.
In this situation, a switch...case statement is preferred as #Ondrej has explained.
I can think of at least two alternative ways to simulating a dice roll (which it appears you are trying to do:
Use consecutive values for each option:
if (prand >= 1 && prand <= 8) {
// ...
} else if (prand >= 9 && prand <= 13) {
// ...
} else if (prand >= 14 && prand <= 17) {
// ...
} else if (prand >= 18 && prand <= 20) {
// ...
} else {
// Print an error message
}
Store the different possibilities in a std::list<std::set<int>>. Then you can iterate over the sets in the list and use the std::set.contains() method to check if the current set contains the value. This has the advantage of scalability. For example, it makes it easier to code the choices for 1d100 or other dice rolls with a large number of possible values.
If it is "C" then You are testing the result of a comma operator. So the result of prand == 1,5,9,10,14,15,19,20, is the last element (BTW the first element is prand == 1). It is 20 which is always true.
I would suggest to build an array and check its elements...
enum Being_t {BEING_PENGUIN, BEING_TROLL, BEING_GOBLIN, BEING_WIZARD};
enum Being_t arr[20] = {BEING_PENGUIN, BEING_TROLL, BEING_GOBLIN, BEING_WIZARD,
BEING_PENGUIN, BEING_TROLL, BEING_GOBLIN, BEING_WIZARD, ...};
Then You can use a switch
srand(time(0));
prand = (rand() % 20);
switch (arr[prand]) {
case BEING_PENGUIN:
...
break;
...
}
You should use or's or switch statements. For example, with if
if (prand == 1 || prand == 5 || prand == 9 || prand == 10 || prand == 14|| prand == 15|| prand == 19|| prand == 20)
{
// your code here
}
and with switch
switch (prand)
{
case 1:
{
// your code here
break;
}
case 5:
{
// your code here
break;
}
case 9:
{
// your code here
break;
}
case 10:
{
// your code here
break;
}
case 14:
{
// your code here
break;
}
case 15:
{
// your code here
break;
}
case 19:
{
// your code here
break;
}
case 20:
{
// your code here
break;
}
}