This question already has answers here:
Changing switch variable inside a case
(4 answers)
Closed 9 years ago.
Will it work/is it allowed to have a switch-case statement and change the key in a statement?
For example:
temp = 1
switch(temp)
{
case 1:
temp = 2;
//Do something with temp..
break;
}
The point of doing this is just that I don't have to create another variable, and it also makes sense to do so in my program. I am not asking about changing to another case in the switch-case statement, just if it's allowed to reuse the variable used as the key without any side effects.
This is perfectly fine. Virtually every state machine on the planet does something equivalent to what you do here.
Yes, you may do that. In fact, the following is common practice for writing lexers:
int c = getc(file);
switch(c)
{
case '+':
c = getc(file); // < `c` modified here!
switch(c)
{
case '+': return OP_INC;
default: ungetc(c, file); return OP_ADD;
}
...
}
Though it is not a good idea to use the same variable however the code will work because the branch is determined in the moment when the expression in the switch statement is evaluated.
Related
Please note that this is a question about C++ language, not about how real or useful is the example I'm giving to illustrate it.
Imagine we have an enum in a namespace (or namespaces):
namespace SomeVeryLargeNamespaceExample {
enum class E {
One,
Two,
};
}
Now, we want to use it in the expression of a switch statement. Today I found that it is possible to add the using SomeVeryLargeNamespaceExample::E inside the switch statement, before the first case, reducing the code cluttering in the cases:
switch (e) {
using SomeVeryLargeNamespaceExample::E;
case E::One:
std::cout << "One\n";
break;
case E::Two:
std::cout << "Two\n";
break;
}
At first glance I thought it was some kind of "do this before any case statement" feature that I never learned about, but some expressions, such as a function call, are not executed (actually, gcc generates a warning statement will never be executed [-Wswitch-unreachable]). On the other hand, a variable declaration is possible (but not initialization).
My question is, what other statements are possible? Is this a feature or just a consequence of how switch is designed?
Note: I found this other question, but it is specific for C (so it doesn't mention the namespaces case, for example), and I'm curious about C++.
Any valid C++ statement is possible:
int a;
void foo(int x)
{
switch (x) {
a=4;
case 0:
a=1;
break;
case 1:
a=2;
break;
}
}
This is syntactically valid C++, and gcc has no issues compiling it and producing an executable. However the initial statement can never be reached, of course. Therefore every modern C++ compiler will give you a warning message:
t.C: In function ‘void foo(int)’:
t.C:8:18: warning: statement will
never be executed [-Wswitch-unreachable]
8 | a=4;
|
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm modifying some existing code written in C++ that uses string pointers, but struggling to understand why I'm having so much difficulty using the toupper() function, or reducing the ASCII value by 32 to perform a case conversion. I have successfully achieved what I want, with minimal C++ knowledge, but I'd like to improve on the present code which — in order to simply prove a technical point — contains an if condition for every letter of the alphabet.
Other than my difficulties getting to grips with C++ syntax and rules, my attempt is working fine as I want.
The existing code defines 'buf' as follows:
static void c_write(Ldisc ldisc, const char *buf, int len)
{
from_backend(ldisc->frontend, 0, buf, len);
}
I then added the following, for each of 26 letters of the alphabet, in order to prove my point.
if (buf[0] == 97) buf="A";
if (buf[0] == 98) buf="B";
if (buf[0] == 99) buf="C";
if (buf[0] == 100) buf="D";
...and so on etc.
If I replace my 26 conditions with the following, then compilation fails.
if (buf[0]>=97 && buf[0]<=122)
{
buf[0]=buf[0]-32;
}
The message was "(376) : error C2166: l-value specifies const object"
I also tried using the toupper() function, but obtained unsatisfactory results there, either crashing the routine or returning a spurious value.
To the extent that it might help to understand the context in which buf[] is being used, the existing code contains the following working section.
switch (buf[0]) {
case CTRL('M'):
if (ldisc->protocol == PROT_TELNET && ldisc->telnet_newline)
ldisc->back->special(ldisc->backhandle, TS_EOL);
else
ldisc->back->send(ldisc->backhandle, "\r", 1);
break;
case CTRL('?'):
case CTRL('H'):
if (ldisc->telnet_keyboard) {
ldisc->back->special(ldisc->backhandle, TS_EC);
break;
}
case CTRL('C'):
if (ldisc->telnet_keyboard) {
ldisc->back->special(ldisc->backhandle, TS_IP);
break;
}
case CTRL('Z'):
if (ldisc->telnet_keyboard) {
ldisc->back->special(ldisc->backhandle, TS_SUSP);
break;
}
default:
ldisc->back->send(ldisc->backhandle, buf, len);
break;
The problem is very simple, in this
static void c_write(Ldisc ldisc, const char *buf, int len)
const is a promise not to modify the string pointed at by buf. So obviously trying to convert it to upper case is not allowed. That's what your error "(376) : error C2166: l-value specifies const object" is trying to tell you.
It seems reasonable that a function whose (apparent) purpose is to write a string would not modify that string. So if you need to convert to upper case I would say that the correct place to do that is before you call c_write, not as part of c_write.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Debugging a switch statement in a C-based programming puzzle
I found the below C question on web:
#include<stdio.h>
int main()
{
int a=10;
switch(a)
{
case '1':
printf("ONE\n");
break;
case '2':
printf("TWO\n");
break;
defa1ut:
printf("NONE\n");
}
return 0;
}
Although I never used 'switch' of int '10' with char '1', I assume the worst would be a non-compile, or 'default' get executed. But no, on my VStudio, it goes directly to 'return 0'. Why is this?
By the way, although I had a few years of experience in C programming, my previous motto was to stick to MSDN or available code samples. Now with the interviews and questions, the solidness of my skill is definitely being challenged.
defa1ut is not the same as default.
That's an unused and unreachable label.
As SLaks pointed out, defa1ut is a user defined label (e.g. for a goto), not the switch keyword default. This is why you aren't seeing the expected output.
But to answer your other question, in C you can compare char literals with integers. In this case '1' has a numerical value of 49, assuming you are using the ASCII character set.
Assuming you meant default, and you are using ASCII, your code sample is equivalent to this:
int a=10;
switch(a)
{
case 49: // ASCII value of '1'
printf("ONE\n");
break;
case 50: // ASCII value of '2'
printf("TWO\n");
break;
default:
printf("NONE\n");
}
You are reading defa1ut as default; default is C language's keyword but defau1t is not. If you want the output to be simply "NONE" use default instead of defau1t.
My professor commonly asks my class how many statements there are in a given program, but I can't determine what he defines as a statement. It seems as though an if/else is one statement, and a for loop is one statement regardless of if there are other supposed statements within it. Are there any governing rules for this matter or is his definition of his own invention?
Thanks
For a precise definition of a statement:
Definition: A statement is a block of code that does something. An assignment statement assigns a value to a variable. A for statement performs a loop.
In C, C++ and C# Statements can be grouped together as one statement using curly brackets
{
statement1;
statement2;
}
As far as counting statements, I agree with the others, there's not much point. Counting Lines of Code (LOC) though, actually has some value and there's a lot of research that tries to relate the number of LOC to the workload of developers. It's possible that your instructor is having you count statements and thinking of statements as nothing more than a single LOC, which isn't quite the case.
Statements nest, i.e. smaller statements can be joined into larger statements, like compound statements. For this reason, the question about "how many statements are there in this program" are ambiguous. One has to define the counting method first. Without it the question of "how many" makes little sense.
Here is the function that handles statements parsing in JS alike language:
static void do_statement(CsCompiler *c )
{
int tkn;
switch (tkn = CsToken(c)) {
case T_IF: do_if(c); break;
case T_WHILE: do_while(c); break;
case T_WITH: do_with(c); break;
case T_DO: do_dowhile(c); break;
case T_FOR: do_for(c); break;
case T_BREAK: do_break(c); CsSaveToken(c,CsToken(c)); break;
case T_CONTINUE: do_continue(c); CsSaveToken(c,CsToken(c)); break;
case T_SWITCH: do_switch(c); break;
case T_CASE: /*do_case(c);*/ CsParseError(c,"'case' outside of switch"); break;
case T_DEFAULT: /*do_default(c);*/ CsParseError(c,"'default' outside of switch"); break;
case T_RETURN: do_return(c); break;
case T_DELETE: do_delete(c); break;
case T_TRY: do_try(c); break;
case T_THROW: do_throw(c); break;
case '{': do_block(c, 0); break;
case ';': ; break;
default:
{
CsSaveToken(c,tkn);
do_expr(c);
break;
}
}
}
As you see it includes things like for, while and also expressions (separated by ;)
In computer programming a statement
can be thought of as the smallest
standalone element of an imperative
programming language. A program is
formed by a sequence of one or more
statements. A statement will have
internal components (e.g.,
expressions).
More at Statement (Computer Science) at Wikipedia.
Example:
switch( x )
{
case y:
if ( true )
{
break;
}
cout << "Oops";
break;
}
If the switch statement selects y, will Oops be written to the standard output?
- Is break in switch statements a dynamic keyword like continue which can be called under conditions or static like a closing bracket }?
break breaks out of an enclosing switch, while, for, or do ... while. It doesn't break out of an enclosing if or bare block. Pretty much exactly like continue.
It's certainly not part of the required syntax of a switch statement (like a close-brace is part of the syntax of blocks). break is a statement, essentially meaning "transfer execution to the point after the end of the innermost breakable construct".
No, Oops will not written out, the break jumps behind this statement.
You can use break statements conditionally just fine, you only have to watch out when you create nested statements that also support break (i.e. loops).
break is absolutely dynamic. So, if you write if (false) break; your Oops would be written out.
Think of break in this case as a goto end_of_switch.
No, it will not be printed in your case. break only breaks from switches and loops, not conditionals or functions or arbitrary enclosing scopes. Therefore, a more relevant question would be whether Oops is printed in this case:
switch( x )
{
case y:
for ( int i = 0; i < 10; ++i )
{
break;
}
cout << "Oops";
break;
}
And the answer here is yes, it will. The break will break out of the for, not the switch.
No. It would break out of the switch construct. "break" is used to come out of the innermost loop construct or switch construct. So, in your case the "oops" is not printed out on the screen. If you want that to happen, in your code, you could use if(false) instead of if(true).