Basic Types
Exercises
Question 7.1
Give the decimal value of each of the following integer constants.
0770x77OXABC
- Program
#include <stdio.h>
int main (void) {
int num_1 = 077; // need to precede the number with 0 to tell the compiler it's a octal number
int num_2 = 0x77; // need to precede the number with 0x to tell the compiler it's a hex number
int num_3 = 0XABC;
printf("077 in decimal is: %d\n", num_1);
Question 7.2
Which of the following are not legal constants in C? Classify each legal constant as either integer or floating-point.
010E232.1E+50790100_0003.978e-2
- Answer
- Program
010E2, 32.1E+5 and 3.978e-2 are valid floating-point but 0790 and 100_000 are not valid integer numbers. (or any valid constant). 0790 is invalid since 9 is not a valid number in octal and 100_000 is invalid since _000 is an invalid suffix on integer constant.
#include <stdio.h>
int main (void) {
printf("010E2 is %f\n", 010E2);
printf("32.1E+5 is %f\n", 32.1E+5);
// printf("0790 is %d\n", 0790); // invalid since 9 is not a valid number
// printf("100_000 is %d\n", 100_000); // invalid since _000 is an invalid suffix on integer constant
printf("3.978e-2 is %f\n", 3.978e-2);
Question 7.3
Which of the following are not legal types in C?
short unsigned intshort floatlong doubleunsigned long
- Answer
Only short float is not a legal type in C. short unsigned int is the same as unsigned short int, long double is a new type introduced in C99, and unsigned long is a short-hand form for the type unsigned long int.
Question 7.4
If c is a variable of type char, which one of the following statements is illegal?
i += c; /* i has type int */c = 2 * c - 1;putchar(c);printf(c);
- Answer
Statements (a), (b), and (c) are legal statements, whereas statement (d) is illegal. since char is basically an 8-bit integer, c treats the variable c as an integer, so the ascii value of the character stored in the variable is added to the variable i. The second statement is also valid statement for the reasons stated for the first statement. putchar function puts a character in the standard output. But the last statement is invalid as printf requires the conversion specification inside a string as the first argument to represent the variable. The legal statement would be: printf("%c", c);
Question 7.5
Which one of the following is not a legal way to write the number 65? (Assume that the character set is ASCII.)
'A'Ob1OOOOO101010x41
- Answer
Since 'A' translates to 65 when the character is represented as an integer (65 is the ASCII code to represent the character A), it is a legal way to write the number 65. The second value is not legal since it represents an octal number but b is not a legal number in octal constant. 0101 is an octal number which converts to 65 in decimal, so it too is legal. 0x41 is a hex number which converts to 65 in decimal, hence it also is a legal way to write the number 65.
Question 7.6
For each of the following items of data, specify which one of the types char, short, int, or long is the smallest one guaranteed to be large enough to store the item.
- Days in a month
- Days in a year
- Minutes in a day
- Seconds in a day
- Answer
The days in a month ranges from 28-31, so it can be represented in a char variable (although not recommened) as the variable is basically an 8-bit integer. It is not recommened as the character representation of the values from 0 to 31 is not a valid character but special characters that includes null character, tabs, line feed, form feed and so on. It would be best to represent the days using the short type. The days in a year is 365 or 366 (leap year), so it does not require any more than a short variable. There are 1440 minutes in a day, so it can also be represented in a short variable. There are 86400 seconds in a day, so short and int are not enough to represent all the values (unless it is a 64-bit machine which can represent all the numbers in an int variable). So the preferred type should be a long variable.
Question 7.7
For each of the following character escapes, give the equivalent octal escape. (Assume that the character set is ASCII.) You may wish to consult Appendix E, which lists the numerical codes for ASCII characters.
\b\n\r\t
- Answer
To represent the character escapes in octal, we need to first see the corresponding ASCII value of the character escapes. The value should be preceded by the \. So the corresponding representation in octal will be:
\010or\10\012or\12\015or\15\011or\11
Question 7.8
Repeat Exercise 7, but give the equivalent hexadecimal escape.
- Answer
To represent the character escapes in hex, we need to see the corresponding ASCII value of the character escapes. Also, the value should be preceded by \x.
\xa\xc\xf\xb
Question 7.9
Suppose that i and j are variables of type int. What is the type of the expression i / j + 'a'?
- Answer
Since i and j are int and 'a' is a character, integer promotion occurs which promotes the type of char to int. i / j will not be a integer, rather the decimal point and the value after the decimal point (if any) gets truncated, but the result of the entire expression will be an integer.
Question 7.10
Suppose that i is a variable of type int, j is a variable of type long, and k is a variable of type unsigned int. What is the type of the expression i + (int) j * k?
- Answer
The expression broken down using braces turns into (i + (((int) j) * k)). First the cast operation is performed that converts the variable j from long to int. Now, integer promotion is applied to the variable j, making it an unsigned int. This would result in the multiplication to result a value of unsigned int. When the result is added to i, firstly, i is promoted to unsigned int and the type of the entire expression will be unsigned int.
Question 7.11
Suppose that i is a variable of type int, f is a variable of type float, and d is a variable of type double. What is the type of the expression i * f / d?
- Answer
The expression has the same precedence of operators in use, so the compiler uses the rules of associativity to break down this expression into sub-expression. The expression is broken down as: ((i * f) / d). Since i is of type int and f is a float, the integer promotion is applied which results the sub-expression to result in floating type. When it is divided by variable d which is of type double, promotion occurs which promotes the float type to double type. So, the resulting type of the entire expression will be of type double.
Question 7.12
Suppose that i is a variable of type int, f is a variable of type float, and d is a variable of type double. Explain what conversions take place during the execution of the following statement:
d = i + f;
- Answer
The expression (i + f) will have the type float as i is promoted to type float. As = is too an assignment operator, the type of the resulting value is promoted to the one with highest precedence, i.e. of type double.
Question 7.13
Assume that a program contains the following declarations:
char c = '\1';
short s = 2;
int i = -3;
long m = 5;
float f = 6.5f;
double d = 7.5;
Give the value and the type of each expression listed below.
|
|
|
- Answer
For now, the value of c will be converted to the value of integer 1 (since \1 is an ASCII octal representation that results 1 in decimal value as well). Moving on to individual cases:
- In
c * i,cis promoted to typeintdue to integer promotion, which results in the value of-3. - In
s + m,sis promoted to typelong, and the resulting value will be7of typelong. - In
f / c,cis converted to typefloat, and the resulting value will be6.500000of typefloat. - In
d / s,sis converted to typedouble, and the resulting value will be7.500000000000of typedouble. - In
f - d,fis converted to typedouble, and the resulting value will be1.000000000000of typedouble. - In
(int) f,fis explicitly converted to typeint, and the resulting value will be6, and.5will be truncated.
Question 7.14
Does the following statement always compute the fractional part of f correctly (assuming that f and frac_part are float variables)?
frac_part = f - (int) f;
If not, what's the problem?
- Answer
The expression f - (int) f will result in the fractional part of f since (int) f will truncate the decimal values after the decimal point. But before the subtraction happens, the value of (int) f is converted to f, so the result should not have a problem. But, if the value of f exceeds the value which is out of range in the int type, there may be some problem when it is converted to int.
Question 7.15
Use typedef to create types named Int8, Int16, and Int32. Define the types so that they represent 8-bit, 16-bit, and 32-bit integers on your machine.
- Answer
- Program
We can approach this problem in two ways:
- First, we can use the
stdintheader that provides types likeint8_t,int16_t, andint32_t. - Second, we can use
charto represent 8 bit,short intto represent 16 bit, andintto represent 32 bit.
Since, the second one is unreliable on other machines, we'll use the first one.
#include <stdio.h>
#include <stdint.h>
// we can approach this problem in two ways
// first, we can use the stdint header that provides types like int8_t, int16_t, and int32_t.
// second, we can use char to represent 8 bit, short int to represent 16 bit, and int to represent 32 bit.
// Since, the second one is unreliable on other machine, we'll use the first one.
int main (void) {
Programming Projects
Project 7.1
The square2.c program of Section 6.3 will fail (usually by printing strange answers) if i * i exceeds the maximum int value. Run the program and determine the smallest value of n that causes failure. Try changing the type of i to short and running the program again. (Don't forget to update the conversion specifications in the call of printf!) Then try long. From these experiments, what can you conclude about the number of bits used to store integer types on your machine?
- Answer
- Program
For int variable:
999289 999290 | 2146092849 -2146875868 | (max value representation) (the strange answer) |
For short variable:
181 182 | 32761 -32412 | (max value representation) (the strange answer) |
For long variable:
I'm not gonna bother waiting minutes to get a validation that my machine is a 64-bit one.
#include <stdio.h>
int main (void) {
long i, n;
printf("This program prints a table of squares.\n");
printf("Enter number of entries in the table: ");
scanf("%ld", &n);
Project 7.2
Modify the square2.c program of Section 6.3 so that it pauses after every 24 squares and displays the following message:
Press Enter to continue...
After displaying the message, the program should use getchar to read a character, getchar won't allow the program to continue until the user presses the Enter key.
- Program
#include <stdio.h>
int main (void) {
int i, n;
char ch;
printf("This program prints a table of squares.\n");
printf("Enter number of entries in the table: ");
Project 7.3
Modify the sum2.c program of Section 7.1 to sum a series of double values.
- Program
#include <stdio.h>
int main (void) {
double n, sum = 0;
printf("This program sums a series of integers.\n");
printf("Enter integers (0 to terminate): ");
scanf("%lf", &n);
Project 7.4
Write a program that translates an alphabetic phone number into numeric form:
Enter phone number: CALLATT
2255288
(In case you don't have a telephone nearby, here are the letters on the keys: 2=ABC, 3=DEF, 4=GHI, 5=JKL, 6=MNO, 7=PRS. 8=TUV. 9=WXY.) If the original phone number contains nonalphabelic characters (digits or punctuation, for example), leave them unchanged:
Enter phone number: 1-800-CQL-LECT
1-800-265-5328
You may assume that any letters entered by the user are upper case.
- Program
#include <stdio.h>
int main (void) {
char ch;
printf("Enter phone number: ");
// Read characters until newline is encountered
Project 7.5
In the SCRABBLE Crossword Came, players form words using small tiles, each containing a letter and a face value. The face value varies from one letter to another, based on the letter's rarity. (Here are the face values: 1: AEILNORSTU. 2: DG, 3: BCMP, 4: FHVWY, 5: K, 8: JX, 10: QZ.) Write a program that computes the value of a word by summing the values of its letters:
Enter a word: pitfall
Scrabble value: 12
Your program should allow any mixture of lower-case and upper-case letters in the word. Hint: Use the `toupper library function.
- Program
#include <stdio.h>
#include <ctype.h>
int main (void) {
char ch;
int scrabble_value = 0;
printf("Enter a word: ");
Project 7.6
Write a program that prints the values of sizeof(int), sizeof(short), sizeof(long), sizeof(float), sizeof(double) and sizeof(long double).
- Program
#include <stdio.h>
int main (void) {
printf("Size of int is : %zu bytes\n", sizeof(int));
printf("Size of short is : %zu bytes\n", sizeof(short));
printf("Size of long is : %zu bytes\n", sizeof(long));
printf("Size of float is : %zu bytes\n", sizeof(float));
printf("Size of double is : %zu bytes\n", sizeof(double));
Project 7.7
Modify Programming Project 6 from Chapter 3 so that the user may add, subtract, multiply, or divide two fractions (by entering either +, -, *, or / between the fractions).
- Program
#include <stdio.h>
int main (void) {
int num_1, num_2;
int denom_1, denom_2;
char ch;
printf("Enter two fractions separated by +, -, *, or /: ");
Project 7.8
Modify Programming Project 8 from Chapter 5 so that the user enters a time using the 12-hour clock. The input will have the form hours:minutes followed by either A, P, AM, or PM (either lower-case or upper-case). White space is allowed (but not required) between the numerical time and the AM/PM indicator. Examples of valid input:
1:15P
1:15PM
1:15p
1:15pm
1:15 P
1:15 PM
1:15 p
1:15 pm
You may assume that the input has one of these forms; there is no need to test for errors.
- Program
#include <stdio.h>
int main (void) {
// declare departure time variables
int departure_1, departure_2, departure_3, departure_4;
int departure_5, departure_6, departure_7, departure_8;
// initialize deprature time in minutes
Project 7.9
Write a program that asks the user for a 12-hour time, then displays the time in 24-hour form:
Enter a 12-hour time: 9:11 PM
Equivalent 24-hour time: 21:11
See Programming Project 8 for a description of the input format.
- Program
#include <stdio.h>
int main (void) {
int hour, minute;
char ch;
printf("Enter a 12-hour time: ");
scanf("%d:%d %c", &hour, &minute, &ch);
Project 7.10
Write a program that counts the number of vowels (a, e, i, o, and u) in a sentence:
Enter a sentence: And that's the way it is.
Your sentence contains 6 vowels.
- Program
#include <stdio.h>
#include <ctype.h>
int main (void) {
char ch;
int vowel_count = 0;
printf("Enter a sentence: ");
Project 7.11
Write a program that takes a first name and last name entered by the user and displays the last name, a comma, and the first initial, followed by a period:
Enter a first and last name: Lloyd Fosdick
Fosdick, L.
The user's input may contain extra spaces before the first name, between the first and last names, and after the last name.
- Program
#include <stdio.h>
int main (void) {
char first_initial, ch;
printf("Enter a first and last name: ");
first_initial = getchar();
Project 7.12
Write a program that evaluates an expression:
Enter an expression: 1+2.5*3
Value of expression: 10.5
The operands in the expression are floating-point numbers; the operators are +, -, *, and /. The expression is evaluated from left to right (no operator takes precedence over any other operator).
- Program
#include <stdio.h>
int main (void) {
float operand_1, operand_2;
int decimal_1, decimal_2;
decimal_1 = 0;
decimal_2 = 0;
operand_1 = 0.0f;
Project 7.13
Write a program that calculates the average word length for a sentence:
Enter a sentence: It was deja vu all over again.
Average word length: 3.4
For simplicity, your program should consider a punctuation mark to be part of the word to which it is attached. Display the average word length to one decimal place.
- Program
#include <stdio.h>
int main (void) {
int word_count = 0;
int character_count = 0;
float avg_word_length = 0.0f;
char ch;
Project 7.14
Write a program that uses Newton's method to compute the square root of a positive floating-point number:
Enter a positive number: 3
Square root: 1.73205
Let be the number entered by the user. Newton's method requires an initial guess for the square root of (we'll use = 1). Successive guesses are found by computing the average of and . The following table shows how the square root of 3 would be found:
| Average of and | |||
|---|---|---|---|
| 3 | 1 | 3 | 2 |
| 3 | 2 | 1.5 | 1.75 |
| 3 | 1.75 | 1.71429 | 1.73214 |
| 3 | 1.73214 | 1.73196 | 1.73205 |
| 3 | 1.73205 | 1.73205 | 1.73205 |
Note that the values of get progressively closer to the true square root of . For greater accuracy, your program should use variables of type double rather than float. Have the program terminate when the absolute value of the difference between the old value of and the new value of is less than the product of .00001 and . Hint: Call the fabs function to find the absolute value of a double. (You'll need to include the <math.h> header at the beginning of your program in order to use fabs.)
- Program
#include <stdio.h>
#include <math.h>
int main (void) {
double x, y, division, difference;
double old_y;
printf("Enter a positive number: ");
Project 7.15
Write a program that computes the factorial of a positive integer:
Enter a positive integer: 6
Factorial of 6: 720
- Use a
shortvariable to store the value of the factorial. What is the largest value of for which the program correctly prints the factorial of ? - Repeat part (a), using an
intvariable instead. - Repeat part (a), using a
longvariable instead. - Repeat part (a), using a
long longvariable instead (if your compiler supports thelong longtype). - Repeat part (a), using a
floatvariable instead. - Repeat part (a), using a
doublevariable instead. - Repeat part (a), using a
long doublevariable instead.
In cases (e)-(g). the program will display a close approximation of the factorial, not necessarily the exact value.
- Answer
- Program
Largest number for which the factorial will be not give garbage value:
short int: 7 → 5040 int: 15 → 2004310016 long: 20 → 2432902008176640000 long long: 20 → 2432902008176640000 float: 34 → 295232822996533287161359432338880069632 double: 170 → 7257415615307994045399635715589591467896184117242257803405544211755693246215271577444614997868077640013184176271985826801597743247247979077995336619429980685793285768053360886112149825437081356365699043287884614002788490694530469661753007801896962563721104619242357348735986883814984039817295623520648167424.000000 long double: 170 → 7257415615307994045399635715589591467896184117242257803405544211755693246215271577444614997868077640013184176271985826801597743247247979077995336619429980685793285768053360886112149825437081356365699043287884614002788490694530469661753007801896962563721104619242357348735986883814984039817295623520648167424.000000
For reference, check point #12 (since my machine is of 64-bit architecture), #15, and #41 to get a gist of maximum values for the implemented data types.
#include <stdio.h>
int main (void) {
int option;
int count = 1;
printf("Welcome to the factorial calculator!\n");
printf("Choose any of the following type to calculate factorial:\n");