1. Functions — the basics
-1.0000 -1.0000 1.0000 -0.8415 -0.9000 -0.7290 0.9000 -0.7833 -0.8000 -0.5120 0.8000 -0.7174 . . . 0.9000 0.7290 0.9000 0.7833 1.0000 1.0000 1.0000 0.8415
Write functions that receive a real number parameter, and return:
cube()
– its third power,absolute()
– its absolute value (there is afabs()
library function but do not use it this time)!
Write a program that tabulates the values of a
, a3
, |a|
and sin(a)
using 4 decimal digits after the decimal point from a = −1 to +1, stepping by 0.1! Include math.h
to use sin
.
Solution
#include <stdio.h> #include <math.h> double cube(double x) { return x*x*x; /* or: return pow(x, 3); */ } double absolute(double x) { if (x < 0) return -x; else return x; /* or: return x < 0 ? -x : x; */ } int main() { for (double a = -1; a <= +1; a += 0.1) printf("%10.4f %10.4f %10.4f %10.4f\n", a, cube(a), absolute(a), sin(a)); return 0; }
2. Stammering
Stammering (or stuttering) is a speech disorder when syllables (usually the first one in the words) are unintentionally repeated. Look at the following ahartihifihicihiahal stahammehereher cohodehe (artificial stammerer code)
#include <stdio.h> int main(void) { char c; while (scanf("%c", &c) == 1) { if (c=='a' || c=='e' || c=='i' || c=='o' || c=='u') printf("%ch%c", c, c); else printf("%c", c); } return 0; }
Write a function to distinguish vowels from other letters (the function receives a character, and returns whether it is a vovel or not).
Modify the program above to use this function in main()
.
Solution
#include <stdio.h> #include <stdbool.h> /* Returns true if the function parameter is a vowel. */ bool vowel(char c) { return c=='a' || c=='e' || c=='i' || c=='o' || c=='u'; } int main() { char c; while (scanf("%c", &c) != EOF) if (vowel(c)) printf("%ch%c", c, c); else printf("%c", c); return 0; }
How to make it work for words starting with a capital? Like, for the word „Apart” „Ahapahart” should be printed. To accomplish this the program must be able to identify uppercase vowels, too. The original
character should be printed before h
, and the lowercase counterpart after it. You can use your existing
vowel()
function for deciding but always pass the lowercase letter to it.
Hint
There are character handling library functions in #include <ctype.h>
. One of them is tolower()
.
The tolower(c)
expression is the lowercase counterpart of c
if it is an uppercase letter, for any other
character it returns the original character.
Solution
Let us send to the vowel
function the lowercase variant of the character:
vowel(tolower(c))
. However, when printing to the screen, first the original character c
needs to be displayed,
then the lowercase variant of the character tolower(c)
. You can use the built-in tolower()
function
(#include <ctype.h>
), or your own one.
while (scanf("%c", &c)==1) if (vowel(tolower(c))) printf("%cv%c", c, tolower(c)); else printf("%c", c);
A twin prime is a prime number that is either 2 less or 2 more than another prime number - for example, either member of the twin prime pair (41, 43). In other words, a twin prime is a prime that has a prime gap of two.
The first couple of twin primes are (3, 5), (5, 7) and (11, 13). Write a C program to find the 60th twin prime! Extend the program to check whether the number between the twin primes has any digit equal to 5. Avoid code duplication, use functions wherever reasonable! Follow the top-down design methodology.
Hint
First, write a function that receives an integer number, and returns whether the number is prime. Then, an other function is needed to determine if a number contains a certain digit. The main should be as small and compact as possible, it should make use of the two functions.
Solution
The principle of the solution
The next twin prime can be found by the following algorithm:
while (!(prime(number) && prime(number + 2))) number += 2;
For detecting digit 5 we need to consider each digit of the number one by one: the value of number % 10
gives the last digit.
#include <stdio.h> #include <stdbool.h> /* decides whether the number is a prime or not */ int prime(int number) { for (int divisor = 2; divisor < number; divisor++) if (number % divisor == 0) return 0; return 1; } /* decides whether the number has a specific digit included or not */ int contains(int number, int digit) { while (number > 0) { if (number % 10 == digit) return 1; number /= 10; } return 0; } int main(void) { int number, i; /* initialization */ number = 1; i = 0; while (i < 60) { /* find next twin primes */ number += 2; while (!(prime(number) && prime(number + 2))) number += 2; ++i; } printf("%dth twin prime: %d %d\n", 60, number, number+2); /* second part: check if the number inbetween contains digit 5 */ printf("The number inbetween %s digit 5.\n", contains(number + 1, 5) ? "does contain":"does not contain"); return 0; }
4. Menu controlled program
Create a simple menu controlled program! The program stores a number with an initial value of n = 1
.
Then the program should print the actual value of n
and the menu below. After the user selects a menu item
(scanf()
) the program should do whatever the user requested and print the value of n
and the menu!
These must be repeated as long as the user chooses anything but the Exit menu option! Use switch()
and post-testing
do ... while()
loop.
printf("0. Restore the initial value (n = 1)\n" "1. Add 1\n" "2. Negate the number (+/-)\n" "3. Multiple by 2\n" "9. Exit\n");
Realize each operation in a (tiny) function that receives the value of n
as a parameter and
returns the modified value! Your main()
can only call these functions to change the value of
n
.
Why is this task so important?
Note that the main function controls the calling of the other functions. It will call the appropriate subprogram according to the choice of the user, and when they return main gets back the control. The main program and the subprograms communicate via function parameters and return values.
Solution
To select the proper action it is recommended to use a switch()
instruction. In this way, we can list the
corresponding function calls one-by-one, below each other. Care has to be taken to not to forget the break
.
The menu can be put into the body of a loop. This can be a bottom-test loop, since we have to execute the body at least once,
to print the options and let the user select one.
#include <stdio.h> int reset() { return 1; } int increment(int a) { return a+1; } int invert(int a) { return -a; } int duplicate(int a) { return 2*a; } int main() { int menuselection; int a = reset(); do { printf("a = %d\n\n", a); printf( "0. Re-setting the variable (a = 1)\n" "1. Increment by 1\n" "2. Invert the sign\n" "3. Multiply by 2\n" "9. Exit\n" "? "); scanf("%d", &menuselection); switch (menuselection) { case 0: a = reset(); break; case 1: a = increment(a); break; case 2: a = invert(a); break; case 3: a = duplicate(a); break; case 9: /* nothing, we are going to exit */ break; default: printf("HEY!\n"); break; } printf("\n"); /* cosmetic line break */ } while (menuselection != 9); return 0; }