Lecture 8
Data Types in C
The primary data types of C are integers (int),
floating point numbers (float) and characters (char). Are they all? Do the C
programmers use only these 3 data types and create brilliant programs? The
answer is- No! Not only this, the primary data types themselves could be of
several types. For example, a char could be an unsigned char or a
signed char or an int could be a short int or a long
int. Let’s take a tour to know what those are.
Integers: short and long
The range of integer depends on the compiler.
Turb C/C++ is a 16 bit compiler. For such compiler the range of an integer is –32768
to 32767.
Why such range? Well, compiler allocates maximum 16 bits to hold an
integer. Then, in that allocated location in memory, values up to 215 = 32,768 can be stored. Well, if you take both
sides (positive and negative) then the range will be -32,768 to 32,767. Why 215
if 16 bit is allocated, then it should be 216, no? No! Just
one bit is preserved to indicate “Signs”- 0 for positive and 1 for negative.
C offers a variation of the integer data type
that provides what are called short and long integer values. The
intention of providing these variations is to provide integers with different
ranges wherever possible. Though not a rule, short and long integers
would usually occupy two and four bytes respectively.

long variables which hold long integers are
declared using the keyword long, as in,
long int i
;
long int
abc ;
long integers cause the program to run a bit slower,
but the range of values that we can use is expanded tremendously. The value of
a long integer typically can vary from -2147483648 to +2147483647. More
than this you should not need unless you are taking a world census.
If there are such things as longs,
symmetry requires shorts as well—integers that need less space in memory
and thus help speed up program execution. short integer variables are
declared as,
short int
j ;
short int
height ;
C allows the abbreviation of short int to
short and of long int to long. So the declarations made
above can be written as,
long i ;
long abc ;
short j ;
short
height ;
Naturally, most C programmers prefer this
short-cut.
Integers:
signed and unsigned
Sometimes, we know in advance that the value
stored in a given integer variable will always be positive—when it is being
used to only count things, for example. In such a case we can declare the
variable to be unsigned, as in,
unsigned
int num_students ;
With such a declaration, the range of permissible
integer values (for a 16-bit OS) will shift from the range -32768 to +32767 to
the range 0 to 65535. Thus, declaring an integer as unsigned almost
doubles the size of the largest possible value that it can otherwise take. This
so happens because on declaring the integer as unsigned, the left-most
bit is now free and is not used to store the sign of the number. Note that an unsigned
integer still occupies two bytes. This is how an unsigned integer
can be declared:
unsigned
int i ;
unsigned i
;
Like an unsigned int, there also exists
a short unsigned int and a long unsigned int. By default a short
int is a signed short int and a long int is a signed long
int.
Characters:
signed and unsigned
Parallel to signed and unsigned ints
(either short or long), similarly there also exist signed and
unsigned chars, both occupying one byte each, but having different
ranges. To begin with it might appear strange as to how a char can have
a sign. Consider the statement
char ch =
'A' ;
Here what gets stored in ch is the
binary equivalent of the ASCII value of ‘A’ (i.e. binary of 65). And if 65’s
binary can be stored, then -54’s binary can also be stored (in a signed char).
A signed char is same as an ordinary char
and has a range from -128 to +127; whereas, an unsigned char has a
range from 0 to 255. Let us now see a program that illustrates this range:

What output do you expect from this program?
Possibly, 291 and the character corresponding to it. Well, not really.
Surprised? The reason is that ch has been defined as a char, and
a char cannot take a value bigger than +127. Hence when value of ch exceeds
+127, an appropriate value from the other side of the range is picked up and
stored in ch. This value in our case happens to be 35, hence 35 and its
corresponding character #, gets printed out.
Here is another program that would make the
concept clearer.

This program should output ASCII values and
their corresponding characters. Well, No! This is an indefinite loop. The
reason is that ch has been defined as a char, and a char cannot
take values bigger than +127. Hence when value of ch is +127 and we
perform ch++ it becomes -128 instead of +128. -128 is less than 255
hence the condition is still satisfied. Here onwards ch would take
values like -127, -126, -125, .... -2, -1, 0, +1, +2, ... +127, -128, -127,
etc. Thus the value of ch would keep oscillating between -128 to +127,
thereby ensuring that the loop never gets terminated. How do you overcome this
difficulty? Would declaring ch as an unsigned char solve the
problem? Even this would not serve the purpose since when ch reaches a
value 255, ch++ would try to make it 256 which cannot be stored in an unsigned
char. Thus the only alternative is to declare ch as an int.
However, if we are bent upon writing the program using unsigned char, it
can be done as shown below. The program is definitely less elegant, but
workable all the same.

floats
and doubles
A float occupies four bytes in memory
and can range from -3.4e38 to +3.4e38. If this is insufficient then C offers a double
data type that occupies 8 bytes in memory and has a range from -1.7e308 to
+1.7e308. A variable of type double can be declared as,
double a,
population ;
If the situation demands usage of real numbers
that lie even beyond the range offered by double data type, then there
exists a long double that can range from -1.7e4932 to +1.7e4932. A long
double occupies 10 bytes in memory.
You would see that most of the times in C
programming one is required to use either chars or ints and cases
where floats, doubles or long doubles would be used are
indeed rare.
What We
Have Learnt

The
Essence

Constants
Constants refer to fixed values that may not be
altered by the program. For example, 100 is an integer constant. Integer
constants are numbers without fractional part. Floating point constants require
the use of decimal point followed by the number’s fractional part. 11.123 is a
floating point constant.
C also allows you to use constants with
scientific notation. The general form of such notation is-
number E
sign exponent
Please note that there is no space in actual C
declaration. The spaces are provided to understand the components of such
declaration. The sign part is optional. 1234.56 can be written as 123.456E1 (in
everyday math, it is 123.456X101) which is equal to 1234.56.
Character constants are within single quotes.
Both ‘a’ and ‘%’ are character constants. However, there is nothing in C that
prevents you from assigning a character variable a value using a numeric
constant. The ASCII code for ‘A’ is 65. Therefore, both the assignments below
are correct-
char ch;
ch=’A’;
ch=65;
C supports another type of constant- the
string. A string is a set of characters enclosed by double quotes. You have
worked with strings with printf() and scanf(). C allows you to define string
constants, but it does not formally have a string data type. We will see later
that C supports strings with character arrays. To display a string with
printf(), you can either make it part of the control string or you can use %s
format specifier. The following code
shows My Name is Anthony Gonzales on the output screen.
main(){
pritnf(“%s %s %s %s”, “My”, “Name”, “is”,
“Anthony”, “Gonzales”);
}
Type
Conversions in Expressions
Unlike many other computer languages, C lets
you mix different types of data together in one expression. This is a perfectly
valid C code-
char ch;
int i;
float f;
double
outcome;
ch=’0’;
i=10;
f=10.2;
outcome=
ch*i/f;
C provides the functionality of integral
promotion- whenever in an expression a char type and short int type is
used, its value is automatically promoted to int. after the automatic integral
promotion, C will convert all the operands up to the type of the largest
operand. This is called type promotion and is done by
operation-by-operation basis.
main(){
int i=10;
float f=30.25;
printf(“%f”, i*f);
}
In this case, there are two operands i and f
which are integer and float respectively. So, when we use them inside an
operation (i*f), C sees that float is in a better place than integer, it does
an integral promotion to i by making it 10.0 and the result of i*f is thus a
float as well.
In the expression 100.0/(10/3), let us see what
happens. The division of 10 by 3 produces an integer result (as both of them
are integer, neither is in better position) which is 3 and is an integer. Then
the expression becomes 100.0/3. Now, float is in better position than integer.
So, 3 is converted into 3.0 and the expression becomes 100.0/3.0. The result of
this expression is hence a float as well.
char ch;
short i;
unsigned
long ul;
float f;
f/ch – (i*ul)
What is the overall type of the expression-
f/ch – (i*ul)? Well, the first expression to execute there is i*ul (integer
with unsigned long). So, as unsigned long is in better place than integer, the
integer will be turned into unsigned long. Therefore, the expression inside the
brackets is unsigned long. The second expression to execute there is f/ch
(float with character). Since float is in better place, the character will be
turned into a float and the result of f/ch will thus be a float. Now, float –
unsigned long. As float is in a better place, the result will be a float.
I am saying better place – which is the order
of the data types (who will convert who). The order of such data types is as
follows (descending order)-
Long
double
Double
Float
Unsigned
long
Long
Unsigned
So, if there is an expression for unsigned long
with long, the long will be converted to unsigned long.
Type
Conversion in Assignments
-
In
an assignment statement (a=b), in which the type of right side differs with the
type of left side, the type of right side will be converted into the type of
the left side.
-
When
the type of the left side is in a better place than the type of the right side,
there is nothing wrong.
-
But
when the type of the right side is in a better place than the type of the left
side, then data loss may occur.
main(){
char ch;
int i=1000;
ch=i;
printf(“%d”,ch);
}
In this program, the output will not be 1000,
it will be something else. The reason is- you are trying to put a 16-bit number
into 8-bit container. So, digits from 16-bit obviously will be lost.
-When converting from long double to double or
double to float, precision is lost.
- When converting from float to integer,
fractional part is lost.
- If the number is too large to fit in the
target type, a garbage value will result.
main(){
float f=1234.5678;
int i;
i=f;
printf(“%f %d”, f, i);
}
Will make the variable i holding only 1234
omitting the fractional part.
main(){
short int si;
long int li=100000;
si=li;
printf(“%hd”, si);
}
will produce a meaningless value since short
integer can hold maximum 32,767.
main(){
long double iamlongdouble=10.0;
int iaminteger;
iaminteger=iamlongdouble;
printf(“%d”, iaminteger);
}
will show 10 on the screen. Though it is long
double on the right hand side, 10 can be well fit into an integer (on the left
hand side).
main(){
float f=10/3;
printf(“%f”, f);
}
Will print 3.0 on the screen. 10/3 is an
integer as both are integers- which is 3 and as left side (float) is in a
better position, integer 3 is converted into float 3.0.
Type Cast
Sometimes it is necessary to transform the type
of a variable temporarily. Say, you want to use a variable in modulus
operation, so you have declared it as an integer since modulus operation never
accepts variables other than integers. But you may require using the variable
in division as well which may produce a floating point result. You can use type
cast this time. The general form of casting a type is-
(type)
value
where type is any valid C data type.
float
f=100.2;
printf(“%d”,
(int)f);
prints only 100 as type cast (int) f causes the
value of f to be converted into an integer.
Note- you cannot cast a variable that is on the left
side of an assignment statement. This is an invalid statement in C:
int num;
(float)
num=1234.567;
1 comments:
This is great blog! Keep it up. aircon chemical wash
Post a Comment