C Basopr Ref
C Basopr Ref
Objectives
Understand the need of Programming Language Understand the structure of a C program Understand variables and constants Perform basic input & output operations with correct
format specifiers Use of operators and applying precedence rules Understand type casting
Programming Languages
What is the need of Programming Languages? What do you expect a programming language to do? >> To express the algorithm for solving a particular problem so that computer can understand that. What are the intended features? >> Clarity >> Simplicity >> Easy to translate( i.e. compilation should be efficient) >> Support for Abstraction What are the different kinds of programming languages? >> Procedural Languages e.g. C >> Object Oriented Languages e.g. Java >> Functional Languages e.g. LISP >> Logic Programming Languages e.g. Prolog
Preprocessor Commands Type definitions Function prototypes Variables Functions The main function is where a program starts execution. It is generally the first user-written function run when a program starts. The value returned from the main function becomes the exit status of the process, though the C standard only ascribes specific meaning to two values: for normal exit it is taken as 0 i.e. by specifying return 0;
Documentation Section ..... .....Link Section ..... .....Definition Section ..... .....Global declaration Section ..... .....main() function section .....{ ..........Declaration Section ..... ..........Executable Section .....} .....Sub-program Section .....function1 .....{ ..........Statements .....} .....function2 .....{ ..........Statements .....} .....function3 .....{ ..........Statements .....}
Example C program
/******************************************************************************* Example Program ********************************************************************************/
#include <stdio.h> int main() { printf("hello, world\n"); /* some very clever code I haven't quite sorted out yet. */ printf("the solution to the problem of life, the universe and everything is"); /* more very clever code still to be developed */ return 0; }
Identifiers
In computer languages identifiers are textual tokens (also called symbols) which name language entities. Some of the kinds of entities an identifier denotes include variables, types, labels, subroutines, and packages. Computer languages usually place restrictions on what characters may appear in an identifier. C Programming Identifier rules
Identifiers must begin with a letter of the alphabet. In C, the underscore character (_) is considered a letter. The first letter may be followed by a sequence of letters and / or digits. The compiler regards upper case and lower case No variable name may be a keyword.
Example
Grosspay, count, _total, PI, top_value, max123 89_var this is not allowed
Variables are those whose value can be changed during the course of execution of the program. That way, the compiler knows what the variables are called and what type of variables they are (what values they can contain).
double - data type - double is used to define BIG floating point numbers. Generally, it reserves twice the storage for the number.
double Atoms; Atoms = 2500000;
10
The modifiers define the amount of storage allocated to the variable. The amount of storage allocated is not cast in stone. ANSI has the following rules:
short int <= int <= long int float <= double <= long double
What this means is that a 'short int' should assign less than or the same amount of storage as an 'int' and the 'int' should be less or the same bytes than a 'long int'. So the size of the data types may change from platform( Underlying architecture, compiler and OS) to platform but above rules are to be followed. Guidelines for variable naming
11
Type short int unsigned short int unsigned int int long int signed char unsigned char float Double long double
Bytes Bits 2 2 4 4 4 1 1 4 8 12 16 16 32 32 32 8 8 32 64 96
Range -32,678 -> +32,767 0 -> +65,535 0 -> +4,294,967,295 -2,147,483,648 -> +2,147,483,647 -2,147,483,648 -> +2,147,483,647 -128 -> +127 0 -> +255
12
const
The const qualifier is used to tell C that the variable value can not change after initialization. const float pi=3.14159; pi cannot be changed at a later time within the program.
Example
#include <stdio.h> main() { const int Men=10; Men = 20; /* This will be failed by the compiler. */ }
const int and int const would give the same effect. Try it!!
Printing Output
printf()
The printf function allows you to send output to standard output
#include <stdio.h> int main() { int num1, num2, sum; num1 = 5; num2 = 7; sum = num1 + num2; printf("%d + %d = %d\n", num1, num2, sum); return 0; } Note : %d for integers , %f for float , %c for character,
Accepting Inputs
scanf() The scanf function allows you to accept input from standard input (generally the keyboard) . #include <stdio.h> int main() { int num1, num2, sum; printf(\nEnter two intgers :); scanf(%d%d,&num1, &num2); sum = num1 + num2; printf("%d + %d = %d\n", num1, num2, sum); return 0; }
Accepting Inputs
15
scanf("%d", &num1);
The statement will read in an integer value that the user enters on the keyboard and place that value into address represented by num1. num1 must be declared previously as an integer . Note the & (means scanf will put the value entered in the address of the variable)
int main() { printf(" Men are from"); scanf("%s", MenRespond); printf(", and women are from"); scanf("%s", WomenRes); }
Operators
C provides rich set of operators to facilitates the computation Basic Arithmetic Operators (+,-,*,/,%) Assignment Operators( = , +=, -=,...) Following programs illustrate the use of the these operator
int main() { int nX, nY, nZ; nX = 1; // assign 1 to nX nY = 2; // assign 2 to nY nZ = nX + nY; // assign the sum of nX and nY to nZ nX = nX - 2; // subtract 2 nX /= 10; // divide by 10 nZ += nZ; // doubles nZ nX = nX * nX; // square nY *= nY; // square nZ = nX % nY // assign the remainder after nX / Ny to nZ nX %= 2; // modulus with 2 }
Operators
17
In the above example, because the value of count is not assigned to any variable, the effects of the PRE/POST operation are not clearly visible. Now see the next slide for the difference.
Operators
Consider the following program, #include <stdio.h> int main() { int count = 0, loop; loop = ++count; /* same as count = count + 1; loop = count; */ printf("loop = %d, count = %d\n", loop, count); loop = count++; /* same as loop = count; count = count + 1; */ printf("loop = %d, count = %d\n", loop, count); }
Sample Program Output loop = 1, count = 1 loop = 1; count = 2 Did you get the difference now?? The same stands true for decrement operators too.
18
Operators
19
Operators
20
They compare or evaluate logical and relational expressions. Logical AND (&&) This operator is used to evaluate 2 conditions or expressions with relational operators simultaneously. If both the expressions to the left and to the right of the logical operator is true then the whole compound expression is true. a > b && x = = 10 Logical OR (||) The logical OR is used to combine 2 expressions and the condition evaluates to be true if any one of the 2 expressions is true. a < m || a < n Logical NOT (!) The logical not operator takes single expression and evaluates to true if the expression is false and evaluates to false if the expression is true. In other words it just reverses the value of the expression. !(x >= y) -The NOT expression evaluates to false only if the value of x is either greater than or equal to y
Operators
21
| (Bitwise OR) sets a bit to 1 if one or both of the corresponding bits in its operands are 1, and to 0 if both of the corresponding bits are 0. & (Bitwise AND) sets a bit to 1 if and only if both of the corresponding bits in its operands are 1, and to 0 if the bits differ or both are 0. ^ (Bitwise XOR or exclusive OR) sets the bit to 1 where the corresponding bits in its operands are different, and to 0 if they are the same. ~ (Bitwise NOT) takes only one parameter and inverts each bit in the operand, changing all the ones to zeros and zeros to ones. int num1 =10,num2 = 20; num1 ^= num2; num2 ^= num1; num1 ^= num2; What would be the output? Just check on your machine and then take bit by bit operation on both the numbers by hand and justify the answer!
22
printf("the OR Operation on i and j=%d",i|j); printf("the XOR operation on i and j=%d",i^j); printf(" left shifting of i by 3=%d",i<<3); return 0;
Operators
Unary operators (& , * , + , - sizeof, !, ~, ++, - -)
Operates on single operand. & : address of operator (will be more clear when pointers will be discussed )
23
* : Dereferencing operator (This too is related to pointers) + , - : unary plus and minus respectively 10 * (-10) Sizeof is used to find out memory allocated for the entity sizeof(int); sizeof(123);
Shift Operators
24
<< and >> are called as shift operators. If we do a<<2 (considering the a as unsigned integer), a will be shifted to left by 2 position. What does it mean? It means every bit of binary equivalent of the number will be shifted to left. Obviously leftmost bit will be gone and one place will be created at rightmost position to maintain the fixed length of the number. See below for example. Let us take a=27; binary equivalent of it( assuming the size of integer as 4 bytes) is: 00000000000000000000000000011011 If we shift this number by one i.e. a<<1 then the number will be 00000000000000000000000000110110. See, left most 0 has gone and we added one extra 0 at rightmost position.
25
54
So left shift multiplies the number by 2 . But what happens if a=4294967295 and you apply the left shift on that. you will get unpredictable results. Why? Because the value given above is the maximum value which can be represented by unsigned integer. In that case the result after multiplying it by 2 will go beyond the range of the unsigned integer and hence it will give wrong result. So we have to take one thing in our mind while using left shift as a multiplicative operation tool that our result should not go beyond the limit of the unsigned integer( Limit can be calculated as Pow(2,8*sizeof(int)-1). Though Left shift operation can be applied on negative integers also but the results may be unpredictable This is why, they should be applied to unsigned integers only.
Shift Operators
26
If we do a>>2 (considering the a as unsigned integer), a will be shifted to right by 2 position. What does it mean? It means every bit of binary equivalent of the number will be shifted to right . Obviously rightmost bit will be gone and one place will be created at leftmost position to maintain the fixed length of the number. See below for example. Let us take a=27; binary equivalent of it( assuming the size of integer as 4 bytes) is: 00000000000000000000000000011011 If we shift this number by one i.e. a>>1 then the number will be 000000000000000000000000000001101. See, right most 1 has gone and we added one extra 0 at left most position.
27
13
So right shift divides (integer division) the number by 2 . Fortunately we can apply right shift on any number with in the range of unsigned integer as by division, result does not go beyond the limit in any case. Again , right shift operations are also suggested to be applied for unsigned integers only A short program is shown to illustrate these operations as below:
28
In this example we are printing the power table of 2 i.e. 2, 4,8 and reverse power table of 2 like 1024,512,256..
int main () { unsigned int number=2; int count; printf("Table of power of 2 using bitwise operator\n"); printf("%u\n",number); for(count=1;count<10;count++) printf("%u\n",number<<count);
printf("Reverse table of power of 2 using shift operator\n"); number =1024; printf("%u\n",number); for(count=1;count<10;count++) printf("%u\n",number>>count); return 0; } // each time it being divided by 2
29
In an expression that contains more than one operator, the order in which operations are performed can be confusing. Usually operator with higher precedence is performed first. But a sub expression enclosed in the parentheses ( ) is evaluated first, without regard to the operator precedence because parentheses have the highest precedence.
For example:
Evaluate 25 - (2 * (10 + (8 / 2))); ( 5 + 10 ) == ( 3 * 5 ) so depth of the parentheses is deciding the order of evaluation here and hence 8/2 will be evaluated first But in expressions like following, order of evaluation is determined by precedence and associatively rules. (described in the next slide) -2 * b + b * b 4 * a * c (Root of quadratic equation)
Operators Associativity ( ) [] -> . Left to right ! - ++ -- + * & (type-cast) sizeof Right to left (in the above line, +, - and * are the unary forms) * /% Left to right + - (Binary) Left to right << >> Left to right < <= > >= Left to right == != Left to right & Left to right ^ Left to right | Left to right && Left to right || Left to right ?: Left to right = += -= *= /= %= &= ^= |= <<= >>= Right to left , Left to right
Logical Operators
Expressions connected by Logical operators(&& , ||) are evaluated from Left to right and evaluation stops as soon as the truth or falsehood value of whole expression is known. For example in the expression a||b||c, if value of a is non-zero(true) then the value of whole expression is evaluated as true and b||c will not be evaluated. Operand to a logical operator is false if it is 0 and true for anything nonzero Numeric value of relational & logical expressions are 1 or 0 Unary negation(!) converts nonzero operand into 0 and 0 to 1
Type Cast
32
During the program development, you may encounter the situations where you need to convert to the different data type from previously declared variables, as well as having mixed data type in one expression.
For example, let say you have declared the following variables: int total, number; float average; But in the middle of your program you encountered the following expression: average = total / number; This expression has mixed data type, int and float. The value of the average will be truncated, and it is not accurate anymore. Many compilers will generate warning and some do not, but the output will be inaccurate.
Type Cast
33
C provides the unary (take one operand only) typecast operator to accomplish this task. The previous expression can be re written as
This (float) is called type cast operator, which create temporary floatingpoint copy of the total operand. The construct for this typecast operator is formed by placing parentheses around a data type name as: (type) such as (int), (float) and (char). In an expression containing the data types int and float for example, the ANSI C standard specifies that copies of int operands are made and promoted to float. Implicitly, actually, only a temporary version of each new value (type) is created and used for the mixed-type expression, the original value with original type still remain unchanged. The same is true with mix of char and int and int and unsigned int.
34
printf ("i = %d; g = %f\n", i, g); // due to implicit type conversion 87 and 65.000 will be printed return 0; }
Thank you