This blog is not for beginers to C language. If you are one, read any C book (preferrably k&r) and then come back to this.
1> One divided by 3 is 0?
What is the value of m here ?
int n=1;
int p = 3;
float m;
m = n/p;
Did you say 0.3333. The answer is wrong. m is zero. You see here n and p are integers. Hence n/p gives integer result which is 0. Now m is assigned to 0.00.
float p = 2 ,q;
int m,n;
m=1; n=3;
q = m/n * p;
Now tell me what is the value of q in the above code. Don't tell me that it is 0.6667. It is again zero. Now you may think that as p is a non-integer, the calculation should happen in floating point arithmetic. But that happens after m/n is performed. In a division if both numerator and denominator are integers, result is a truncated integer. This zero is now multiplied by 2 which again gives 0.
2> Modulo operator does not compile ?
float a = 2;
int m = 15 % a;
What is the value of m? It is not 1. The code produces a syntax error which says something like '%' : illegal, right operand has type 'float'. Because Both operands for % operator should be integers.
3> Division by zero is not caught by compiler
float p = 2 ,q;
int m,n;
m=1; n=0;
q = m/n * p;
Do you think 4th line in this code produces syntax error and saves you from further trouble. No. C compilers think you programmers are very smart and even very careful. So the code compiles and then executes and gives a run time exception division by zero. Always ensure that your denominator is not zero.
4> Lazy evaluation
Let us ensure that denominator is not zero when performing a division
float p = 2 ,q;
int m,n,s=3;
m=1; n=0;
if (s == m/n && n!=0)
printf("%d",s);
else
printf("Denominator is zero.");
OK, we have taken care of checking denominator is non-zero. Are we saved? Not yet. This also produces run time error for s==m/n.
Let us interchange the operands of && operator , because && is cumulative i.e. A&&B is same is B&&A. Now our code is
float p = 2 ,q;
int m,n,s=3;
m=1; n=0;
if (n!=0 && s==m/n)
printf("%d",s);
else
printf("Denominator is zero.");
Now the code runs correctly. What went right? Well this is called lazy evaluation. Logical and and or operators have left to right associativity (i.e. they are evaluated from left to right) and the evaluation stops when an unambiguous answer is obtained. If n is zero, first condition is false and irrespective of second condition, the result will be false. Hence C does not evaluate the second operand. So no division by zero and no run time error.
In situations like these, lazy evaluation (also called short circuiting) comes to your rescue.
Last question.
5> Isn't -2 less than 4 ?
May not be.
t = -2 "<" sizeof(int);
Sizeof int is 4 for all 32 bit processors. So -2"<"4 ? Is true. So t must be true that is 1. No! You get t as 0? Howzzat?
sizeof operator yields an unsigned integer. Now < operator has one operand -2 as int and another sizeof(int) as unsigned int which is larger data type. So compiler converts both operands into unsigned. -2becomes 0xfffffffe when converted to unsigned. This is certainly not less than 4. Hence the result.
Thursday, April 17, 2008
Tuesday, April 1, 2008
C data types
Data types in C
When someone asks you in an interview, how many data types are present in C, you will start counting your fingers int, short int, unsigned int, double, float etc. But the right answer might be
There are 4 data types in C which are int, float, char and double.
Now what about short, long etc. Well, these can be called as data type modifiers. These can be used with int as
Long int
Short int
Unsigned int
Signed int
Long unsigned int
Short unsigned int
And with char as
Signed char
Unsigned char
int data type
You all know what is an int. It is a basic number without any fractional information which will be stored internally in binary (have to tell). Now what about negative integers? How are these stored? C stores these in either 1’s complement or 2’s complement format. This needs one bit which is MSB for storing the sign of the number (1 –indicates negative and 0 indicates positive ). Hence the largest number which can be stored will be not as big as you expect. (e.g. if an int is stored using 16 bits, the largest int which can be stored is not 216 -1 but instead 216-1 – 1.
Now how big is an int. Well it is not infinity because computer should store and manipulate the numbers using CPU registers which are having limited bit length. That is exactly how big is an int as big as a register (or in other words the size of an int is word length of the computer). This Turbo C has set a misconception in students. Turbo C shows size of an int as 16 bits or 2 bytes even on a Pentium machine which is 32 bit processor. So students will either think an int is 2 bytes or at the most they may say int size depends on the compiler. No, int size does not work on the compiler. But turbo c works in real mode which is compatible with X86 i.e. 16 bit processor. [u1] Hence all this confusion. Find the size of int in Visual c++ compiler in Windows or gcc compiler to get the correct picture.
The size of an int is word size of the computer
Now what are the differences between short, long and unsigned and signed ints. Well ANSI standard does not say much. It just says that
Sizeof short int<=sizeof int<=sizeof long int Most of the implementations provide short int as 16 bits and long int as 32 bits. Now unsigned prefix will make the range from 0 to 2Xmax as that of ordinary int, or short int or long int. Please keep in mind that default is signed. You can also define variables as short a; unsigned long b; These are valid because C adds default int to these variable declarations. (Remember if a function type is not declared, it is treated as a function returing int -- For that matter even if we declare static m; M is treated as static integer. Int literals can have only digits 0 to 9. If the int literal has 0 as a prefix, then it is treated as an octal value. Similarly if the int literal has 0x as prefix, it is treated as hexadecimal value. (If you already do not know, in hexadecimal a-f or A-F represent 10 to 15) If an int literal has a suffix of l, then it’s a long integer. If it has suffix of u, it is unsigned integer. Question : Which of the following are valid integers in a 16 bit computer. 40000 0890 0xabcd char data type char in C stored using some code normally ASCII. This is a 7 bit code. Size of a char is always 1 byte. Now a char is stored as an integer which represents the given character in the given coding scheme. i.e. the alphabet ‘A’ is stored as 65 A character literal should be enclosed in single quotes. char c =’A’; Some of the characters can not be typed. E.g. how do you type enter key which will take the cursor to next line. Or how do you type tab character. Such characters have some escape sequences. Escape sequences are char constants which start with backward slash. Some of the escape sequences are ‘\t’ tab ‘\n’ new line character ‘\r’ carriage return ‘\f’ form feed ‘\b’ bell ‘\nnn’ character whose code in octal in nnn char is an integer data type. That is to say it can be used in any arithmetic calculation. char c =’A’; int m=c+2; Now the value of m will be 67. A char can also be used in a for loop. Char can use datatype modifier signed and unsigned. Unsigned char will have a range from 0 to 255 whereas a signed char will have a range from -128 to 127. If we use a char variable without these modifiers, do we get a signed char or unsigned char ? That does depend on the implementation. So if you want to write portable programs, always explicitly specify signed/ unsigned. Another thing to remember here is any char variable in an expression is converted into int. Hence you will notice that sizeof(‘A’) is 4 bytes (on a 32 bit processor) instead of 1 byte. (In C++ this size is 1 byte because c++ is strongly typed language) When do you use a char. Obviously when you want to use non-numerical information. But please remember a char can not store your complete name. Name is not a character. It has many characters. Such strings have to be stored using an array of characters. char a[10]=”Usha”; A string literal should be enclosed within double quotes. float data types floating point data types are fractional numbers. They are so called because you can move around the decimal point by varying the exponent. Normally these numbers are stored in two parts – viz mantissa and exponent. E.g. if the number is 1.7e-5 then mantissa is 1.7 and exponent is -5. And by the way its value is 0.0000175. These float numbers can be stored only with limited precision. Now if the number can be stored with 6 digits precision, then the number will be accurate for first 6 digits. Double data type will normally have double the precision of the float type. All float arithmetic calculations are performed in double precision. And in any expression a float will be converted to double. Now C standard does not mention anything about how a float has to be stored. But most compilers use IEEE 754 standard. This stores the mantissa in normalized form and exponent by adding 127 for float and 1024 for double[u2] . The header file float.h will have macros FLT_MAX, FLT_MIN, FLT_DGT, DBL_MAX etc.
Always keep in mind that floats are not very accurate. Hence you should be careful when comparing a float for equality. Check this program.
float a = 1.7;
if (a==1.7)
printf(“Equal”);
else
printf(“Unequal”);
float literals can be written either in decimal notation or scientific notation with e or E specifying exponent to the base 10. A float literal by default is double literal. To make it float, suffix with f or F.
float a = 1.7f;
Hence size of a 1.7 will be 8 bytes (which is the size of double) rather than 4 bytes.
Exercises :
1> Find the sizes of unsigned int , short int and long int, double and float
Hint : use sizeof operator
2> Find the maximum, minimum short and long integer and unsigned integer without using loop
Hint : Use limits.h file
3> Find out whether your compiler uses signed char as default or unsigned char.
When someone asks you in an interview, how many data types are present in C, you will start counting your fingers int, short int, unsigned int, double, float etc. But the right answer might be
There are 4 data types in C which are int, float, char and double.
Now what about short, long etc. Well, these can be called as data type modifiers. These can be used with int as
Long int
Short int
Unsigned int
Signed int
Long unsigned int
Short unsigned int
And with char as
Signed char
Unsigned char
int data type
You all know what is an int. It is a basic number without any fractional information which will be stored internally in binary (have to tell). Now what about negative integers? How are these stored? C stores these in either 1’s complement or 2’s complement format. This needs one bit which is MSB for storing the sign of the number (1 –indicates negative and 0 indicates positive ). Hence the largest number which can be stored will be not as big as you expect. (e.g. if an int is stored using 16 bits, the largest int which can be stored is not 216 -1 but instead 216-1 – 1.
Now how big is an int. Well it is not infinity because computer should store and manipulate the numbers using CPU registers which are having limited bit length. That is exactly how big is an int as big as a register (or in other words the size of an int is word length of the computer). This Turbo C has set a misconception in students. Turbo C shows size of an int as 16 bits or 2 bytes even on a Pentium machine which is 32 bit processor. So students will either think an int is 2 bytes or at the most they may say int size depends on the compiler. No, int size does not work on the compiler. But turbo c works in real mode which is compatible with X86 i.e. 16 bit processor. [u1] Hence all this confusion. Find the size of int in Visual c++ compiler in Windows or gcc compiler to get the correct picture.
The size of an int is word size of the computer
Now what are the differences between short, long and unsigned and signed ints. Well ANSI standard does not say much. It just says that
Sizeof short int<=sizeof int<=sizeof long int Most of the implementations provide short int as 16 bits and long int as 32 bits. Now unsigned prefix will make the range from 0 to 2Xmax as that of ordinary int, or short int or long int. Please keep in mind that default is signed. You can also define variables as short a; unsigned long b; These are valid because C adds default int to these variable declarations. (Remember if a function type is not declared, it is treated as a function returing int -- For that matter even if we declare static m; M is treated as static integer. Int literals can have only digits 0 to 9. If the int literal has 0 as a prefix, then it is treated as an octal value. Similarly if the int literal has 0x as prefix, it is treated as hexadecimal value. (If you already do not know, in hexadecimal a-f or A-F represent 10 to 15) If an int literal has a suffix of l, then it’s a long integer. If it has suffix of u, it is unsigned integer. Question : Which of the following are valid integers in a 16 bit computer. 40000 0890 0xabcd char data type char in C stored using some code normally ASCII. This is a 7 bit code. Size of a char is always 1 byte. Now a char is stored as an integer which represents the given character in the given coding scheme. i.e. the alphabet ‘A’ is stored as 65 A character literal should be enclosed in single quotes. char c =’A’; Some of the characters can not be typed. E.g. how do you type enter key which will take the cursor to next line. Or how do you type tab character. Such characters have some escape sequences. Escape sequences are char constants which start with backward slash. Some of the escape sequences are ‘\t’ tab ‘\n’ new line character ‘\r’ carriage return ‘\f’ form feed ‘\b’ bell ‘\nnn’ character whose code in octal in nnn char is an integer data type. That is to say it can be used in any arithmetic calculation. char c =’A’; int m=c+2; Now the value of m will be 67. A char can also be used in a for loop. Char can use datatype modifier signed and unsigned. Unsigned char will have a range from 0 to 255 whereas a signed char will have a range from -128 to 127. If we use a char variable without these modifiers, do we get a signed char or unsigned char ? That does depend on the implementation. So if you want to write portable programs, always explicitly specify signed/ unsigned. Another thing to remember here is any char variable in an expression is converted into int. Hence you will notice that sizeof(‘A’) is 4 bytes (on a 32 bit processor) instead of 1 byte. (In C++ this size is 1 byte because c++ is strongly typed language) When do you use a char. Obviously when you want to use non-numerical information. But please remember a char can not store your complete name. Name is not a character. It has many characters. Such strings have to be stored using an array of characters. char a[10]=”Usha”; A string literal should be enclosed within double quotes. float data types floating point data types are fractional numbers. They are so called because you can move around the decimal point by varying the exponent. Normally these numbers are stored in two parts – viz mantissa and exponent. E.g. if the number is 1.7e-5 then mantissa is 1.7 and exponent is -5. And by the way its value is 0.0000175. These float numbers can be stored only with limited precision. Now if the number can be stored with 6 digits precision, then the number will be accurate for first 6 digits. Double data type will normally have double the precision of the float type. All float arithmetic calculations are performed in double precision. And in any expression a float will be converted to double. Now C standard does not mention anything about how a float has to be stored. But most compilers use IEEE 754 standard. This stores the mantissa in normalized form and exponent by adding 127 for float and 1024 for double[u2] . The header file float.h will have macros FLT_MAX, FLT_MIN, FLT_DGT, DBL_MAX etc.
Always keep in mind that floats are not very accurate. Hence you should be careful when comparing a float for equality. Check this program.
float a = 1.7;
if (a==1.7)
printf(“Equal”);
else
printf(“Unequal”);
float literals can be written either in decimal notation or scientific notation with e or E specifying exponent to the base 10. A float literal by default is double literal. To make it float, suffix with f or F.
float a = 1.7f;
Hence size of a 1.7 will be 8 bytes (which is the size of double) rather than 4 bytes.
Exercises :
1> Find the sizes of unsigned int , short int and long int, double and float
Hint : use sizeof operator
2> Find the maximum, minimum short and long integer and unsigned integer without using loop
Hint : Use limits.h file
3> Find out whether your compiler uses signed char as default or unsigned char.
Subscribe to:
Posts (Atom)