Skip to main content

Basic Types

Exercises

Question 7.1

Give the decimal value of each of the following integer constants.

  1. 077
  2. 0x77
  3. OXABC
#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.

  1. 010E2
  2. 32.1E+5
  3. 0790
  4. 100_000
  5. 3.978e-2

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.


Question 7.3

Which of the following are not legal types in C?

  1. short unsigned int
  2. short float
  3. long double
  4. unsigned long

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?

  1. i += c; /* i has type int */
  2. c = 2 * c - 1;
  3. putchar(c);
  4. printf(c);

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.)

  1. 'A'
  2. Ob1OOOOO1
  3. 0101
  4. 0x41

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.

  1. Days in a month
  2. Days in a year
  3. Minutes in a day
  4. Seconds in a day

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.

  1. \b
  2. \n
  3. \r
  4. \t

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:

  1. \010 or \10
  2. \012 or \12
  3. \015 or \15
  4. \011 or \11

Question 7.8

Repeat Exercise 7, but give the equivalent hexadecimal escape.

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.

  1. \xa
  2. \xc
  3. \xf
  4. \xb

Question 7.9

Suppose that i and j are variables of type int. What is the type of the expression i / j + 'a'?

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?

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?

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;

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.

  1. c + i
  2. s + m
  1. f / c
  2. d / s
  1. f - d
  2. (int) f

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:

  1. In c * i, c is promoted to type int due to integer promotion, which results in the value of -3.
  2. In s + m, s is promoted to type long, and the resulting value will be 7 of type long.
  3. In f / c, c is converted to type float, and the resulting value will be 6.500000 of type float.
  4. In d / s, s is converted to type double, and the resulting value will be 7.500000000000 of type double.
  5. In f - d, f is converted to type double, and the resulting value will be 1.000000000000 of type double.
  6. In (int) f, f is explicitly converted to type int, and the resulting value will be 6, and .5 will 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?

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.

We can approach this problem in two ways:

  1. First, we can use the stdint header that provides types like int8_t, int16_t, and int32_t.
  2. 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 machines, we'll use the first one.

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?

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.


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.

#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.

#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.

#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.

#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).

#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).

#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.

#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.

#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.

#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.

#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).

#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.

#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 xx be the number entered by the user. Newton's method requires an initial guess yy for the square root of xx (we'll use yy = 1). Successive guesses are found by computing the average of yy and x/yx/y. The following table shows how the square root of 3 would be found:

xxyyx/yx/yAverage of yy and x/yx/y
3132
321.51.75
31.751.714291.73214
31.732141.731961.73205
31.732051.732051.73205

Note that the values of yy get progressively closer to the true square root of xx. 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 yy and the new value of yy is less than the product of .00001 and yy. 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.)

#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

  1. Use a short variable to store the value of the factorial. What is the largest value of nn for which the program correctly prints the factorial of nn?
  2. Repeat part (a), using an int variable instead.
  3. Repeat part (a), using a long variable instead.
  4. Repeat part (a), using a long long variable instead (if your compiler supports the long long type).
  5. Repeat part (a), using a float variable instead.
  6. Repeat part (a), using a double variable instead.
  7. Repeat part (a), using a long double variable instead.

In cases (e)-(g). the program will display a close approximation of the factorial, not necessarily the exact value.

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.