Heys.
I have this code, which sets a table for some mystery reason. Size is 6x60. Which means SIZEY defined as 6, and SIZEX as 60.
void set_table(char** table)
{
int i,j,k=0;
for(i=0;i<SIZEY;i+=3){
for(j=0;j<SIZEX;j++){
switch(k++%5){
case 0:
table[i][j]='|';
break;
case 1:
table[i][j]=' ';
break;
case 2:
table[i][j]=(char)((((k-2)/50)%10)+48);
break;
case 3:
table[i][j]=(char)((((k-3)/5)%10)+48);
break;
case 4:
table[i][j]=' ';
break;
default:
continue;
}
}
}
}
I am doing this with 3 variables, as you can see. Question is, can i do that with 2 variables, or even with only 1 ?
Thanks in advance.
Here's a simplification for you:
switch(k++%5){
case 0:
table[i][j]='|';
break;
case 1:
case 4:
table[i][j]=' ';
break;
case 2:
case 3:
table[i][j]= '0';
break;
default:
continue;
}
With C++, one case can fall into another, such as with cases 1 and 2 above.
Your expressions for case 2 and 3 can be simplified. I'll use case 2 as an example:
((((k-2)/50)%10)+48)
Substituting 2 for k yields
((((2-2)/50)%10)+48)
Simplify:
((((0)/50)%10)+48)
Zero divided by anything is zero, simplifying again:
(((0)%10)+48)
Zero mod anything is zero, since it involves division:
((0)+48)
Simplifying:
(48)
Replacing with the equivalent character (since your array is char):
'0'
Related
so this is the code that im trying to get to work but it displays "duplicate case value" whenever it reaches for B
im a first year college student so i might have used a wrong format or i might be overlooking something i really dont seem to figure out the problem so i turn to you guys for help
char dep;
int exp;
cout<<"please enter your department, A, B OR C: ";
cin>>dep;
cout<<"please enter your years of experience ";
cin>>exp;
switch(dep)
{
case 'A' || 'a' :{
switch (exp) {
case 5:
cout<<"you will recieve a 5% raise and 2.5% extra due to your experience";
break;
defualt : cout<<"you get 5% raise";
break;
}
}
break;
case 'B' || 'b' :{
switch (exp) {
case 5:
cout<<"you will recieve a 2% raise and 2.5% extra due to your experience";
break;
defualt : cout<<"you get 2% raise";
break;
}
}
break;
Though it compiles (or would without the B version), and spells what you wanted if roughly translated to English, case 'A' || 'a' does not do what you think it does.
The expression after case is treated as an exact match for the selection statement — it's compared exactly to dep. You can't throw in a more complex expression and expect it to be "unrolled" into multiple comparisons. Think of switch/case as a simple lookup table, rather than an intelligent branching feature (that's what if is for!).
Perhaps confusingly, the expression 'A' || 'a' is valid in its own right, but (like any expression) it evaluates to a single value: either true or false, depending on whether either of the operands if "truthy". In this particular example, neither has ASCII value zero so both is truthy, and the expression is always true. It'll be converted to the type of dep (the rules say it becomes 1) and used for that exact lookup.
Since you did this with 'B' and 'b' too, you do then indeed have two equivalent cases.
Instead, write a separate case for each condition. Fortunately, since cases fall through, you don't need to repeat the "body" of the case: you can just put the two cases next to each other; just don't put a break between them:
case 'A':
case 'a':
// code here
break;
case 'B':
case 'b':
// code here
By the way, you misspelt default.
Here below is my code for a switch statement:
switch(pin)
{
case 1:
break;
case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20:
case 21: case 22: case 23: case 24:case 25:case 26:case 27:case 28:case 29: case 30: case 31:
case 32: case 33: case 34: case 35:
dataOut[pin-2] = 1;
DAQmxWriteDigitalLines(taskHandleOut,1,1,10.0,DAQmx_Val_GroupByChannel,dataOut,NULL,NULL);
break;
default:
break;
In the above, the case 2-35 are to be grouped together for which, I mean, when pin is equal to 2-35, the specific task is to be performed.
I want to know if the above code is valid or not. I haven't seen case grouping in switch statements. Any weblinks for similar multiple case grouping is appreciated. Maybe there is some better way to do so instead of grouping multiple cases.
While your case may be better served with an if-check if (pin >= 2 && pin <= 35), it is common to group case labels like that.
gcc/clang/tinycc even have syntactic sugar for it:
switch(pin){
case 2 ... 35: /*nonstandard GNU extension; note well the whitespace*/
};
Yes, this is absolutely fine, although I'd write
if (pin >= 2 && pin <= 35){
dataOut[pin-2] = 1;
DAQmxWriteDigitalLines( ...
}
if I were you. If you are using gcc exclusively as your compiler, then you could also use case ranges.
It is valid. It's called fallthrough, and it's the reason you have to put breaks to separate cases. That is, if you don't break, the instructions following your case will get executed anyway. Like in
int i = 1;
switch(i) {
case 1:
cout<<1<<endl;
case 2:
cout<<"nope!\n";
}
This will output
1
nope!
because there's no break before case 2:.
But in your case you may as well do
if (pin >= 2 && pin <= 35) {
dataOut[pin-2] = 1;
DAQmxWriteDigitalLines(taskHandleOut,1,1,10.0,DAQmx_Val_GroupByChannel,dataOut,NULL,NULL);
}
Yes, you can. C++ provides fall-through for switch case statements. So unless you provide a break; at the end of the case:, control falls-through to the next case allowing you to do exactly what you describe with a switch. Some compilers allow short-hand for describing multiple case statements at once, but for portable C++, simply providing each case without a break; is all you need, e.g.
switch(pin)
{
case 1:
break;
case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9:
case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17:
case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25:
case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33:
case 34: case 35:
/* do what you need with pins 2 - 35 */
dataOut[pin-2] = 1;
DAQmxWriteDigitalLines (taskHandleOut, 1, 1, 10. 0,
DAQmx_Val_GroupByChannel, dataOut, NULL, NULL);
break;
default:
break;
}
Now any case 2-35 will execute your desired statements:
dataOut[pin-2] = 1;
DAQmxWriteDigitalLines (taskHandleOut, 1, 1, 10. 0,
DAQmx_Val_GroupByChannel, dataOut, NULL, NULL);
It's valid code but I would rather use default in your case especially when you have planned to use other numbers for other cases. default will be used like else in an if/else statement. Here default would be called for every number you don't have an case specified.
I've got a problem with converting types in C++. I've got an expression: string wholeExpression = "44*2"; and I want to separate numbers from operators.
If it is a operator, I use this part of code:
string subExpression;
char skladnik;
subExpression = wholeExpression.substr(poczatek, lenght);
skladnik = subExpression[0];
if it is a number:
subExpression = wholeExpression.substr(poczatek, lenght);
skladnik = atoi(subExpression.c_str());
#EDIT
switch (skladnik)
{
case '+':
case '-':
{
while (topOfStack > 0 && stack[topOfStack - 1] != '(')
{
outPut += stack[topOfStack - 1] + przecinek;
stack.resize(topOfStack - 1);
topOfStack--;
}
stack += skladnik;
topOfStack++;
break;
}
case '/':
case '*':
{
while (topOfStack > 0 && (stack[topOfStack - 1] == '*' || stack[topOfStack - 1] == '/'))
{
outPut += stack[topOfStack - 1] + przecinek;
stack.resize(topOfStack - 1);
topOfStack--;
}
stack += skladnik;
topOfStack++;
break;
}
case '(':
{
stack += skladnik;
topOfStack++;
break;
}
case ')':
{
while (stack[topOfStack - 1] != '(')
{
outPut += stack[topOfStack - 1] + przecinek;
stack.resize(topOfStack - 1);
topOfStack--;
}
if (stack[topOfStack - 1] == '(')
{
stack.resize(topOfStack - 1);
topOfStack--;
}
break;
}
default:
{
outPut += to_string(skladnik) + przecinek;
break;
}
}
}
But suddenly I've got problem with a numbers from 40 to 43 and 45 and 47 -> which are operators (in ASCII code). They are probably interpret by the switch not as numbers but as oparators. Another numbers work perfectly. How can i solve this problem?
You've answered your own question. The char for the number 40 doesn't exist. It's two char variables: 4 and 0. Because you are putting an int into a char with atoi, it is going to use the ASCII code. Without knowing the value of lenght, it's hard to say that this is indeed your problem, but here are two possible solutions:
Don't use atoi upfront. Instead interpret each number char into an actual integer after your switch statement (4 and 0 would be
atoi('4') * 10 + atoi('0'))
use an int orlong or double variable to hold your numbers.
You are using your variable skladnik in two different ways. In one code path it refers to a decoded integer, in the second code path it refers to a character. Once you've conflated the meaning like this, there's no way to tell once you're at the switch which meaning it has.
You should use two different variables, one for decoded numbers and one for operator characters. Then there will be no confusion.
I am new into programming. Is it possible to use <, > in a switch case?
For instance,
...
...
...
int i;
cin>> i;
...
...
switch(i){
case 20<i<35
...
C++ does not offer a switch syntax for matching ranges.
When ranges are relatively small, you could supply case labels, and rely on fall-through:
switch(i) {
case 20:
case 21:
case 22:
case 23:
case 24:
case 25: doSomething();
break;
case 26:
case 27:
case 28:
case 29: doSomethingElse();
break;
...
}
For medium-size ranges (1000 elements or so) you could use a vector of function objects to dispatch to a particular logic, but that requires a lot more work than writing a simple switch statement.
For large ranges your best bet is a chain of if-else statements.
How can I convert the following if=statement to a switch-statement WITHOUT needing to create a case for every number between that interval (41-49)? Is it possible?
if (num < 50 && num > 40)
{
printf("correct!");
}
You have to enumerate every case for a switch. The compiler converts this to a jump table, so you can't use ranges. You can, however, have multiple cases use the same block of code, which may be closer to what you want.
switch(num) {
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
case 48:
case 49:
printf("correct!");
break;
default:
break;
}
What about this?
switch ((num-41)/9) {
case 0:
printf("correct!");
break;
}
bool criteria1 = (num < 50 && num > 40);
switch criteria1: ...
It may result in multilevel decision networks.. scary?
In C or C++ (since you are using printf, I'll assume that's what it is), cases need to be enumerated for each choice.
The only difference between switch/case and if is the possibility that the compiler can turn it into a computed goto instead of checking ranges. If switch/case supported ranges, that would defeat the purpose of opening the possibility of this optimizaton.