How to implement an else clause in POSIX bc? - bc

POSIX bc has neither an else clause nor boolean operators. Is there any simple way to do simulate an else clause?

Use a second if statement. The code
if (expression) {
statement1
} else {
statement2
}
in GNU bc does the same as
if (expression) {
statement1
}
if (expression == 0) {
statement2
}
in POSIX bc.

Related

Should I prefer two if statements over an if-else statement if the conditions aren't related?

So I know that generally speaking, I should prefer an else-if over and if if. But what if the two conditions aren't related? For example, these would be considered "related" conditionals:
if (line[a] == '{'){
openCurly = true;
}
else if (line[a] == '}'){
closeCurly = false;
}
Notice how the two conditionals in the if-statements are related in a way such that when one is true, the other must be false. This is because line[a] can either be { or } but not both.
Here is another example:
if (line[a] == '{')
{
openCurly = true;
}
else if ((line[a] == ';' && !openCurly) || (line[a] == '}' && openCurly))
{
DoSomething(line);
line = "";
}
The second condition will never evaluate to true if the first condition if true, so it makes sense to have an else-if. However, those two conditionals look vastly different.
So, should I prefer something like this?
if (line[a] == '{')
{
openCurly = true;
}
if ((line[a] == ';' && !openCurly) || (line[a] == '}' && openCurly))
{
DoSomething(line);
line = "";
}
You should use an else-if statement. This is because an if-else construct only checks the second statement if the first one doesn't evaluate to true.
In the example you give,
if (line[a] == '{')
{
openCurly = true;
}
else if ((line[a] == ';' && !openCurly) || (line[a] == '}' && openCurly))
{
DoSomething(line);
line = "";
}
replacing the else if with an if statement would result in the second condition being checked even if the first one is true, which is completely pointless and would also lose you some time.
In the future, make decisions to use else-if statements based on whether the conditions are mutually exclusive or not.
You could do something like this:
#include <stdint.h>
#define COMBINATION(x, y) ((uint16_t(x) << 8) | (uint16_t(y) << 0))
...
switch (COMBINATION(line[a], openCurly))
{
case COMBINATION('{', false):
...
break;
case COMBINATION(';', false):
case COMBINATION('}', true):
...;
break;
}
}
Some may say it's a bit of an overkill, but I think that it may actually help splitting up the logical operation of your program into a set of distinct cases, thus make it easier to handle each case precisely as desired.

When to use else if instead of if?

Suppose we have this code:
if (condition_1)
do this
if (condition_2)
do that
else
do blablabla
And now this one:
if (condition_1)
do this
else if (condition_2)
do that
else
do blablabla
And now let's check what happens line by line. If i'm not mistaken, the first program starts checking if condition_1 is true or false, then the same thing happens for condition_2. And if none of these conditions are true, the program runs "do blablabla".
The second program starts from checking condition_1, and if it's false then if checks condition_2. If condition_2 if false, if does nothing (by nothing i mean it ignores the else statement).
If so, the second if statment from the second program can be replaced by:
if (!(condition_1) and condition_2)
do that
But else then can be run, i thought that every else if statement can be replaced by only if with a bit longer condition. So is this possible to replace every else if by using only if? And when "do blablabla" will run?
First part:
if (condition_1)
do this
// previous if has nothing to do with this if & else
if (condition_2)
do that
else
do blablabla
This case if condition_2 is true then do that will be executed, otherwise do blablabla
will be executed..
Now the second part:
if (condition_1)
do this
else if (condition_2)
do that
else
do blablabla
Here, the first true condition will be executing and rest of else if & else will be ignored, all conditions will be checked sequentially till else or a true condition is found.
If no conditions hold then else will be executed. So do blablabla will be executed if those both of two conditions are false
And finally, yes second if can be replaced by:
if (!(condition_1) and condition_2)
do that
This is because second if will be checked (do that will be executed) only if the condition_1 is false.. and condition_2 is true.
Which is equivalent to: (if and only if the condition_1 is false)
if (!(false) and condition_2)
do that
You can replace else ifs by checking whether previous condition was false, this way each else ifs with previous conditions, this is tedious.
Example:
if (a) {
// do task1
} else if (b) {
// do task2
} else if (c) {
// do task3
} else {
// do task4
}
Is equivalent to:
if (a) {
// do task1
}
if (!a and b) {
// do task2
}
if (!a and !b and c) {
// do task3
}
if (!a and !b and !c) {
// here is the else
// do task4
}
When to use else if instead of if?
Generally speaking, we chain if, else if's and an else at the last to ensure execution of only one condition, if one is true rest are ignored and executions goes to the next of very last line ( } ) of last else.
If i'm not mistaken, the first program starts checking if condition_1 is true or false, then the same thing happens for condition_2. And if none of these conditions are true, the program runs "do blablabla".
No, condition_1 does not influence what happens in condition_2. condition_1 can be either true or false but it's only condition_2 that matters in the second condition:
if (condition_1) {
do this
}
// --- no connection here ---
if (condition_2) {
do that
} else {
do blablabla
}
It's different in the second version since then condition_1 must be false for condition_2 to be even evaluated. It helps to put curly brackets out:
if (condition_1) {
do this
} else {
if (condition_2) {
do that
} else {
do blablabla
}
}

what is the use of if else statements?

I don't quite understand the meaning of else if statements.
why not just to continue with the if statements in case one is false?
it works the same.
example with if only that will work the same with else if:
function testSize(num) {
if (num < 5){
return "Tiny";
}
if (num < 10){
return "small";
}
return "Change Me";
}
testSize(7);
In your actual code you specify a return statement in the code associated to the if statement.
Suppose you don't specify a return statement or suppose today you specify a return statement but tomorrow you remove it to do a common return at the end of the method.
This code will test each condition even if the first one is true :
if (num < 5){
// do something
}
if (num < 10){
// do something
}
This code will not test the next condition if the first one is true :
if (num < 5){
// do something
}
else if (num < 10){
// do something
}
These two ways of doing have two distinct meanings.
When you have a series of if statements, you expect that more than one condition may be true.
When you have a series of if-else-if statements, you expect to have not more than one condition true.
Using the first form (a series of if) while functionally you expect to have not more than one condition true is misleading.
Besides, if the code is modified and you add a condition that is both true for two if statements while you don't want have this case, it would create an issue.
Your code is only showing your belief. What would happen in the example below?
function testSize(num) {
if (num < 5){
x = 1;
}
if (num < 10){
x = 2;
}
result = complex calculations;
}
function testSize2(num) {
if (num < 5){
x = 1;
} else if (num < 10){
x = 2;
}
return x * 2;
}
testSize(4); // result is 4
testSize2(4); // result is 2
x may also be involved in more calculations
if(condition) {...}
if(condition) {...}
if(condition) {...}
In above code, even if the first or second condition is true, third condition have to be checked.
if(condition) {}
else if(condition){}
else if(condition){}
Here if first condition is true, next two will not be checked. So, it saves time and is more readable logically.
A one way if statement takes an action if the specified condition is true.If the condition is false, nothing is done. But what if you want to take alternative actions when the conditions is false ? You can use a two-way if-else statement. The action that a two-way if-else statements specifies differ based on whether the condition is true or false.
Well, there is a bit different from this two statement.Consider the follow samples
if(a > 0) {
...
}
if( a == 0) {
...
}
if(a < 0) {
...
}
and
if(a > 0) {
...
}
else if( a == 0) {
...
}
else if(a < 0) {
...
}
when a is zero the last else if statement will not be execute while if need to compare third time.If a equals to 10, else if could be execute once while if is third.From this else if statement could be execute less and let your program a bit fast.
else if should be used when there are multiple conditions and you want only one of them to be executed, for instance:
if(num<3){ console.log('less than 3') }
else if(num<2){ console.log('less than 2')
If you use multiple if statements instead of using else if, it will be true for both the conditions if num = 1, and therefore it will print both the statements.
Multiple if statements are used when you want to run the code inside all those if statements whose conditions are true.
In your case it doesn't make a difference because the function will stop and return at the very first return statement it encounters. But let's say, the blocks' orders are interchanged, then your function will never return 'tiny' even if num = (anything less than 5).
I hope that helps!
If all your if branches terminate the function (e.g., but returning a value of throwing an exception), you're right, and you really don't need an else statement (although some coding standards might recommend it).
However, if the if branches don't terminate the function, you'd have to use an else or else if clause to prevent multiple blocks from being executed. Assume, e.g., you want to log a message to the console instead of returning it:
if (num < 5) {
console.log("Tiny");
} else if (num < 10) {
console.log("small");
} else {
console.log("Change Me");
}

how does a C-like compiler interpret the if statement

In C-like languages, we are used to having if statements similar to the following:
if(x == 5) {
//do something
}
else if(x == 7) {
//do something else
}
else if(x == 9) {
//do something else
} else {
//do something else
}
My question is, does the compiler see that if statement that way, or does it end up being interpreted like:
if(x == 5) {
//do something
}
else {
if(x == 7) {
//do something
}
else {
if(x == 9) {
//do something
}
else {
//do something else
}
}
}
EDIT: I realized that while the question made sense in my head, it probably sounded rather stupid to the rest of the general populace. I was more referring to how the AST would look and if there was any special AST cases for 'else-if' statements or if it would be compiled as a cascading if/else block.
They are equivalent to a C compiler. There is no special syntax else if in C. The second if is just another if statement.
To make it clearer, according to C99 standard, if statement is defined as
selection-statement:
if (expression) statement
if (expression) statement else statement
switch (expression) statement
and a compound-statement is defined as
compound-statement:
{block-item-list(opt) }
block-item-list:
block-item
block-item-list block-item
block-item:
declaration
statement
When a compiler frond-end tries to understand a source code file it often follows these steps:
Lexical analysis: turn the plain-text source code into a list of 'tokens'
Semantic analysis: parse the token list and generate an abstract syntax tree (AST)
The tree is then passed to compiler middle-end (to optimize) or back-end (to generate machine code)
In your case this if statement
if(x == 7) {
//do something else
} else if(x == 9) {
//do something else
} else {
//do something else
}
Is parsed as a selection-statement inside a selection-statement,
selection-stmt
/ | \
exp stmt stmt
| | |
... ... selection-stmt
/ | \
exp stmt stmt
| | |
... ... ...
and this one
if(x == 7) {
//do something else
} else {
if(x == 9) {
//do something else
} else {
//do something else
}
}
is the same selection-statement inside a compound-statement inside a selection-statement:
selection-stmt
/ | \
exp stmt stmt
| | |
... ... compound-stmt
|
block-item-list
|
block-item
|
stmt
|
selection-stmt
/ | \
exp stmt stmt
| | |
... ... ...
So they have different ASTs. But it makes no differences for the compiler backend: as you can see in the AST, there is no structural changes.
In both C and C++ enclosing a statement into a redundant pair of {} does not change the semantics of the program. This statement
a = b;
is equivalent to this one
{ a = b; }
is equivalent to this one
{{ a = b; }}
and to this one
{{{{{ a = b; }}}}}
Redundant {} make absolutely no difference to the compiler.
In your example, the only difference between the first version and the second version is a bunch of redundant {} you added to the latter, just like I did in my a = b example above. Your redundant {} change absolutely nothing. There's no appreciable difference between the two versions of code you presented, which makes your question essentially meaningless.
Either clarify your question, or correct the code, if you meant to ask about something else.
The two snippets of code are, in fact, identical. You can see why this is true by realizing that the syntax of the "if" statement is as follows:
if <expression>
<block>
else
<block>
NOTE that <block> may be surrounded by curly braces if necessary.
So, your code breaks down as follows.
// if <expression>
if (x == 5)
// <block> begin
{
//do something
}
// <block> end
// else
else
// <block> begin
if(x == 7) {
//do something else
}
else if(x == 9) {
//do something else
} else {
//do something else
}
// <block> end
Now if you put curly braces around the block for the "else", as is allowed by the language, you end up with your second form.
// if <expression>
if (x == 5)
// <block> begin
{
//do something
}
// <block> end
// else
else
// <block> begin
{
if(x == 7) {
//do something else
}
else if(x == 9) {
//do something else
} else {
//do something else
}
}
// <block> end
And if you do this repeatedly for all "if else" clauses, you end up with exactly your second form. The two pieces of code are exactly identical, and seen exactly the same way by the compiler.
Closer to the first one, but the question doesn't exactly fit.
When a programs compiled, it goes through a few stages. The first stage is lexical analysis, then the second stage is syntactic analysis. Lexical analysis analyses the text, separating it into tokens. Then syntactic analysis looks at the structure of the program, and constructs an abstract syntax tree (AST). This is the underlying syntactic structure that's created during a compilation.
So basically, if and if-else and if-elseif-else statements are all eventually structures into an abstract syntax tree (AST) by the compiler.
Here's the wikipedia page on ASTs: https://en.wikipedia.org/wiki/Abstract_syntax_tree
edit:
And actually, and if/if else statement probably forms something closer to the second one inside the AST. I'm not quite sure, but I wouldn't be surprised if its represented at an underlying level as a binary tree-like conditional branching structure. If you're interested in learning more in depth about it, you can do some research on the parsing aspect of compiler theory.
Note that although your first statement is indented according to the if-else "ladder" convention, actually the "correct" indentation for it which reveals the true nesting is this:
if(x == 5) {
//do something
} else
if(x == 7) { // <- this is all one big statement
//do something else
} else
if(x == 9) { // <- so is this
//do something else
} else {
//do something else
}
Indentation is whitespace; it means nothing to the compiler. What you have after the first else is one big if statement. Since it is just one statement, it does not require braces around it. When you ask, "does the compiler read it that way", you have to remember that most space is insignificant; the syntax determines the true nesting of the syntax tree.

how to use regex in switch case in expect script?

Normally, switch case in expect looks like this:
switch -- $count \
1 {
set type byte
} 2 {
set type word
} big {
set type array
} default {
puts "$count is not a valid type"
}
I need to use regex operators such as | or & - how can I do that?
The below example does not work with expect code :
switch -- $variable \
("a"|"b"|"c") {
do something
}
("a"|"b"|"c") represents a or b or c, but it does not seem to work.
How do I use such statements in switch or may be an and statement?
Use the -regexp option for the command, and brace the expression the Tcl way. Also, you can use braces around all the switches so you don't have to use line continuations.
switch -regexp -- $variable {
{a|b|c} {
do something
}
{^[def].*(?:g|h|i)} {
do a different thing
}
default {
do something else
}
}
http://tcl.tk/man/tcl8.5/TclCmd/switch.htm
http://tcl.tk/man/tcl8.5/TclCmd/re_syntax.htm