Hexadecimal Number convertor - c

i trying to write a Recursion function that get a decimal number and print the value in hexadecimal
but i dont know what worng in my code
please help me i still new in Recursion and dont get it complitly...
my code:
void PrintHexadecimalNumber(int n)
{
if (n%16==0)
return ;
PrintHexadecimalNumber(n/16);
switch ((n % 16))// A-F cases
{
case (10):
printf("A");
break;
case (11):
printf("B");
break;
case (12):
printf("C");
break;
case (13):
printf("D");
break;
case (14):
printf("E");
break;
case (15):
printf("F");
break;
}
if ((n%16)<10)
printf(n%16);
}

Your code isn't going to work because of the test you've written to stop the recursion.
if (n%16==0)
If you have the number (in hex) 10, the function will stop immediately because n % 16 will be 0. What you actually want to test for is when n is 0. Like this
if (n==0)
Your switch statement should also be expanded out to include the values 0 to 9 rather than having a separate if statement after it. You can group them together by leaving out the break
switch(n % 16)
{
/* existing case statements go here */
case 0:
case 1:
case 2:
...
case 9:
printf("%d",n % 16); // also fixing this as per comments above.
break;
}
Or you could just use printf("%x",n % 16) and do away with the switch completely if what you're trying to do is explore how recursion works.

Related

Exercise in C with if and switch statements: Write code to convert 2 digit numbers into words

There's this exercise I'm trying to figure out. The assignment asks to convert a two-digit number in words, the output should be something like this :
Enter a two-digit number:45
You entered the number forty-five.
I'm still a total beginner to programming. I'm at this chapter in this C programming book, in the exercise section about the switch and if statements. The exercise suggests to use two switch statements, One for the tens and the other one for units, but numbers within 11 and 19 require special treatment.
The problem is that I'm trying to figure out what should I do for numbers between 11 and 19, I was thinking to use the if statement but then the second switch function would include in the output and it would turn into something like You've entered the number eleven one.
This is the program I've been writing so far (incomplete):
int digits;
printf("Enter a two-digit number:");
scanf("%d", &digits);
printf("You entered the number ");
switch (digits / 10) {
case 20:
printf("twenty-");break;
case 30:
printf("thirty-");break;
case 40:
printf("forty-");break;
case 50:
printf("fifty-");break;
case 60:
printf("sixty-");break;
case 70:
printf("seventy-");break;
case 80:
printf("eighty-");break;
case 90:
printf("ninety-");break;
}
switch (digits % 10) {
case 1:
printf("one.");break;
case 2:
printf("two.");break;
case 3:
printf("three.");break;
case 4:
printf("four.");break;
case 5:
printf("five."); break;
case 6:
printf("six.");break;
case 7:
printf("seven.");break;
case 8:
printf("eight.");break;
case 9:
printf("nine.");break;
}
return 0;
Before the switch use these if then else statements.
if (digits == 11) {
printf("eleven");
}
else if (digits == 12) {
printf("twelve");
}
else if (... ) {// similar statements for 13 14 15 16 17 18 19
}
// now figure out where do the switch statements have to be inserted
else {
// here?
}
// or here?
The above solution assumes you haven't learnt arrays yet. If you have learnt or know to use arrays - there are ways to improve this code.
This is such a good problem for a learner, do not want to give much away
// Pseudo code
int print_two_digits(int tens, int ones) {
if (tens 2 or more)
print tens_place(tens) // use `tens` to index an array of strings.
if (ones == 0) return;
print -
else
ones += tens*10;
print ones_text(ones) // ones is 0-19 at this point. Index an string array with `ones`
}
How to index a string array and print?
// index: valid for 0,1,2
void print rgb(int index) {
const char *primary[] = { "red", "green", "blue" };
puts(primary[index]);
}
Trivia: English numbers in text 10-99 are mostly big-endian, most significant first as in "forty-two", except for [11-19] which has the smaller digit first as in "fourteen".
I would suggest you write a function with 3 switches instead of 2:
a first switch to handle special cases such as 0 and the numbers from 10 to 19 and return directly.
a second switch to handle tens from 20 and print the word without a trailing dash,
an if statement where you test if you need a dash,
a third switch where you handle units.

C switch case values cannot be modified within the switch (not constant)

I am trying to create bounce dynamics in a game that I'm programming on an arduino uno.
I can create a series of nested ifs but I've heard that a switch is faster.
I know that the case values are specified to be constants, but I'm curious if it's possible to make this code work?
// player and ball are both byte arrays
switch(ball[0]) { // bounce off edges x-axis
case (player[0]-1):
ball[3] -= 2;
break;
case player[0]:
ball[3] -= 1;
break;
case (player[0]+3):
ball[3] += 1;
break;
case (player[0]+4): // At this line the compiler says: the value of 'player' is not usable in a constant expression
ball[3] += 2;
break;
}
I'm pretty sure that the answer is either no, or that the workaround of putting the variables into constants will be much slower and larger than simply giving in to the nested ifs, but it doesn't hurt to ask.
Avi Berger presented a fantastic solution which I was able to fit and to make work:
// player and ball are both byte arrays
switch(ball[0] - player[0]) { // bounce off edges x-axis
case 1:
ball[3] -= 2;
break;
case 0:
ball[3] -= 1;
break;
case -3:
ball[3] += 1;
break;
case -4:
ball[3] += 2;
break;
}

How can I use ranges in a switch case statement in C?

My logic is:
if number is between 1 to 10, execute first case statement
if number is from 20 to 30, execute second case statement
is there a solution other than the one below?
case '1' ... '10':
case '20' ... '30':
The GCC compiler supports, as a language extension, case ranges like:
switch(i) {
case 0 ... 9: return true;
default: return false;
}
This language extension is also accepted by Clang/LLVM. So use it if you can afford restricting your code to GCC & Clang compilers.
See also this.
I have no idea why this extension was not included in C11 standard.
Notice also that GCC accepts computed or indirect goto and labels as values. There are cases (in particular in
generated C code) where these features are useful. Examples could include some efficient bytecode interpreter. Some implementations of the Ocaml virtual machine are a good example.
void SwitchDemo(int value)
{
switch(value / 10)
{
case 0: ...; break; // 0 - 9
case 1: ...; break; // 10 - 19
...
}
}
or, specific to the question ranges:
void SwitchDemo(int value)
{
switch((value-1) / 10)
{
case 0: ...; break; // 1 - 10
case 1: ...; break; // 11 - 20
...
}
}
Option 1: use case 0 for 0-9, case 1 for 11-20 and so on.
Option 2: use if
Option 3:
Another shabby way is using fall through cases like this:
#include <stdio.h>
int main(void) {
int i=1;
for(i=1;i<=25;i++)
{
switch(i)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
printf("%d is in between 1-10\n", i);
break;
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
printf("%d is in between 11-20\n", i);
break;
default:
printf("%d is above 20\n", i);
}
}
return 0;
}
Output:
1 is in between 1-10
2 is in between 1-10
3 is in between 1-10
4 is in between 1-10
5 is in between 1-10
6 is in between 1-10
7 is in between 1-10
8 is in between 1-10
9 is in between 1-10
10 is in between 1-10
11 is in between 11-20
12 is in between 11-20
13 is in between 11-20
14 is in between 11-20
15 is in between 11-20
16 is in between 11-20
17 is in between 11-20
18 is in between 11-20
19 is in between 11-20
20 is in between 11-20
21 is above 20
22 is above 20
23 is above 20
24 is above 20
25 is above 20
https://ideone.com/Cw6HDO
C doesn't support case values other than single integers (or integer-like things -- characters, enumeration values). So your options are:
As suggested by pzaenger in a now-deleted comment: transform the number you're working with into something you can switch on (in this case, divide by 10).
Multiple case statements (taking advantage of fallthrough): case 1: case 2: case 3: ... case 10: do_something();
Use if rather than case.
In the C programming language the case statement used in a switch() statement must specify a value that the compiler can turn into a constant in some way. Each of the values used in the case statements must be unique within the scope of the switch(). The default keyword indicates the default if none of the case statements match the expression in the switch() statement.
As an aside, check out Duff's Device to show an interesting use of switch() and case. See How does Duff's device work?
So the following shows several examples of proper case statements in a switch():
#define XXVAL 2
#define CASETEST(x) (x + 5)
int iValue;
// set the value of the variable iValue at some point
switch (iValue) {
case 0:
// do the case if iValue == 0
break;
case XXVAL:
// do the case if iValue == XXVAL
break;
case CASETEST(3):
// do the case if iValue == CASETEST(3)
// works because preprocessor generates the source text which is
// then compiled and the expression can be resolved to a constant
break;
case CASETEST(5) * 2:
// do the case if iValue == CASETEST(5) * 2
// works because preprocessor generates the source text which is
// then compiled and the expression can be resolved to a constant
break;
default:
break;
}
What you can do if you still want to use a switch() with ranged case statements is to provide some mechanism to fold the expression into one or more specific constant values.
So in a simple, trivial example you could do something like the following. This is a trivial case to show the technique which ends up making the logic of the simple if statements opaque. This technique can be useful for complex decisions and classification that can be folded into a simple set of constants.
int foldit (int iValue)
{
if (iValue < 5000) return 0;
else if (iValue < 10000) return 1;
else if (ivalue < 20000) return 2;
else return 9999; // triggers the default part of the switch
}
switch (foldit(iValue)) {
case 0:
// do what is needed for up to but not including 5000
break;
case 1:
// do what is needed for 5000 up to but not including 10000
break;
case 2:
// do what is needed for 10000 up to but not including 20000
break;
default:
// handle anything else
break;
}
Where the fold approach can be helpful is when you have several different results perhaps using a filter to try to classify a data item.
#define type1 0x00001
#define type2 0x00002
#define type3 0x00004
#define type4 0x00008
struct datatype {
int iVal;
int jVal;
};
unsigned long is_a_type1(struct datatype * thing)
{
unsigned long retVal = 0; // initialize to not a type1, set to type1 if turns out to be
// do checks for the type and if so set retVal to type1 if it matches
return retVal;
}
unsigned long is_a_type2(struct datatype * thing)
{
unsigned long retVal = 0; // initialize to not a type2, set to type2 if turns out to be
// do checks for the type and if so set retVal to type2 if it matches
return retVal;
}
unsigned long is_a_type3(struct datatype * thing)
{
unsigned long retVal = 0; // initialize to not a type3, set to type3 if turns out to be
// do checks for the type and if so set retVal to type3 if it matches
return retVal;
}
unsigned long is_a_type4(struct datatype * thing)
{
unsigned long retVal = 0; // initialize to not a type4, set to type4 if turns out to be
// do checks for the type and if so set retVal to type4 if it matches
return retVal;
}
unsigned long classify (struct datatype *thing)
{
unsigned long ulTestResult = 0;
// test to see if this is a type1 thing
ulTestResult |= is_a_type1(thing);
// test to see if this is a type2 thing
ulTestResult |= is_a_type2(thing);
// test to see if this is a type3 thing
ulTestResult |= is_a_type3(thing);
// test to see if this is a type4 thing
ulTestResult |= is_a_type4(thing);
return ulTestResult;
}
int main ()
{
struct datatype myThing;
// other source code then
switch (classify(&myThing)) {
case type1 | type2 | type3:
// do stuff if this is a type1, type2, and type3 but not type4
// that is classify() determined that myThing matched all three types.
break;
case type1:
// do stuff if type1 which includes stuff you do for type2 as well under
// special values of myThing.
if (myThing.iVal < 50) {
case type2:
// at this point we have type2 case stuff that we do. Code above is skipped
// and the switch () will jump straight to here if classify() is type2.
//
// Also stuff we do if type1 and myThing.iVal < 50
// in other words this code is execute if classify(&myThing) is type2 or
// if classify(&myThink) is type1 and there is a special processing for myThing.iVal < 50
break; // if classify() type2 or if classify() type1 and myThing.ival < 50
}
// do stuff if only type1 and myThing.iVal >= 50
break;
case type2 | type3:
// do stuff if type2 and type3 matched but none of the others.
break;
default:
// any other case
break;
}
return 0;
}
Switch statements in c can only operate on a constant expression, the case statements cannot include dynamic comparisons.
Example of something which is, and is not, a "Constant Expression" in C?
For something this simple an if/else structure could be clearer and simpler, depending on the compiler your case statement may be translated into a series of branching comparison statements anyways.

Which is better, a function with one return statement or multiple ones? [Embedded C]

While developing a code for the micro-contoller, I faced these warning that my function has multiple return statements.
I can replace them with single one at the end of the function, but I thought this is better. Could someone explain to me which is better and why
unsigned char getDays(unsigned char oldDay,unsigned char newDay,unsigned char currentMonth){
unsigned char xtemp;
if(oldDay < newDay){ //in the same month
xtemp = newDay - oldDay ;
return xtemp ;
}
else{
switch(currentMonth){
case 2:
case 4:
case 6:
case 8:
case 9:
case 0x11:
case 1:
xtemp = newDay + 0x31 - oldDay;
return xtemp ;
break;
case 3:
xtemp = newDay + 0x28-oldDay;
return xtemp ;
break;
case 5:
case 7:
case 0x10:
case 0x12:
xtemp = newDay+0x30-oldDay;
return xtemp ;
}
}
}
Given that all paths with a return statement calculate a value of xtemp and then finish with return xtemp;, and there are no loops so the flow is clear, I suggest a single return statement would suffice.
That said, I think the number of return statements is the most minor problem with that code.
Your switch statement has no default clause so, if currentMonth is not any of the chosen case values, the function falls off the end (with no return statement at all). That causes the caller to have undefined behaviour if it uses the return value of your function. Having a single return statement at the end would eliminate that problem, if the code is structured so xtemp is always initialised or assigned a value.
I'd also be concerned about readability - a set of magic values, some expressed as decimal and some as hex, increases difficulty for mere mortals to understand the code - which in turn makes it harder to get right. In fact, my hunch is that - because you have used a hex value in at least one place where a decimal value appears to have been intended - that you have not actually got that code working correctly.
Rather than a switch, I'd probably use some carefully constructed if/else if statements.
Thanks alot for your help ... with your help that's the final code i get
unsigned char getDays(unsigned char oldDay,unsigned char newDay,unsigned char currentMonth){
if (oldDay > newDay){
switch(currentMonth){
case 0x3: return newDay + 0x28 - oldDay;
case 0x5: case 0x7: case 0x10: case 0x12: return newDay + 0x30 - oldDay;
default: return newDay + 0x31 - oldDay;
}
}
return newDay - oldDay; //in the same month
}

C switch statement with do-while interleaved [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does Duff's device work?
I am trying to understand how this is working. Any help would be appreciated.
#include<stdio.h>
void duff(int count)
{
int n=(count+7)/8;
printf("n=%d count =%d\n",n,count%8);
switch(count%8){
case 0: do{ printf("case 0\n");
case 7: printf("case 7\n");
case 6: printf("case 6\n");
case 5: printf("case 5\n");
case 4: printf("case 4\n");
case 3: printf("case 3\n");
case 2: printf("case 2\n");
case 1: printf("case 1\n");
}while( --n >0);
}
}
main(){
int count;
scanf("%d",&count);
duff(count);
}
Basically if the switch case evaluates to case statement 2, then the do statment of the while is never executed. But i ran this program and it gave me the output, but unable to explain:
output:
3
n=1 count =3
case 3
case 2
case 1
This is known as duff's device and is used in code optimization techniques to reduce branch instructions. The reason that it works is that by default case statements without breaks fall through to the next case so when you hit case 3, you keep going through to case 2 and case 1.
Both the do and the case "statements" are essentially just "goto labels". They don't add any actual code. They just tell while and switch (respectively) where to jump to. In other words, there is no code for the do to (not) execute.
(That said, it is somewhat remarkable/bizarre that C's grammar allows cases to exist in children of the switch, rather just as direct children of a switch.)
There are no break statements between the cases so the cases fall through. Therefore n=3 causes case 3: case 2: and case 1: to be executed.

Resources