C course menu
Type Conversion and Casting in C: Implicit Conversions, Integer Division and Casts
Learn type conversion in C: implicit conversions and the usual arithmetic conversions, integer division and how to avoid it, explicit casts, truncation when converting decimals to integers, signed and unsigned comparison traps, and converting strings to numbers with strtol and atof.
On this page
C converts values between types automatically in many situations, and lets you convert them explicitly with a cast. Knowing the rules prevents some of the most common C bugs.
Integer division#
When both operands are integers, / performs integer division and throws away the fractional part:
int total = 7;
int people = 2;
printf("%d\n", total / people);
printf("%f\n", total / people * 1.0);
printf("%f\n", (double)total / people);3
3.000000
3.5000007 / 2is3.total / people * 1.0still gives3.0: the division happens first, as integers.(double)total / peopleconvertstotalfirst, so the division is done with decimals.
Implicit conversions#
When an expression mixes types, C converts the "smaller" operand to the "larger" type before calculating (the usual arithmetic conversions). For example, int mixed with double becomes double:
int items = 3;
double price = 49.5;
double total = items * price; /* items is converted to double */
printf("%.1f\n", total);148.5Assigning to a variable converts the value to the variable's type, which can lose information:
double average = 7.9;
int whole = average; /* truncated towards zero, not rounded */
printf("%d\n", whole);
printf("%d\n", (int)-7.9);7
-7Converting a decimal to an integer truncates (drops the fraction). To round, use round() from math.h, or add 0.5 for positive numbers.
Explicit casts#
A cast (type)expression converts a value on purpose:
#include <stdio.h>
#include <math.h>
int main(void) {
int marks = 457, subjects = 5;
double avg = (double)marks / subjects;
printf("%.2f\n", avg);
printf("%d\n", (int)round(avg));
printf("%c\n", (char)66);
return 0;
}91.40
91
BCasts also silence warnings, so use them only when you mean it.
Characters and integers#
char values take part in arithmetic as integers:
char c = 'a';
printf("%c\n", c - 32); /* 'a' (97) - 32 = 'A' (65) */
printf("%d\n", '9' - '0');A
9toupper() from ctype.h is the clearer way to change case.
The signed and unsigned trap#
When a signed and an unsigned value of the same size are compared, the signed one is converted to unsigned, so negative numbers become huge:
int balance = -1;
unsigned int limit = 10;
if (balance < limit) {
printf("less\n");
} else {
printf("not less (!)\n");
}not less (!)-1 converted to unsigned int is 4294967295. GCC warns about this with -Wall -Wextra. Avoid mixing signed and unsigned values in comparisons; this often happens with sizeof and strlen, which return the unsigned type size_t.
Strings to numbers#
Text from the user or files must be converted:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *text = "42 apples";
char *end;
long n = strtol(text, &end, 10);
printf("%ld, rest: \"%s\"\n", n, end);
double d = strtod("3.75", NULL);
printf("%.2f\n", d);
printf("%d\n", atoi("123"));
return 0;
}42, rest: " apples"
3.75
123strtol(andstrtoll,strtoul) convert to integers and report where parsing stopped, so you can detect invalid input.strtodconverts todouble.atoiandatofare simpler but cannot report errors:atoi("abc")just returns 0. Preferstrtolfor real input.
Numbers to strings are done with snprintf: snprintf(buffer, sizeof buffer, "%d", n);.
Practice#
Practice exercise
Three students scored 78, 85 and 90. Print the average correctly to two decimal places, then print it rounded to the nearest whole number.
Show solution
#include <stdio.h>
#include <math.h>
int main(void) {
int a = 78, b = 85, c = 90;
double avg = (a + b + c) / 3.0;
printf("%.2f\n", avg);
printf("%d\n", (int)round(avg));
return 0;
}84.33
84Dividing by 3.0 (a double) avoids integer division.
Key takeaway#
Finished this lesson?