# C Programming Homework

Use only “stdio.h” library

Write two functions in a single program. After writing following functions, call them from main function to test if they are working correctly (how functions will be tested depends on programmer).

i) Write a function that will receive two integer variables (x,y) as parameter. This function will find and show on screen all odd numbers between x and y (both included and order of x and y, while sending them to defined function, is not important).

ii) Write a function that will perform following mathematical expression (note that, x, y and z are integer values), and return result.

answered Jun 19, 2020 by (140 points)
#include<stdio.h>

int main()
{
int x, y,z;
// odd nuber//

printf("Enter start and end value to generate Odd numbers\n");
scanf("%d%d", &x, &y);

printf("\nOdd numbers between %d and %d are:\n", x, y);

while(x <= y)
{
if(x % 2 != 0)
{
printf("%d\n", x);
}
x++;
}

//MATHS//
printf("Enter first number :");
scanf("%d",&x);

printf("Enter second number :");
scanf("%d",&y);

z=x+y;
printf("Sum is :%d\n",z);

printf("----THANK YOU---------");

return 0;
}
answered Jun 19, 2020 by (15,620 points)
edited Jun 22, 2020 by Peter Minarik

# The Solution

So we need to know what an odd number is. It can be defined as a number that cannot be divided by 2 and the result being a whole number. In mathematics, we can also say the modulo division by 2 does not yield 0.

Let's print these numbers.

## Naive implementation

We can just iterate between the start and the end and check if a number can be divided by two or not and print accordingly.

```void printOdds(int start, int end)
{
while (start <= end)
{
if (start % 2 != 0)
printf("%d, ", start);
start++;
}
printf("\n");
}```

## But we can do better

We know, after we found the first off number, that the next odd number is larger by two. So instead of checking every number, all we need to do is find the smallest odd number from start, and list (without checking) every second number until we reach the end (or reach the first odd after end, which we do not process any more).

If the first number is odd, we're good. If not, the first odd is one larger than our start.

```// print all the odd numbers between start and end (inclusive)
void printOdds(int start, int end)
{
if (start % 2 == 0)
start++;

for (int i = start; i <= end; i += 2)
{
if (i != start)
printf(", ");

printf("%d", i);
}
}```

## We can still do better

But what if someone was tricky and start is larger than end? In this case, we have to list the numbers descending. Things will get a bit tricky.

In this case, we have to increase or decrease start depending on what direction we go: ascending (+1) or descending (-1).

The direction can be determined by comparing the start and end and see which one is larger.

We also have to make sure end is the first odd we do not want to print, as i != end is the exit condition of the loop. So first we make sure end is the last odd that we want to print, then we take a step beyond this limit.

```// print all the odd numbers between start and end (inclusive)
void printOdds(int start, int end)
{
int direction = start < end ? +1 : -1;

if (start % 2 == 0)
start += direction;

if (end % 2 == 0)
end -= direction;

int step = 2 * direction;

end += step;

for (int i = start; i != end; i += step)
{
if (i != start)
printf(", ");

printf("%d", i);
}
printf("\n");
}
```

## Handle corner cases?

If we still want to work on this method, we may notice, that we may have an overflow or underflow if we pick end to be too high or too low due to t he end += step line.

We can battle this by:

1. leaving the loop if we reached the end before we increment the loop variable.
2. we do not enter the loop at all, if there's nothing to do (avoiding double checking the exit condition)
```typedef enum { finished = 0, firstElement = 1, restOfTheElements = 2} states;

void printOdds(int start, int end)
{
// ...
int dirAfterLimitAdjust = start <= end ? +1 : -1;
if (direction != dirAfterLimitAdjust) // There were no odds between start and end
{
printf("\n"); // Indicate no output by an empty line.
return;
}

int step = 2 * direction;
states status = firstElement;
while (status)
{
if (status == firstElement)
status = restOfTheElements;
else // status == restOfTheElements
printf(", ");

printf("%d", start);
if (start == end)
status = finished;

start += step;
}

printf("\n");
}```

# The Final Implementation

```#include <stdio.h>

typedef enum
{
finished = 0,
firstElement = 1,
restOfTheElements = 2
}  states;

// print all the odd numbers between start and end (inclusive)
void printOdds(int start, int end)
{
int direction = start <= end ? +1 : -1;

if (start % 2 == 0)
start += direction;

if (end % 2 == 0)
end -= direction;

int dirAfterLimitAdjust = start <= end ? +1 : -1;
if (direction != dirAfterLimitAdjust) // There were no odds between start and end
{
printf("\n"); // Indicate no output by an empty line.
return;
}

int step = 2 * direction;
states status = firstElement;
while (status)
{
if (status == firstElement)
status = restOfTheElements;
else // status == restOfTheElements
printf(", ");

printf("%d", start);
if (start == end)
status = finished;

start += step;
}

printf("\n");
}

int main()
{
printf("[-4, 6]: "); printOdds(-4, 6); // Test ascending
printf("[6, -4]: "); printOdds(6, -4); // Test descending
printf("[6, 6]: "); printOdds(6, 6); // Test empty
printf("[5, 5]: "); printOdds(5, 5); // Test only one odd

return 0;
}```

## Note

Problem #2 is not described ("perform following mathematical expression", what is that? It's not put into the post), so it cannot be solved.