This question already has answers here:
Using Exclamation Marks '!' in C
(5 answers)
Closed 3 years ago.
I was reading a code and I found these "!" all over the place what is it supposed to do ? this is a part from the code I found it in :
if (!piocherMot(motSecret))
exit(0);
piocherMot is a function in another file while "motsecret" is a variable in my main code.
This
!
is logical NOT operator & its a unary operator i.e it takes only one operand, result of this operator is either true(1) or false(0). Truth table of logical NOT operator is
A !A
----------
| 0 | 1 |
| 1 | 0 |
----------
Hence if piocherMot(motSecret) results in true i.e !1 which is 0 then if block will not get executes, in reverse case it gets executes.
if(!1) { /* 0 i.e if block won't executes */
}
And
if(!0) { /* 1 i.e if blocks executes */
}
Related
I have seen something like this in some of my coworkers code today :
I2C1ADB1= (slave_read_address | 0x01);
What does this | 0x01 part do? Does it end 1 at the end of the bits?
Let's say I2C1ADB1=0b00000000. If I use above line, will the new I2C1ADB1 be 0b000000001? Will it also increase the bit count from 8 to 9?
'|' is bit-wise OR operator in C. It does bit-wise OR between two values and return the final value.
I2C1ADB1= (slave_read_address | 0x01);
Assume slave_read_address in binary is 0bxxxxxxxx where each x is bit value 1 or 0. Similarly, 0x01 in binary is 0x00000001.
As you know OR will return true (1) if at least one of the value is true (1). Otherwise returns false (0).
So After the above C line, I2C1ADB1 will have 0bxxxxxxx1.
The operator will not ADD bits. Usually '|' (OR) operator is used to set a particular set of bits without altering other bits.
The statement I2C1ADB1 = (slave_read_address | 0x01); stores the value of slave_read_address into I2C1ADB1, forcing the low order bit to 1.
Your interpretation is incorrect, the value is not shifted, no extra bit is appended. The lowest bit is set to 1:
0 becomes 1,
1 is unchanged,
2 becomes 3,
3 does not change,
4 becomes 5,
etc.
Because on the left you have a variable and on the right a constant the result is to set all the corresponding 1 bits from the constant in the variable. In this case you’re right: it sets the last bit. No bit count increase occur!
Having an issue with my parser and I just can't wrap my head around it. I keep getting the error: parser.y:79.33-41: symbol character is used, but is not defined as a token and has no rules. I've put the line in ** **.
Below is my parser code:
%token PLUS TIMES DIVIDE SUBTRACT BRA KET EQUALS NOT_EQUAL LESS_THAN GREATER_THAN GREATER_THAN_OR_EQUAL
%token COMA SEMICOLON ARROW DECIMAL ENDDO ENDFOR ENDIF ENDP ENDWHILE ELSE CODE OF TYPE DECLARATIONS CHARACTER
%token INTEGER REAL IF THEN DO WHILE FOR IS BY TO WRITE NEWLINE READ NOT AND OR ID LESS_THAN_OR_EQUAL APOSTROPHE
%%
Program : block
| ENDP
| ID
;
block : DECLARATIONS declaration_block CODE statement_list
| CODE statement_list
;
declaration_block : ID OF TYPE SEMICOLON
| ID_list OF TYPE SEMICOLON
| ID_list OF TYPE SEMICOLON declaration_block
;
ID_list : ID
| ID COMA ID_list
;
type : CHARACTER
| INTEGER
| REAL
;
statement_list : statement
| statement_list SEMICOLON statement
;
statement : assignment_statement
| if_statement
| do_statement
| while_statement
| for_statement
| write_statement
| read_statement
;
assignment_statement : expression ARROW ID
;
if_statement : IF conditional THEN statement_list ELSE statement_list ENDIF
;
do_statement : DO statement_list WHILE conditional ENDDO
;
while_statement : WHILE conditional DO statement_list ENDWHILE
;
for_statement : FOR ID IS expression BY expression TO expression DO statement_list ENDFOR
;
write_statement : WRITE BRA output_list KET write_statement NEWLINE
;
read_statement : READ BRA ID KET
;
output_list : value
| output_list COMA value
;
conditional : expression comparator expression
| NOT conditional
| expression comparator expression AND conditional
| expression comparator expression OR conditional
;
comparator : EQUALS
| NOT_EQUAL
| LESS_THAN
| GREATER_THAN
| LESS_THAN_OR_EQUAL
| GREATER_THAN_OR_EQUAL
;
expression : term
| expression PLUS term
| expression SUBTRACT term
;
term : value
| term TIMES value
| term DIVIDE value
;
value : ID
| constant
| BRA expression KET
;
constant : number_constant
| character_constant
;
**character_constant : APOSTROPHE character APOSTROPHE**
;
number_constant : INTEGER
| SUBTRACT INTEGER
| SUBTRACT INTEGER DECIMAL INTEGER
| INTEGER DECIMAL INTEGER
;
%%
Below is my lexical analyser:
%{
#ifdef PRINT
#define TOKEN(i) printf("Token: " #i "\n");
#else
#define TOKEN(i) return (i);
#endif
%}
delim [ \r\n\t]
ws {delim}+
digit [0-9]
character [a-zA-Z]
INTEGER {digit}+
id {character}({character}|{digit})*
character_constant ('{character}')
%%
{ws} ; /* Do Nothing */
"+" TOKEN(PLUS)
"*" TOKEN(TIMES)
"/" TOKEN(DIVIDE)
"-" TOKEN(SUBTRACT)
"(" TOKEN(BRA)
")" TOKEN(KET)
...
"'" TOKEN(APOSTROPHE)
ENDP TOKEN(ENDP)
CODE TOKEN(CODE)
OF TOKEN(OF)
TYPE TOKEN(TYPE)
DECLARATIONS TOKEN(DECLARATIONS)
character TOKEN(CHARACTER)
{INTEGER} TOKEN(INTEGER)
...
{id} TOKEN(ID)
{character_constant} TOKEN(character_constant)
%%
The spelling is correct throughout my files from my BNF to my parser, does anyone know what seems to be the issue here. I've tried changing it to letter instead of character but that just gives me another error.
The fault is that the single character cannot be differentiated from an identifier in the lexer. You have correctly added a lexer rule to match it which returns a token named character_constant, however you have also put a parser rule for character constant which is not needed, as its already matched in the lexer. The lexer should not be returning an APOSTROPHE as a token as it would have been matched in the character_constant token.
You should just delete the rule from bison for character_constant and add character_constant to the list of tokens matched by the lexer in the %token declaration.
I'd normally recommend using uppercase for the token names to avoid any ambiguity of which is a terminal and which a non-terminal.
The message means exactly what it says. You use the symbol character but you have neither declared it to be a token nor have you provided a production for it. So it is neither a terminal nor a non-terminal, and the parser generator complains when it is used.
What happens in your lexer is not visible to the parser generator. So the fact that you have (pointlessly, IMHO) created a lexer definition of {character} is only of interest inside the lexer file. (It's pointless because you could equivalently use the Posix character class [[:alpha:]] which has a clear meaning and is just as readable as {character}.) And really the parser doesn't need to know anything about how the lexer comes up with the token code value. So when you declare a token in the parser definition, the parser generator puts a definition for that symbol in a header file; the lexer #includes that header file, and that lets it use that symbol as a return value for the parser. No other communication is necessary.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I recently corrected a bug in a C program where I had:
if (foobar != FOO | BAR | BAZ)
The correct code is
if (foobar != (FOO | BAR | BAZ))
According to the C operator precedence it is clear that != has precedence over |.
My question is why it is like this and not the other way around? From my experience I will often use either a == b || a == c or d == (a | b | c), but never a == b | c == d.
What is the logic behind this choice?
It has historical reasons, quote from Dennis Ritchie:
“Early C had no separate operators for & and && or | and ||. Instead
it used the notion (inherited from B and BCPL) of ‘truth-value
context': where a Boolean value was expected, after ‘if‘ and ‘while‘
and so forth; the & and | operators were interpreted as && and || are
now; in ordinary expressions, the bit-wise interpretations were used.
It worked out pretty well, but was hard to explain. (There was the
notion of ‘top-level operators’ in a truth-value context.) “The
precedence of & and | were as they are now.
Primarily at the urging of
Alan Snyder, the && and || operators were added. This successfully
separated the concepts of bit-wise operations and short-circuit
Boolean evaluation. However, I had cold feet about the precedence
problems. For example, there were lots of programs with things like:
if (a==b & c==d) …
“In retrospect it would have been better to go
ahead and change the precedence of & to higher than ==, but it seemed
safer just to split & and && without moving & past an existing
operator.”
Dennis Ritchie's Development of the C Language covers this and other curious historical artifacts.
Basically, originally the language did not have the && and || operators -- just & and |, so you would write things like a == b | c == d. The precedence rules were designed based on that.
Later, the short ciruiting operators were added, but the precedence of the old operators was not revised.
I have used ternary operator before for a condition like if-else but here it's different i.e. not checking a condition before ?.
printf( "%d\n",10?0?5:11:12 );
Edited:
So,how will it evaluate 11 as by compiler because i don't see any condition before first ?.
The expression 10 ? 0 ? 5 : 11 : 12 is parsed this way: 10 ? (0 ? 5 : 11) : 12. So this means that in the first test, since 10 is true, it will evaluate 0 ? 5 : 11, which evaluates to 11 since 0 is false.
It will be solved in this manner
printf("%d\n",10?0?5:11:12);
i.e 10?(0?5:11):12
First solve 0?5:11 as 0 means false so it will return 11.
Now Condition will be like 10?11:12
As 10 is non zero condition will be true, so it will return 11.
printf( "%d\n",10?0?5:11:12 ); is of syntax (condition)?TRUE:FALSE
There are two ternary operators. For better readibility and understanding, let's put it this way
(10 ? (0 ? 5 : 11) : 12)
So, the inner condition, (0 ? 5 : 11) checks whether 0 is TRUE or FALSE. It is a FALSE value, [yes, zero is considered as FALSE and non-zero value is considered as TRUE and both are perfectly valid sysntax for conditional check]. so , it evaluates to 11.
Now, for the outer condition, the code appears as (10 ? 11 : 12). Following simmilar logic, 10 being a TRUE, it returns 11. which is passed to printf(). That's how you get your output.
Your expression is parsed as 10?(0?5:11):12 and the inner conditional expression (0?5:11) is constant folded to 11 then the entire expression is constant folded to 11 (since 10 is true since non-zero).
Notice that a condition (such as the first test operand of a ?: ternary conditional expression) can be any scalar, non-void, expression. In particular 11 is a valid condition.
What is going on is in pseudo code a little bit:
(But in the ternary operator first the inner ternary condition get's "calculated")
if (10) { //true
if(0) { //false
print 5
} else {
print 11 //Output 11
}
} else {
print 12
}
Or as a ternary operator but a little bit more readable:
(10 ? (0 ? 5 : 11) : 12)
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
Someone showed me the following code snippet and asked what it meant:
if (!pFCT->FBMap(| ( VBQNum - 1 ) / 8 |) & (1 << (7 - ( ( VBQNum - 1 ) % 8)))))
{
stuff
}
And I got stuck on the stand alone vertical bars. I know two together mean "or" but just one, what does that mean.
One bar by itself means "bitwise OR" (as opposed to the double bar which means "Logical OR")
1 | 1 == 1
0 | 1 == 1
1 | 0 == 1
0 | 0 == 0
true || true == true
false || true == true
01 | 10 == 11
01 || 10 == true
However, the vertical bars in your sample, as far as I can tell, are syntax errors. It looks like the author is going for "absolute value", which would use vertical bars – in writing or pseudo-code – but not in any computer language I know of.
if (!pFCT->FBMap(| ( VBQNum - 1 ) / 8 |) & (1 << (7 - ( ( VBQNum - 1 ) % 8))))) { stuff }
/* ^^^ syntax error ^^^ */
I guess whoever showed you the line in question meant absolute value
if (!pFCT->FBMap(abs( ( VBQNum - 1 ) / 8 )) & (1 << (7 - ( ( VBQNum - 1 ) % 8))))) { stuff }
/* ^^^^^^ ^^^ */
Oh! A single vertical bar means bitwise or.
Bitwise inclusive or:
The bitwise-inclusive-OR operator compares each bit of its first operand to the corresponding bit of its second operand. If either bit is 1, the corresponding result bit is set to 1. Otherwise, the corresponding result bit is set to 0.
Source.
It is a bitwise OR.
Essentially it takes the two values and ORs each of the corresponding bits in their binary representations:
10010001
01001010
--------
11011011
If either operand's bit is a 1, the answer's bit in that place is a one. If neither are 1s, the answer has a 0 there.
It is a bitwise OR operator.
Dale said he knew it meant "or" with two operands. His question is what it means when used as a unary operator. Short answer is that it doesn't mean anything in C/C++.
In some languages (like Verilog for coding hardware) this is an or-reduction, which result in a 1 if any bit is one.
So I think this is a syntax error unless the is something funny going on overloading the parentheses that I can't get my head around.
Your code is not valid C, unless put in a specific (and quite artificial) context. Operator | is a binary operator. It is a bitwise-or, as you seem to know already. By itself, it cannot be used the way it is used in your code.
If one wanted to force this code to compile as C code, one'd probably have to define FBMap as a macro. Something like
#define FBMap(x) something_else(abs(0 x 0))
thus trying to emulate the mathematical "absolute value" operator | |. Your call will expand into
pFCT->something_else(abs(0 | ( VBQNum - 1 ) / 8 | 0))
thus making the application of | operator valid.
But even after that you'd need something_else to be a function pointer in that *pFCT struct, since the call looks awfully as a C++ method call. Your question is tagged C, so the only way to make it work in C is to introduce a function pointer member into the struct.