Fresh Pap 2 -Programming Languages
Fresh Pap 2 -Programming Languages
Syntax / Commenting Code / Creating Executable Programs / Hello World - First C Program Variables Types of Constants
/ #include Directive / Header Files / Main Functions Variables are like containers in the computer's memory – one can store values in them and retrieve or modify Numbers are considered as LITERAL constants – It is not possible to change the number 20, nor assign
The C character set consists of alphabet, digit or special symbol, that is a to z, A to Z, 0 to 9 and some special them when necessary. something else into 20.
characters like underscore, hash, asterisk etc. Constants are like variables, but once a valued is stored (i.e. the constant is INITIALIZED), its value cannot be On the other hand, SYMBOLIC constants can be assigned a value during initialization and are represented by a
These basic characters are used to form constants, variables and keywords, equivalent to words in English. changed. word.
Keywords are words whose meaning has already been explained to the compiler or the computer. External Variable There are several ways to define constants in C. The const keyword is used to define a constant.
There are about 32 keywords in C and they are: When a variable is declared outside the scope of any function that is outside the main function, then the variable Suppose there is a circle with a fixed radius of 5 units. It is possible to create a symbolic constant like this:
Auto Double If Static Break Else Int is called as a global variable. Such variables are called global variables, and the C language provides storage const int radius = 5;
Struct Case Enum Long Switch Char Extern classes which can meet these requirements; namely, the external and static classes. Since radius is declared using the const keyword, statements like: radius = 12; would be illegal.
Near typedef Const Float Register Union Continue Memory for such variables is allocated when the program begins execution, and remains allocated until the Instructions
Far Return Unsigned Default For Short Void program terminates. The scope of external variables is global, i.e. the entire source code in the file following the Instructions can be classified into four different types based on their purpose:
Do Goto Signed While Sizeof Volatile declarations. All functions following the declaration may access the external variable by using its name. However, 1. Type Declaration 2. Arithmetic instruction
Syntax if a local variable having the same name is declared within a function, references to the name access the local 3. Input / Output instruction 4. Control instruction
The C code written is called the SYNTAX. variable cell. The 4 Data Types
Syntax is a mixture of: Example: Introduction
C keywords like int, for and return. int x,y;
In C, there are four data types: char, int, float, and double. Each one has its own properties. For instance, they
Constants and variables. float f;
all have different sizes. The size of a variable can be pictured as the number of containers / memory slots that
Operators like + (arithmetic "addition"), || (logical "or") and & (the "address of" operator). char c;
are required to store it.
Note that C is CASE SENSITIVE! For example, words like cat, Cat, cAt and CAT are all considered different from main()
The char Data Type
one another. {
Variables of the char data type can store a single character from a set of 256 characters.
Also, the amount of "white space" used in a C program does not affect the way it's compiled. Use extra spaces }
All of the characters on a keyboard have a unique numerical code associated with it, so in reality, numerical
can be used to make the programs more readable - indentation of code is very common. It is not allowed to put We can also pre-initialize the variable as follows,
codes are stored into char variables. The set of codes are known as ASCII codes, where ASCII stands for
spaces or line breaks in the middle of keywords like this: str uct int x=4,y=3;
"American Standard Code for Information Interchange" and is usually pronounced "ask-ee".
Compilers float f=7.23;
Declaring and Initializing Variables
There are many compilers available for C like Borland C++ compiler, Microsoft's Visual C++ 6. 0, which is a char c=’Y’;
To DECLARE a variable, means to reserve memory space for it.
powerful package and is suitable for people who are interested in software engineering. MS VC++ is a little main()
Declaring a variable involves inserting a variable name after a data type. It is also possible to declare many
complex to use. In general, C++ packages are fine for compiling C programs - the compiler executed depends {
variables of the same data type all on one line by separating each one with a comma.
on the extension of the source file(s). There are also UNIX-based compilers. }
INITIALIZING a variable involves assigning (putting in) a value for the first time. This is done using the
Commenting Code Static Variable
ASSIGNMENT OPERATOR, denoted by the equals sign, =.
It is possible to add comments to the code by enclosing the remarks within /* and */. However, nested comments static variable can’t be reinitialized and it is the default storage class for global variables. The two variables below
Declaration and initializing can be done on separate lines, or on one line.
aren't allowed. (x and y) both have a static storage class.
Initializing char Variables
A few properties of comments: static int x;
To store a character into a char variable, it should be enclosed with SINGLE quote marks. Double quote marks
They can be used to inform the person viewing the code what the code does. This is helpful int y;
are reserved for STRINGS (an ARRAY of characters).
when revisiting the code at a later stage. {
Strings and arrays are covered in the later sections. The characters assigned are CHARACTER CONSTANTS.
The compiler ignores all the comments. Hence, commenting does not affect the efficiency of the printf("%d\n", y);
So for the example, 'H' is a character constant.
program. }
It is also possible to assign a char variable an integer, that is, the ASCII code.
One can use /* and */ to comment out sections of code when it comes to finding errors, instead static variables can be 'seen' within all functions in this source file. At link time, the static variables defined here
This example should help clarify the declaration and initialization of char variables. Ignore the printf function for
of deletion. will not be seen by the object modules that are brought in.
now.
Here are examples of commented code: 'static' can also be defined within a function! If this is done the variable is initialized at run time but is not reinitalized
when the function is called.. The int Data Type
/* Comments spanning several */ /* lines can be commented*/
{ Variables of the int data type represent whole numbers. If a fraction is assigned to an int variable, the decimal
/* out like this!*/ /* But this is a simpler way of doing it! */
static x=1; part is ignored and the value assigned is rounded down (or TRUNCATED) from the actual value. Also, assigning
// These are C++ // style comments
} a character constant to an int variable assigns the ASCII value.
// and should NOT // be used with C!!
/* /* NESTED COMMENTS ARE ILLEGAL!! */ */ Local Variable The float Data Type
Creating Executable Programs Local variable is the default storage for a variable in ‘C’ language. Its also called as automatic variables and To store variables correct to six decimal places, the float data type can be used.
represented by the keyword ‘auto’. It should be declared at the start of the block. Floats are relatively easy to use but problems tend to occur when performing division. In general:
There are several tasks that need to be performed before running a program like coding, compiling and linking.
When the program execution enters the block, memory is automatically allocated for this variable and released An int divided by an int returns an int.
1. First thing to do is to write the source code in C. Declare which header files are needed to be included within
automatically upon exit from the block. The scope of automatic variable is local to the block in which they are An int divided by a float returns a float.
the source code. The source code must be saved with the extension .c.
declared. And they are so called local variable. We don’t have direct access to local variables from outside the A float divided by an int returns a float.
2. Then run the compiler, which translates the source code into machine, or binary code, which the computer can
block but can access them indirectly using pointers. A float divided by a float returns a float.
understand. Computers do NOT understand C!
If the result of a division is to be stored as a decimal number, make sure that it is stored in a float declared Naming Variables 3. Sometimes the source code is still lacking some parts, so after going through the compiler, the code is passed
variable. There are several rules that must be followed when naming variables: through a LINKER. This basically "links" the source code to other library or object files so that the final binary
If the decimal result of the division is to be between two integers, it is possible to use a method called COERSION Variable Names Examples code is produced.
(or CASTING). This involves placing (float) before an expression being wished to cast. CANNOT start with a number 2times Hello World - First C Program
The double Data Type CAN contain a number elsewhere times2 Type the following code into any text editor (e.g. Notepad, Emacs, SimpleText etc.) and save it with the .c
It is possible to store decimals correct to ten decimal places using the double data type. However, doubles take CANNOT contain any arithmetic operators... a*b+c extension. These MUST be saved in text only format - try and avoid word processors like MS Word.
up twice as much memory than floats, so doubles should be used when it's really necessary. ... or any other punctuation marks... #@%£!! When saving in Notepad, when entering a filename enclose it in quote marks, for example, "world.c" - this ensures
Once again, care should be taken when it comes to calculations that involve divisions - casting should be used ... but may contain or begin with an underscore _height that the filename will be saved with the correct extension, rather than world.c.txt.
when necessary. CANNOT be a C keyword While Example:
Scientific Notation CANNOT contain a space stupid me #include <stdio.h>
It is possible to express numbers in scientific notation, which is handy if the numbers get very large or small. CAN be of mixed cases HelloWorld int main()
In C, scientific notation is of the form xey - x and y should be replaced with numbers (y must be an integer). EXPRESSIONS {
Basically, xey translates to "x times 10 to the power of y". EXPRESSIONS consist of a mixture of constants, variables and operators. They return values. printf("Hello World!\n");
For example, 1.2e3 is 1.2*1000 = 1200 Here are some examples of expressions: return 0;
The signed and unsigned Keywords STATEMENTS PREPROCESSOR. The C preprocessor is a program that is run when compiled. #include is one of the many C
STATEMENTS are instructions and are terminated with a semicolon';'. Statements consist of a mixture of preprocessor commands.
When a variable of the type, int, by default is declared, its value is SIGNED. In other words, the variable could be
expressions, operators, function calls and various keywords. Here are some examples of statements: Basically, when the preprocessor finds #include it looks for the file specified and replaces #include with the
positive or negative.
x = 1 + 8; contents of that file. In a way, this makes the code more readable and easier to maintain if common library
The minimum value of a signed int is -32768 and the maximum value is 32767 (that is, 2^15 -1).
printf ("We will learn printf soon!\n"); functions need to be used.
An unsigned int on the other hand, can only store positive values, and has the range from 0 to 65535 (that is,
2^16 -1). int x, y, z; /* more on "int" later */ Header Files
The short and long Keywords STATEMENT BLOCKS Header files have the extension .h and the full filename follows from the #include directive. They contain
STATEMENT BLOCKS, on the other hand, can contain a group of statements. The C compiler compiles the declarations to certain functions that may or may not have been used in a program.
The cases above all apply when the integer is of the short type, which takes up less memory than the long type.
statement block as if it was just one statement. To declare a statement block statements should be enclosed For example, the stdio.h file is required if functions like printf and scanf are used in the program.
The range of values that a short int could store is somewhat limited, so if huge numbers are to be stored the long
between curly braces. There are two ways to include a header file:
type should be used. Most of the time, an integer will be of the signed short type by default.
This example has a statement block in an if-else statement. Everything in each statement block is somewhat #include "stdio.h" and
merged into a single statement. There are 2 statement blocks here: #include <stdio.h>
Example: If the double quote marks are used, it means that the directory currently in, will be searched for first for the header
if(x==10) {/* block 1 */ file, before any other directories are searched.
printf ("x equals 10\n"); If the square brackets are used, directories other than the one currently in will be searched for the header file.
Sometimes something like this is to be written: x = x + 2; x+5 == 6 printf("%d is odd and greater than zero.\n", a);
There is a better (and efficient) way of writing expressions like these by Since + has higher precedence than ==, x+5 is evaluated first, then the result is compared with 6. }
combining the operator with an equals sign, as shown in the table. Care should be taken with these though: x *= But what about x<3 && y<7 || y==5? else
y+z is the same as x = x*(y+z) and NOT x = (x*y) + z. Suppose x is 4 and y is 5. Since the relation operators have higher precedence than the logical ones, the line {
Long Hand Short Hand can be rewritten as 0 && 1 || 1 because 4<3, 5<7 and 5==5 return 0, 1 and 1 respectively. printf("You entered zero.\n");
x = x % y; x %= y; This tends to get confusing, which is why brackets should be used when there are many operators on a single }
x = x + y; x += y; line. The following is easier to understand than the original: The main focus is on the if block, with the solitary if and else statements, as well as the else ifs. Now, the program
x = x – y; x -= y; (x<3 && y<7) || y==5 evaluates the if condition. If it returns a non zero value, the if branch is executed. Once all the statements in that
Increment and Decrement Operators Expressions in brackets are evaluated first. branch have been executed, THE PROGRAM IGNORES THE REST OF THE IF BLOCK. In other words, the
remaining conditions are not evaluated.
Increasing an integer variable by 1 is a common process. There are people who write statements like x+=1; or
If, on the other hand, (a%2==0 && a<0) returns zero, the first else if condition is evaluated and so on. The main
even worse, x=x+1;
CONDITIONAL OPERATOR thing to remember is that once the program chooses a branch in the if block, the remaining branches are totally
There is an easier way: x++; (POST-INCREMENT)
It's possible to say: "If this condition is true, do this.... , otherwise, do this .... " all in one line. ignored. If it is needed to say, "else do nothing", rather than missing the else statement totally, a blank statement
Alternatively, it is also allowed to use ++x; (PRE-INCREMENT)
This can be achieved using the CONDITIONAL OPERATOR, which is represented by ?: block shall be included:
They both increase x by 1 (note that x MUST be an integer), They differ when it comes to statements like these:
It may look a bit odd at first, but it takes 3 expressions as operands, like this: a ? b : c; a should be a condition to if(x==0) {
y = x++;
be tested for. b is an expression that is evaluated if a returns a non zero value (in other words, if a is true), else printf("x is zero\n");
y = ++x;
expression c is evaluated. }
If x was 5, y = x++; would assign x to y, THEN increase x by 1. The end result is that y equals 5 and x equals 6.
For example: else if(x==1){
If x was 5, y = ++x; would increase x by 1, THEN assign x to y. The end result is that y equals 6 and x equals 6.
x<1 ? printf("x<1") : printf("x>=1"); printf("x is 1\n");
Post-incrementing is done AFTER the assignment, pre-incrementing is done
Note the terms used: the 3 separate operands are expressions - the whole line is a statement. }
BEFORE the assignment.
It's a common mistake to put a semi colon in the middle expression like this: x<1 ? printf("x<1"); : printf("x>=1"); else { /* Do nothing */
Similar rules apply for decrementing. If x is to be decreased by 1 it is correct to
This will generate an error when compiled. }
write x--; (POST-DECREMENT) or --x; (PRE-DECREMENT), as opposed to: x-=1; or
Caution: DON'T put a semi colon after if, else if and else statements like this: if (x==1);
x=x-1;
NESTING IF CONTROL STRUCTURE / BRANCHING / CONDITIONAL BRANCHING The sizeof Operator
When statemnet blocaks are placed within other blocks, it is called NESTING blocks. This function enables to find out how many BYTES a variable occupies. A byte is defined as EIGHT BINARY
The same way, it is possible to place if blocks within branches of another if block. This is when the programmer DIGITS (or "8-bits"). Binary numbers are covered later. For now, think of a byte as a container in the computer's
CONDITIONAL BRANCHING - if This Happens, Do This... else Do This...
should indent and use curly brackets, as these will make the code easier to read as this example demonstrates: memory.
CONDITIONAL BRANCHING is a term that is used to describe the way program flow diverges, depending on
Example: The sizeof operator takes one OPERAND. An operand is an expression that is required for an operator to work.
certain condition(s).
#include <stdio.h> A data type can be used as an operand, to find out how much memory is required to store variables of that data
if statements play an important role in conditional branching and their usage is quite easy to understand. After
int main() { type, as demonstrated by this example:
typing if, the condition should be put in a pair of brackets, followed by a statement that the program should read
int a,b,c; Example:
if the condition expression returns a non-zero value. If multiple statements are needed, a statement block should
printf("Input two integers separated with a space and push return:\n"); #include <stdio.h>
be used. If the condition returns zero, sometimes program needs to do something else. In that case, after the if
scanf("%d %d", &a, &b); int main()
statement, an else statement should be used.
c = a + b; {
Here is an example:
if(a==b) { printf("Size of int is %d bytes\n",sizeof(int));
#include <stdio.h>
printf("%d is equal to %d.\n", a, b);
int main()
printf("And their sum is even.\n"); Relational and Logical Operators
{
}
int a; Relational Operators
else if(a<b) {
printf("Input an integer and push return:\n"); Relation operators are used to compare numerical values. Here are the six relation operators:
printf("%d is less than %d.\n", a, b);
scanf("%d", &a); Operator Name Symbol Operator Name Symbol
if(c%2==0) {
if (a%2==0 && a%5==0) Less than < Less than or equal to <=
printf("And their sum is even.\n");
{ /* Start of if block */ Greater than > Greater than or equal to >=
}
printf("%d is a multiple of 2 and 5\n", a); /* This is the if branch */ Equal to == Not equal to !=
else {
} The top four have higher precedence than the "equal to" and "not equal to" operators.
printf("And their sum is odd.\n");
else All arithmetic operators have higher precedence than the relation operators. The "equal to" operator should not
}
{ be confused with the assignment operator.
}
printf("%d is not a multiple of both 2 and 5\n", a); /* This is the else branch */ Logical Operators
else {
} /* End of if block */ Conditions are expressions that can return one of two values: 1 (true) or 0 (false).
printf("%d is greater than %d.\n", a, b);
return 0; Any non-zero value is considered true, where as zero is thought of as false.
if(c%2==0) {
} Experiment with the relation operators:
printf("And their sum is even.\n");
The program output for this example will depend on the value entered. The logical operators can be used to test for more conditions.
}
This example covers recent material, like using the printf and scanf functions, relation and logical operators, and The first one is the NOT operator (some call it negation). It is denoted by the ! symbol and takes one expression
else {
finally the if and else statements. as its operand.
printf("And their sum is odd.\n");
The printf functions are simple enough, but scanf reads in an integer (due to the %d format specifier), and assigns Then there is the AND operator, represented by &&, and the OR operator, denoted by || (double broken vertical
}
it to the int declared variable, a. bar symbols - shift backslash on the keyboard). Both of these operators require two expressions as their
}
a%2==0 && a%5==0 is the condition part of the if statement - it is surrounded by a pair of brackets. This can be operands.
return 0;
made more readable by adding more brackets like this: Now, their return values depend on the TRUTH VALUES of their operands – do they return 1 or 0? Logical
}
if ((a%2==0) && (a%5==0)) operators are commonly summarized using TRUTH
Caution: The extra white space should be used, as indentation will make the code easier to read, especially when
Onto the condition itself... recall that a%2 returns the remainder of the division of a by 2. If zero is returned, then TABLES, which lists all the different truth combinations of the operands and the final
there are lots of if and else statements used. Also, lining up the curly brackets will help when it comes to finding
a must be a multiple of 2. Similarly, a%5 returns zero if a is a multiple of 5. Now, a%2==0 returns 1 (true) if a%2 logical operator truth-value. NOT reverses the truth value of its operand:
and fixing errors (a process known as DEBUGGING).
is equal to 0. Similar story for a%5==0. AND returns 1 if both operands return non zero values (like 1):
a%2==0 && a%5==0 returns 1 if BOTH operands of the && operator return 1. In that case, the if branch is OR only returns 0 if both operands return zero:
executed, and the else branch is ignored. NOT has higher precedence than AND, which has higher precedence than OR.
If a%2==0 && a%5==0 returns 0, the else branch is executed and the if branch is ignored.
Notice how curly brackets are added, despite having only one statement after the if and else statements. This
makes the code more readable in some ways.
The following would've worked fine:
if (a%2==0 && a%5==0)
printf("...");
else
printf("...");
SWITCH STATEMENT LOOPING / WHILE LOOPS / DO..WHILE LOOPS LOOPING / GOTO STATEMENT / FOR LOOP
There are times when need arises to write a huge if block that consists of many else if statements. The Concept of Looping The Concept of Looping
The switch statement can help simplify things a little. It allows to test the value returned by a single expression The term "looping" describes the way in which the program executes statements over and over again, before The term "looping" describes the way in which the program executes statements over and over again, before
and then execute the relevant bit of code. As many cases needed, can be used, including a default case, which exiting the loop and continuing with program flow. exiting the loop and continuing with program flow.
is evaluated if all the cases fail. This the general form... In C, there are three types of loops: for loops, while loops and do while loops. It is possible to simulate each type In C, there are three types of loops: for loops, while loops and do while loops. It is possible to simulate each type
by writing code using other loops. by writing code using other loops.
switch (expression) { There is a fourth kind of loop but has no specific keyword. INFINITE LOOPS can cause the computer to hang. There is a fourth kind of loop but has no specific keyword. INFINITE LOOPS can cause the computer to hang.
case expression1: They sometimes end after a while, but in theory they should go on forever. They sometimes end after a while, but in theory they should go on forever.
/* one or more statements */ while Loops goto Statement
case expression2:
while loops are simpler to use, since they only require one expression in the brackets: It is not advisable to use goto repeatedly and in larger programs.
/* one or more statements */
while (expression) The goto keyword is followed by a label, which is basically some identifier placed elsewhere in the program - like
/* ...more cases if necessary */
{ a hyperlink that points to a place on the same web page.
default:
/* statements */ #include <stdio.h>
/* do this if all other cases fail */
} int main() {
}
The loop body is executed if expression returns a non-zero value. Most of the time, some sort of condition to be int attempt, number = 46;
The program will branch off depending on what is returned by the expression in the parentheses. However, all is
evaluated is used. looping: /* a label */
not what it seems.
It is mentioned earlier on that it is possible simulate one type of loop with another type - there is no unique way printf("Guess a number from 0 to 100\n");
to loop. scanf("%d", &attempt);
Examine the output of this example:
The previous example can be rewritten using a while loop. if(number==attempt) {
#include <stdio.h>
#include <stdio.h> printf("You guessed correctly!\n\n");
int main()
int main() }
{
{ else {
int a;
int i=10; /* initialize variables */ printf("Let me ask again...\n\n");
printf(“Pick a number from 1 to 4\n”);
int j=0; /* part a of a for loop */ goto looping; /* Jump to the label*/
scanf("%d", &a);
while (i!=j) { /* test for condition }
switch (a) {
part b of for loop */ eturn 0;
case 1:
printf("%d - %d = %d\n", i, j, i-j); }
printf("You chose number 1\n");
i--; /* do something to variables */ for Loop
case 2:
j++; /* part c of for loop */ Here's the basic form of for loop:
printf("You chose number 2\n");
} for (a ; b ; c) {
case 3:
return 0; /* statements */
printf("You chose number 3\n");
} }
case 4:
do while Loops Brief example:
printf("You chose number 4\n");
It's almost identical to a while loop, except the loop body is executed at least once - the while (expression) part for(i=10, j=0 ; i!=j ; i--, j++) {
default:
is after the loop body, like this: printf("%d - %d = %d\n", i, j, i-j);
printf("That's not 1,2,3 or 4!\n");
do { }
}
/* loop body */ a, b and c are expressions that are evaluated at different times. a is evaluated once only - before entering the
return 0;
} while (expression); loop. It is a very good place to assign values to variables. If values are to be assigned to multiple variables, each
}
This example prints out the numbers 0-9: assignment can be separated with a comma like this: i=10, j=0. b determines whether or not the program loops.
Don't forget the semi colon after the expression part! If b returns a non-zero value, an iteration of the loop is performed. In other words, the program enters the loop
(Suppose if 2 is entered ...)
If the example is run again, but initializes i with 11 the loop body is still executed. and executes the statements inside. b should therefore be some sort of condition. Logical operators can be used
Pick a number from 1 to 4:
Simulating a do while loop with either a for or while loop is not advisable – most of the time the statements are in the condition as usual.
2
written in the loop body once, before the loop: C is evaluated after an iteration of the loop, i.e. after all the statements inside the loop body have been executed.
You chose number 2
#include <stdio.h> If there are multiple expressions evaluating, each one can be separated with a comma like this: i--, j++
You chose number 3
int main() The round brackets and semi colons are required at all times. The three expressions aren't compulsory, but
You chose number 4
{ omitting b and failing to place a break statement somewhere in the loop can result in an infinite loop!
That's not 1,2,3 or 4!
int I = 0; Here is a proper example:
Here the program will select the correct case but will also run through all the cases below it (including the default)
do #include <stdio.h>
until the switch block's closing bracket is reached. To prevent this from happening, another statement needs to
{ int main()
be inserted into the cases...
printf("%d", i); {
i++; int i,j;
for(i=10, j=0 ; i!=j ; i--, j++) } while (i<10); Keywords
{ return 0;
Keywords – Predefined meaning
printf("%d - %d = %d\n", i, j, i-j); }
Comments -- Ignored by the compiler
} #include <stdio.h>
Variable – Name given to the memory location
return 0; int main()
Expression – Sequence of operands and operators
} {
Statement – Combination of c tokens
Before entering the loop, i is initialized with 10 and j with 0. Here is the step through the loop one iteration at a int I = 0;
Constant – Value which doesn’t change
time: printf("%d", i); /* "loop body" */
Data types – Inbuilt definition inside the c compiler.
At the end of each iteration, i is decremented by 1, j is incremented by 1. I++;
Operators – Symbol which tell compiler to act
The sixth evaluation of i!=j returns 0 for false, because i and j are equal at that while (i<10)
Control structures – Structures which alter the flow of control based on condition or without condition.
time, so the loop body is not executed. {
Function - set of instructions that performs a particular task. It provides the modularity i.e. splitting the entire
printf("%d", i);
task into some smaller sub tasks.
Output: i++;
Array - collection of homogeneous elements stored in contiguous memory locations
10 - 0 = 10 }
preprocessor - activities to be performed before processing
9-1=8 return 0;
Structures - collection of heterogeneous Elements stored in independent Memory locations.
8-2=6 }
Unions - similar to the structures but the Members of union should share the same memory location. It makes
7-3=4
us to save memory.
Pointers - a variable which holds the address of the another identifier rather than storing the value.
scanf() -scan formatted. It means that the way which we follow to get input from the user is in some format.
printf() -print formatted. It means that the output that has to be provide to user are in some format.
getchar() -used to get the single character as input from the user.
putchar() -used to give the single character as output to the user.
gets() -used to get the string as input from the user.
puts() -used to give the string as output to the user.
file -is a group of related data stored in a place on the hard disk.
Basic file operations - naming, opening, reading, writing and closing the file.
Fopen() -is a function helps to open a file in any of the following modes. r - read only, w – write only, a – append
fclose() -is a function used to close the file
getc(),getw(),fscanf() -function used for read operations.
Putc(),putw(),fprintf() -function used for write operations.
Fseek(),ftell(),rewind() – functions used in random file activities.
Ftell() – returns the current position of the file pointer.
Fseek() – used to move the file pointer to the desired locations.
Rewind() – takes the file pointer to the beginning of the file.
THE BREAK STATEMENT / THE CONTINUE STATEMENT FUNCTION / TYPICAL FUNCTION / SCOPE of FUNCTION Variables / RECURSIVE FUNCTIONS - CALL THEMSELVES FUNCTIONS / CALL
The break and continue statements in C are used to alter the flow of a program. The main difference between MODIFYING FUNCTION ARGUMENTS OTHER FUNCTIONS
the two is that a break statement ends a loop or switch, while a continue statement skips an iteration of a loop:
FUNCTION Recursive Functions - Functions That Call Themselves
Break
A function can be thought of as a mini-program, where a group of statements are executed when the function is A function that calls itself is said to be a RECURSIVE function. Recursive function calls can be less efficient than
Ends a loop or switch statement when a specific condition is met. Control moves to the next statement after the
called. A function is CALLED (or INVOKED) when it is needed to branch off from the program flow and execute a loop.
loop or switch.
a group of statements within that function. Once the statements in the function are executed, program flow Example:
Continue
resumes from the place where the function is called. A few functions: main, printf and scanf were already used. #include <stdio.h>
Skips the remaining code within the current iteration of a loop and immediately jumps to the next iteration. It does
The main function is special, in the way that it's called automatically when the program starts. In C, and other int factorial(int x);
not exit the loop entirely.
programming languages, it is possible to create customized functions. int main()
Example:
A Typical Function {
#include <stdio.h>
Functions have 5 main features: int a, b=1, temp;
int main() {
1. The RETURN TYPE is the data type of the RETURN VALUE of the function. printf("Enter an integer: ");
int a;
2. The NAME is required as an identifier to the function, so that the computer knows which scanf("%d", &a);
printf("Pick a number from 1 to 4:\n");
function is called. Naming of functions follows the same set of rules as the naming of variables. printf("\n%d factorial is %d\n\n", a, factorial(a));
scanf("%d", &a);
3. Functions can take ARGUMENTS - a function might need extra information for it to work. printf("Enter another integer: ");
switch (a) {
Arguments are optional. scanf("%d", &a);
case 1:
4. The function BODY is surrounded by curly brackets and contains the statements of the temp = a;
printf("You chose number 1\n");
function. for( ; a>0 ; a--)
break;
5. The RETURN VALUE is the value that is passed back to the main program. Functions exit {
case 2:
whenever a value is returned. b*=a;
printf("You chose number 2\n");
}
break;
printf("\n%d factorial is %d\n", temp, b);
case 3: SCOPE OF FUNCTION VARIABLES return 0;
printf("You chose number 3\n");
Only a limited amount of information is available within each function. Variables declared within the calling }
break;
function can't be accessed unless they are passed to the called function as arguments. The only other contact a int factorial(int x)
case 4:
function might have with the outside world is through global variables. { /* n factorial, (or n!) is 1*2*3* ... *n */
printf("You chose number 4\n");
Local variables are declared within a function. They are created a new each time the function is called, and if(x!=0)
break;
destroyed on return from the function. Values passed to the function as arguments can also be treated like local {
default:
variables. return (x*factorial(x-1));
printf("That's not 1,2,3 or 4!\n");
Static variables are slightly different; they don't die on return from the function. Instead their last value is retained, }
}
and it becomes available when the function is called again. else
return 0;
Global variables don't die on return from a function. Their value is retained, and is available to any other function, {
}
which accesses them. return 1;
seem virtually identical to the last example, except a break statement is inserted at the end of each case to
Function Declaration }
"break" out of the switch block. Now it should work as expected:
This is what a function definition might look like: }
Pick a number from 1 to 4:
int squareNumber(int a) CALL OTHER FUNCTIONS
2
{ To call a function, you simply need to pass the required parameters along with the function name, and if the
You chose number 2
int b = a*a; function returns a value, then you can store the returned value. Control of the program is transferred to the user-
Notice that it is not needed to surround the statement(s) in each case with opening and closing brackets - not like
return b; defined function by calling it.
the "usual" statement blocks seen in previously.
} Example:
The continue statement
squareNumber is the name of this function. Because an integer is returned, the int keyword must be placed before #include <stdio.h>
The continue statement passes control to the next iteration of the nearest enclosing do, for, or while statement in
the function name. If the function does not return a value, the void keyword should be put before the function int triangular(int x);
which it appears, bypassing any remaining statements in the do, for, or while statement body.
name. This function has one argument, which is of the type int. If there are arguments, variable declarations int main()
Syntax jump-statement :
should be in the round brackets. {
continue;
The function body consists of 2 statements. The first, sees an int variable b declared and assigned a*a, i.e. a int x;
The next iteration of a do, for, or while statement is determined as follows:
squared. The second statement uses the return keyword to pass the value of b back into the main program, printf("Enter an integer: ");
Within a do or a while statement, the next iteration starts by reevaluating the expression of the do or while
hence exiting the function. Within the program, it is possible to write: scanf("%d", &x);
statement.
x = squareNumber(5); if(x%10>3 || x==11 || x==12 || x==13)
A continue statement in a for statement causes the first expression of the for statement to be evaluated. Then
This would assign 25 to x. It is said that 5 is passed as an argument to the function squareNumber. {
the compiler reevaluates the conditional expression and, depending on the result, either terminates or iterates
The variables within the squareNumber function are LOCAL VARIABLES - when the function exits, variables a printf("\n%d is the %dth triangular number\n", triangular(x), x);
the statement body. See The for Statement for more information on the for statement and its nonterminals.
and b are deleted from memory. int squareNumber(int a) is also known as the FUNCTION HEADER. }
else Example: Example of the continue statement:
{ #include <stdio.h> while ( i-- > 0 )
switch(x%10) void printAverage(int x, int y, int z); /* the function declaration */ {
{ int main() x = f( i );
case 1: { if ( x == 1 )
printf("\n%d is the %dst triangular number\n", triangular(x), x); int a, b, c; continue;
break; printf("Enter 3 integers separated by spaces: "); y += x * x;
case 2: scanf("%d %d %d", &a, &b, &c); }
printf("\n%d is the %dnd triangular number\n", triangular(x), x); printAverage(a, b, c); /* the function call */ In this example, the statement body is executed while i is greater than 0. First f(i) is assigned to x; then, if x is
break; return 0; /* exit main function */ equal to 1, the continue statement is executed. The rest of the statements in the body are ignored, and execution
case 3: } resumes at the top of the loop with the evaluation of the loops test.
printf("\n%d is the %drd triangular number\n", triangular(x), x);
break; Modifying Function Arguments
} Some functions work by modifying the values of their arguments. This may be done to pass more than one value
} back to the calling routine, or because the return value is already being used in some way. C requires special
printf("You entered: %d\n", x); arrangements for arguments whose values will be changed.
return 0; You can treat the arguments of a function as variables, however direct manipulation of these arguments won't
} change the values of the arguments in the calling function. The value passed to the function is a copy of the
int triangular(int a) calling value. This value is stored like a local variable, it disappears on return from the function.
{ /* the nth triangular number is 1+2+3+ ... +n */ There is a way to change the values of variables declared outside the function. Passing the addresses of variables
int x = (a * (a + 1)) / 2; to the function does it. These addresses, or pointers, behave a bit like integer types, except that only a limited
return x; number of arithmetic operators can be applied to them. They are declared differently to normal types, and we are
} rarely interested in the value of a pointer. It is what lies at the address which the pointer references which interests
Above main is the function declaration. The triangular function takes an integer argument, and returns an integer. us.
Below main is the function definition - it works out and returns the triangular number of the number passed to the To get back to our original function, we pass it the address of a variable whose value we wish to change. The
function. function must now be written to use the value at that address (or at the end of the pointer). On return from the
Inside main, observe that inside printf, the triangular function is called. The if, else and switch blocks determine function, the desired value will have changed. We manipulate the actual value using a copy of the pointer.
how to display the result.
One important thing to remember is that the x in main is totally different to the x in triangular.
The value of x in main remains unchanged after calling triangular.
ARRAYS CHARACTER ARRAYS / INTO THE NEXT DIMENSTION / ARRAY SIZE SINGLE – MULTI DIMENSIONAL ARRAYS - PASSING ARRAYS TO
Introduction So far arrays of integers are used. Arrays for floats and doubles as well as chars can also be used. FUNCTIONS
Arrays allow storing a sequence of variables of the same data type. An array in the computer's memory can be Character arrays have a special property... Each element of the array can hold one character. But if the array is
Single Dimensional Arrays
assumed as a row of consecutive spaces, each of which can store a data item, known as an ELEMENT. ended with the NULL CHARACTER, denoted by \0 (that is, backslash and zero), it is called a STRING
Sometimes it's inconvenient to call a function that requires a long list of arguments. One way around this is to
Declaring Arrays CONSTANT. The null character marks the end of a string - useful for functions like printf.
store the variables into an array, then pass a pointer to the array on the function. This method will be discussed
Example:
A declaration is to be made before using an array. To declare an array, its data type, its name and, in most cases,
in the pointers section, but for now, the array is passed into the function - not the most efficient way, but it'll do
#include <stdio.h>
its size should be specified. Make sure the array has a valid name.
for now.
int main()
Here's an example:
Example:
{
int arrayOfInts[5];
#include <stdio.h>
char charArray[8] = {'F','r','i','e','n','d','s','\0'};
This reserves memory for an array to hold five integer values. The number of elements should be enclosed in the
int addNumbers(int fiveNumbers[]); /* declare function */
int i;
square brackets. If the number of elements is not specified during the declaration, it means that an UNSIZED
int main()
for(i=0 ; i<8 ; i++)
array is declared - the size will be calculated when values are inserted into it.
{
{
Initializing Arrays int array[5];
printf("charArray[%d] has a value of %c\n", i,
Values can be assigned to the array in several ways. for example, if an arrays is to hold the numbers 1 through int i;
charArray[i]);
to 10, this can be done in several ways, as this example demonstrates: printf("Enter 5 integers separated by spaces: ");
}
int main() for(i=0 ; i<5 ; i++)
printf("My favourite comedy is %s\n", charArray); /*
{ {
Alternative way */
int arrayOfInts1[10] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; scanf("%d", &array[i]);
return 0;
int arrayOfInts2[10]; }
}
int arrayOfInts3[] = {1,2,3,4,5, 6,7,8,9,10}; /* an unsized array */ printf("\nTheir sum is: %d\n", addNumbers(array));
Output:
int arrayOfInts4[10]; return 0;
charArray[0] has a value of F
int i; }
charArray[1] has a value of r
arrayOfInts2[0] = 1; int addNumbers(int fiveNumbers[]) { /* define function */
charArray[2] has a value of i
arrayOfInts2[1] = 2; int sum = 0;
charArray[3] has a value of e
arrayOfInts2[2] = 3; int i;
charArray[4] has a value of n
arrayOfInts2[3] = 4; for(i=0 ; i<5 ; i++)
charArray[5] has a value of d
arrayOfInts2[4] = 5; {
charArray[6] has a value of s
arrayOfInts2[5] = 6; sum+=fiveNumbers[i]; /* work out the total */
charArray[7] has a value of
arrayOfInts2[6] = 7; }
My favourite comedy is Friends
arrayOfInts2[7] = 8; return sum; /* return the total */
Notice that each of the characters is enclosed with single quote marks - double quote marks are reserved for
arrayOfInts2[8] = 9; }
strings. The character and string format specifiers are also used (%c and %s respectively). Caution: Use the right
arrayOfInts2[9] = 10; Notice that the size of the array is left blank in both the function declaration and definition - the compiler works it
slash symbol for the null character.
for(i=0 ; i<10 ; i++) out for the programmer. Also, when the function is called, the name of the array is passed on.
Into The Next Dimension...
{ Multidimensional Arrays
An array's DIMENSION is the number of indices required to reference an element.
arrayOfInts4[i] = i + 1;
This is similar to passing 1D arrays but in the function declarations it is a must to specify all the dimension sizes
Example,
}
(but the leftmost one is optional).
arrayOfInts[0] is the first element. The index is 0 - there is only 1 index so arrayOfInts is one dimensional.
return 0;
#include <stdio.h>
Now suppose arrayOfInts[0] needs to hold 2 integers. Here comes the next dimension... arrayOfInts[0][0] that
}
could hold the first integer, and arrayOfInts[0][1] could hold the other. 2 indices are needed to reference each
Caution: Notice that the first element of an array is indexed 0 rather than 1. This is a simple, yet important idea
void printArray(int array[][4]); /* declare function */
integer, so arrayOfInts is two-dimensional.
that needs to be taken into account.
int main()
2 dimensions is the mostly used, but 3 dimensions is like arrayOfInts[0][0][0]. 2D arrays are useful for storing
Printing Out Arrays {
grid-base information, like coordinates.
One of the commonest ways to print out the contents of the array is to use a loop. A loop used with scanf to insert int array[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
The example given here shows how to declare a 2D array:
elements: printArray(array);
int array2D[3][5];
Example: return 0;
This tells the computer to reserve enough memory space for an array with 15, that is, 3 x 5 elements.
#include <stdio.h> }
One way to picture these 15 elements is an array with 3 rows and 5 columns.
int main()
But there are times when the size is not known. In this case an unsized array can be used. However, every
{ void printArray(int array[][4])
dimension size except the left one should be specified. Like this:
int anotherIntArray[5]; { /* define function */
int array2D[ ] [5];
int i; int i, j;
printf("Enter 5 integers one by one, pressing return after each one:\n"); for(i=0 ; i<3 ; i++)
{
for(j=0 ; j<4 ; j++) ARRAY SIZES for(i=0 ; i<5 ; i++)
{ {
If it is needed to find out how much memory the arrays occupy (1D or multidimensional), the sizeof operator can
printf("%2d ", array[i][j]); scanf("%d", &anotherIntArray[i]);
be used.
} }
Example:
printf("\n"); for(i=0 ; i<5 ; i++)
#include <stdio.h>
} {
int main()
} printf("anotherIntArray[%d] has a value of %d\n", i, anotherIntArray[i]);
{
}
char arrayChar[] = {'A','r','r','a','y','\0'};
return 0;
int arrayInt[5] = {1,2,4,8,16};
}
float arrayFloat[3] = { 1.24 , 2 , 4.68756 };
double arrayDouble[2];
The output might look like:
int arrayInt2D[][4] = {1,6,3,7, 0,3,8,9, 2,5,2,3};
Enter 5 integers one by one, pressing return after each one:
arrayDouble[0] = 23.23456532;
3
arrayDouble[1] = 2.3422267;
7
printf("The size of arrayChar is %d\n", sizeof(arrayChar));
2
printf("The size of arrayInt is %d\n", sizeof(arrayInt));
856
printf("The size of arrayFloat is %d\n", sizeof(arrayFloat));
324
/* Alternative way */
anotherIntArray[0] has a value of 3
printf("The size of arrayDouble is %d\n", sizeof(double) * 2);
anotherIntArray[1] has a value of 7
printf("The size of arrayInt2D is %d\n", sizeof(arrayInt2D));
anotherIntArray[2] has a value of 2
printf("The size of arrayInt2D[0] is %d\n", sizeof(arrayInt2D[0]));
anotherIntArray[3] has a value of 856
return 0;
anotherIntArray[4] has a value of 324
}
Output:
The size of arrayChar is 6
The size of arrayInt is 20
The size of arrayFloat is 12
The size of arrayDouble is 16
The size of arrayInt2D is 48
The size of arrayInt2D[0] is 16
sizeof can be used to find out the maximum of "rows" there are in a 2D array. For example, how many "rows" are
there in arrayInt2D[][4]?
This is given by: sizeof(arrayInt2D) / sizeof(arrayInt2D[0]), which is 48/16 = 3. Think of this calculation as "size
of entire array / size of a column".
So there are 3 "rows" and 4 "columns" to this 2D array.
The "rows and columns" visualization shouldn't be confused with the way the data is stored in memory.
int arrayInt2D[][4] = {1,6,3,7, 0,3,8,9, 2,5,2,3};
This uses 12 consecutive memory slots, with 1 placed in the first slot, 6 in the next one and so on. So 7 is next
to the 0. In fact, arrayInt2D[0][4] returns 0, arrayInt2D[0][5] returns 3 and so on. arrayInt2D[3] returns some
random number because there is no 4th row.
2D ARRAYS / ARRAY SIZES PRE PROCESSOR / DEFINE / UNDEF and MACRO FUNCTIONS IF / ELSE and ELIF / IF DEF, IF NDEF and END IF / The Process of
Methods used are similar to those of the 1D arrays: Introduction Linking /
Example: The C preprocessor is a program that is executed before the source code is compiled.
#if, #else and #elif
#include <stdio.h> C preprocessor commands are called DIRECTIVES, and begin with a pound hash symbol (#). No white space
This set of directives allow to perform conditional branching before the program is compiled, to determine which
int main() should appear before the #, and a semi colon is NOT required at the end. A directive: #include is already
parts to compile - another useful method of debugging.
{ introduced. This takes the specified file, and pastes its contents into the place where #include is placed before
They act just like the C keywords: if, else and else if respectively. No curly brackets are required, but the whole
int first[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11}; the source code is compiled. So when printf is used, stdio.h is required so that the compiler knows what printf is.
conditional block must be terminated by the #endif directive. It is possible to place the condition after the #if or
int second[3][4] = {0, 1, 2, 3, 4, 5, 6, 7,8, 9,10,11}; /* a clearer definition than the first */ #define
#elif directives – round brackets are optional.
int third[][5] = {0,1,2,3,4}; /* third[] only has one index of 1 */
#define allows to make text substitutions before compiling the program. Here's an example:
One important thing to remember is that it is not possible to use any variables declared in main with these
int fourth[][6] = {0,1,2,3,4,5,6,7,8,9,10,11}; /* fourth[] has 2 indices - 0 or 1 */
#define MAX 10
directives, because the directives are read by the C preprocessor - BEFORE main is executed! It is allowed to
int i,j;
Before compilation, if the C preprocessor finds MAX as one word (so words like MAXIMUM will not be affected),
use macro definitions however.
int fifth[5][4];
in the source code, it replaces it with the number 10. If MAX was part of a string (for example, between the quote
#include <stdio.h>
int sixth[2][6];
marks of printf), the preprocessor will leave it alone. The MACRO DEFINITION can be anything that is desired,
#define DEBUG_MODE 1
int seventh[2][3];
as long as it doesn't contain special characters or spaces and it cannot start with a number. It is possible to define
int main()
for(i=0 ; i<5 ; i++)
strings as well:
{
{
Example:
#if DEBUG_MODE==1
for(j=0 ; j<4 ; j++)
#define NAME "Mak" - Every time the preprocessor sees NAME it will replace it with
printf("Debug Mode 1\n");
{
"Mak"
#elif DEBUG_MODE==2
fifth[i][j] = i * 4 + j;
#include <stdio.h>
printf("Debug Mode 2\n");
}
#define MIN 0 /* #defines */
#elif DEBUG_MODE>2
}
#define MAX 10
printf("Debug Mode 3\n");
for(i=0 ; i<2 ; i++)
#define TRUE 1
#else
{
#define FALSE 0
printf("Default Debug Mode\n");
printf("Enter 6 integers separated by spaces: ");
int main() { /* beginning of program */
#endif
for(j=0 ; j<6 ; j++)
int a;
return 0;
{
int okay = FALSE; /* the compiler sees this as int okay = 0; */
}
scanf("%d" , &sixth[i][j]);
while(!okay) {
}
printf("Input an integer between %d and %d: ", MIN, MAX);
Output: Debug Mode 1
printf("\n");
scanf("%d", &a);
Running the example without defining DEBUG_MODE will lead to a compilation error.
}
if(a>MAX) {
printf("You entered:\n");
printf("\nToo large.\n");
for(i=0 ; i<2 ; i++) #ifdef, #ifndef and #endif
}
{ When writing big programs, DEBUGGING should be done, which involves reading through the program, and
else if(a<MIN) {
for(j=0 ; j<6 ; j++) trying to find out what's causing the program to go wrong.
printf("\nToo small.\n");
{ One common method for debugging is to comment out sections of code to find that "bug". But what if there are
}
printf("%d ", sixth[i][j]); comments dotted around the source code? That's when #ifdef and #ifndef come into play. Nesting the comments
else {
} lead to a compilation error.
printf("\nThanks.\n");
printf("\n"); In the case of #ifdef, if the macro definition that follows immediately is defined with #define, the following code
okay = TRUE;
} from that directive to the #endif directive will be considered as part of the program and will be compiled.
}
seventh[0][0] = 0; With #ifndef, it's the other way round, that is, if there isn't a definition, the code up to the #endif directive will be
}
seventh[0][1] = 1; considered as part of the program and will be compiled.
return 0;
seventh[0][2] = 2; Example
}
seventh[1][0] = 3; #include <stdio.h>
The program will loop until a number between 0 and 10 is entered.
seventh[1][1] = 4; #define WORD1 /* No need to put an expression after the defined word */
By the time the compiler receives the program, it won't see words like MIN, MAX, TRUE or FALSE in the source
seventh[1][2] = 5; int main() {
code. Instead, it'll see the numbers 0, 10, 1 and 0 respectively.
return 0; #ifdef WORD1
The Process of Linking
} printf("1: WORD1 is defined so this bit is compiled.\n");
A compiler is a program that translates source code into machine code. But what if the program has more than
#endif
one source file? The LINKER is a program that is run after compilation. Its job is to piece together various parts
For loops are handy. And not just for initialization - they are commonly used for printing out arrays. Here the #ifndef WORD2
of a program, in order to produce the final executable.
"rows" are iterated in the first loop, and then the "columns". printf("2: WORD2 is not defined so this bit is compiled.\n");
The way linker works depends on the compiler. Three compilers were used in the past - gcc on a UNIX platform,
#endif
and Borland C++ and Microsoft Visual C++ on Windows.
#undef WORD1 #undef and Macro Functions ARRAY SIZES
#define WORD2 #undef can be used to remove any already created a macro definition. This means the preprocessor will no longer
If it is needed to find out how much memory the arrays occupy (1D or multidimensional), the sizeof operator can
#ifdef WORD1 make any more text substitutions associated with that word. Also, to change a definition, #undef should be used
be used like this:
printf("3: WORD1 is now undefined so this bit is not compiled.\n"); to undefine it, then #define should be used to redefine it.
Example:
#endif #define can be used to create one’s own MACRO FUNCTIONS. These are useful when the function is relatively
#include <stdio.h>
#ifndef WORD2 small.
int main()
printf("4: WORD2 is now defined so this bit is not compiled.\n"); Example:
{
#endif #define SQR(a) (a*a)
char arrayChar[] = {'A','r','r','a','y','\0'};
return 0; Now if SQR(3) is written in the program, the preprocessor will replace it with (3*3) in the program, NOT 9.
int arrayInt[5] = {1,2,4,8,16};
} Care should be taken with the brackets.
float arrayFloat[3] = { 1.24 , 2 , 4.68756 };
Example :
double arrayDouble[2];
Output: 1: WORD1 is defined so this bit is compiled. #include <stdio.h>
int arrayInt2D[][4] = {1,6,3,7, 0,3,8,9, 2,5,2,3};
Output 2: WORD2 is not defined so this bit is compiled #define MAX(a,b) (a>b ? a : b) /* a "function" */
arrayDouble[0] = 23.23456532;
#define DIFF1 4-7
arrayDouble[1] = 2.3422267;
#define DIFF2 (4-7)
The Process of Linking printf("The size of arrayChar is %d\n", sizeof(arrayChar));
#define NUMBER 10
printf("The size of arrayInt is %d\n", sizeof(arrayInt));
What Does Linking Involve?
int main() {
printf("The size of arrayFloat is %d\n", sizeof(arrayFloat));
A compiler is a program that translates source code into machine code. But what if the program has more than
int a=4, b=7;
/* Alternative way */
one source file?
printf("Out of %d and %d, %d is the bigger number.\n", a, b, MAX(a,b));
printf("The size of arrayDouble is %d\n", sizeof(double) * 2);
The LINKER is a program that is run after compilation. Its job is to piece together various parts of a program, in
printf("DIFF1 = 4-7. DIFF1 times 10 equals %d.\n", DIFF1*10);
printf("The size of arrayInt2D is %d\n", sizeof(arrayInt2D));
order to produce the final executable.
printf("DIFF2 = (4-7). DIFF2 times 10 equals %d.\n", DIFF2*10);
printf("The size of arrayInt2D[0] is %d\n", sizeof(arrayInt2D[0]));
The way linker works depends on the compiler. Three compilers were used in the past - gcc on a UNIX platform,
printf("I live at number %d.\n", NUMBER);
return 0;
and Borland C++ and Microsoft Visual C++ on Windows.
printf("I'm moving soon...");
}
#undef NUMBER /* now undefine NUMBER so that it can be given a different value */
#define NUMBER 7
Output:
rintf(" now I live at number %d.\n", NUMBER);
The size of arrayChar is 6
return 0;
The size of arrayInt is 20
}
The size of arrayFloat is 12
Output:
The size of arrayDouble is 16
Out of 4 and 7, 7 is the bigger number.
The size of arrayInt2D is 48
DIFF1 = 4-7. DIFF1 times 10 equals -66.
The size of arrayInt2D[0] is 16
DIFF2 = (4-7). DIFF2 times 10 equals -30.
I live at number 10.
sizeof can be used to find out the maximum of "rows" there are in a 2D array. For example, how many "rows" are
I'm moving soon... now I live at number 7.
there in arrayInt2D[][4]?
Look at the printf statements:
This is given by: sizeof(arrayInt2D) / sizeof(arrayInt2D[0]), which is 48/16 = 3. Think of this calculation as "size
The compiler will see the first one as:
of entire array / size of a column".
printf("Out of %d and %d, %d is the bigger number.\n", a, b, (a>b ? a : b));
So there are 3 "rows" and 4 "columns" to this 2D array.
Since a and b beforehand were initialized beforehand, it'll work out if a is greater than b, if so, return a from the
The "rows and columns" visualization shouldn't be confused with the way the data is stored in memory.
expression, else return b.
int arrayInt2D[][4] = {1,6,3,7, 0,3,8,9, 2,5,2,3};
The compiler will see the next two printfs as:
This uses 12 consecutive memory slots, with 1 placed in the first slot, 6 in the next one and so on. So 7 is next
printf("DIFF1 = 4-7. DIFF1 times 10 equals %d.\n", 4-7*10);
to the 0. In fact, arrayInt2D[0][4] returns 0, arrayInt2D[0][5] returns 3 and so on. arrayInt2D[3] returns some
printf("DIFF2 = (4-7). DIFF2 times 10 equals %d.\n", (4-7)*10);
random number because there is no 4 th row.
Notice how the preprocessor leaves DIFF1 and DIFF2 alone inside the string of printf. Looking at the above lines,
it will be clear why the top printf prints out -66, where as the bottom did the obvious and printed 30 - macro
The Process of Linking
definitions are just text substitutions! What Does Linking Involve?
The next printf is seen as : printf("I live at number %d.\n", 10); A compiler is a program that translates source code into machine code. But what if the program has more than
After that, NUMBER is undefined, then redefined, so the next printf will look like: one source file?
printf(" now I live at number %d.\n", 7); The LINKER is a program that is run after compilation. Its job is to piece together various parts of a program, in
order to produce the final executable.
The way linker works depends on the compiler. Three compilers were used in the past - gcc on a UNIX platform,
and Borland C++ and Microsoft Visual C++ on Windows.
POINTERS IN C / POINTERS AND STRUCTURES STRUCTURES / USES OF STRUCTURE / DEFINING STRUCTURE ARRAY OF STRUCTURE / NESTED STRUCTURE / ACCESSING and
POINTER The main use of structure is to lump together collections of disparate variable types, so that they can conveniently INITIALIZATION
A pointer in C refers to a variable that holds the address of another variable. In real time, pointers are a quite be treated as a unit. For example, while writing a compiler or assembler, one might need for each identifier
ARRAY OF STRUCTURE
common way to get the contents of a variable. The unary operator `&' is used to return the address of a variable. information like its name (a character array), its source line number (an integer), some type information (a
Just like an array of variable, an array of structure can also be declared. Suppose a symbol table for 100 identifiers
Thus, the following sentence prints the address of a variable called a. character, perhaps) and probably a usage count (another integer).
has to be made. The definitions can be extended like
printf(“The address of the variable is: %u”,&a); char id[10];
char id[100][10];
If the address has to be assigned to a pointer variable, then an appropriate pointer variable has to be declared. int line;
int line[100];
A pointer variable is declared with an asterisk symbol preceding its name. char type;
char type[100];
The following example illustrates this. int usage;
int usage[100];
int a=5, *b, c; In this case, the structure is first defined, that is, what kinds of things it contains; after that one can actually reserve
but a structure lets rearranging this spread-out information so that all the data identifier is collected into one lump:
b = &a; storage for it, either in the same statement or separately. The simplest thing is to define it and allocate storage
struct {
c = *b; all at once.
char id[10];
b contains the address of a and `c = *b' means to use the value in b as an address, that is, as a pointer. The struct {
int line;
effect is that the contents of a is copied to c. char id[10];
char type;
The most frequent use of pointers in C is for walking efficiently along arrays. In fact, in the implementation of an int line;
int usage;
array, the array name represents the address of the zeroth element of the array. char type;
} sym[100];
Consider the following, int usage;
This makes sym an array of structures; each array element has the specified shape. Now, members can be
char *y; } sym;
referred to as
char x[100]; This defines sym to be a structure with the specified shape; id, line, type and usage are the members of the
sym[i].usage++; /* increment usage of i-th identifier */
y is of type pointing to character. The pointer variable y can be made to point to an element of x by either of structure.
for( j=0; sym[i].id[j++] != '\0'; ) ...
y = &x[0];
etc.
y = x;
Uses of Structures Thus, to print a list of all identifiers that have not been used, together with their line number,
Since x is the address of x[0]. This is legal and consistent.
As we have seen, a structure is a good way of storing related data together. It is also a good way of representing for( i=0; i<nsym; i++ )
Now `*y' gives x[0]. More importantly,
certain types of information. Complex numbers in mathematics inhabit a two dimensional plane (stretching in real if( sym[i].usage == 0 )
*(y+1) gives x[1]
and imaginary directions). These could easily be represented here by printf("%d\t%s\n", sym[i].line, sym[i].id);
*(y+i) gives x[i]
typedef struct {
and the sequence
double real;
y = &x[0];
double imag;
y++; Nested Structure
} complex;
leaves y pointing at x[1]. In fact the name of the array is itself a pointer to the first element of the array.
It is possible to declare a structure inside another structure. This means a structure can be made a member of
doubles have been used for each field because their range is greater than floats and because the majority of
The following program accepts elements for an array. The elements of the array are accessed using the name
another structure. The following program uses a structure called date as a member of another structure.
mathematical library functions deal with doubles by default.
of the array.
#include<stdio.h>
In a similar way, structures could be used to hold the locations of points in multidimensional space.
#include<conio.h>
Mathematicians and engineers might see a storage efficient implementation for sparse arrays here.
#include<stdio.h>
struct date
Apart from holding data, structures can be used as members of other structures.
main()
{
Arrays of structures are possible, and are a good way of storing lists of data with regular fields, such as databases.
{
int dd;
Another possibility is a structure whose fields include pointers to its own type.
int x,a[5];
int mm;
These can be used to build chains (programmers call these linked lists), trees or other connected structures.
printf(“Enter 5 elements\n”);
int yy;
These are rather daunting to the new programmer, so we won't deal with them here.
for(x=0;x<5;x++)
};
{
struct stud
scanf(“%d”,&a[x]);
{
}
char name[20];
printf(“The array elements are:\n”);
struct date d;
for(x=0;x<5;x++)
int m1,m2,m3;
{
float per;
printf(“%d\n”,*(a+x));
};
}
main()
}
{
Output:
struct stud s;
Enter 5 elements 1 2 3 4 5
printf("Enter the Details of student\n");
The array elements are 1 2 3 4 5
printf("\nName:");
scanf("%s",s.name); DEFINING A STRUCTURE / UNIONS POINTERS and STRUCTURES
printf("\nDate of Birth(dd mm yy):");
Before a structure is used, it has to be declared. The syntax for structure is as follows: Consider a block of data containing different data types defined by means of a structure. For example, a personal
scanf("%d%d%d",&s.d.dd,&s.d.mm,&s.d.yy);
struct <structure name> file might contain structures, which look something like:
printf("\nMarks in 3 Subject:");
{ struct tag
scanf("%d%d%d",&s.m1,&s.m2,&s.m3);
Data_type structure_element 1; {
s.per=(s.m1+s.m2+s.m3)/3;
Data_type structure_element 2; char lname[20]; /* last name */
printf("\nStudent Result");
Data_type structure _element 3; char fname[20]; /* first name */
printf("\n%s has secured %f%%",s.name,s.per);
Data_type structure_element n; int age; /* age */
getch();
}; };
}
Once, the new structure data type has been defined one or more variable can be declared of that structure type. Just like a variable of type structure, a pointer variable of type structure can also be declared. The following
Consider a structure declared as follows: program declares a pointer variable of type struct tag and uses this pointer variable to access every member of
Output:
struct student { the structure.
Enter the Details of student
char name[10]; Example:
Name:Ashwin
int rollno; #include<stdio.h>
Date of Birth(dd mm yy):12 12 1980
char sex; /* m or f */ struct tag
Marks in 3 Subject:98
int age; {
97
}; char lname[20];
95
This defines a new data type called student to be a structure with the specified shape; name, rollno, sex and age. char fname[20];
Student Result
A variable of type struct student can be declared as follows : int age;
Ashwin has secured 96.000000%
struct student collegestu, schoolstu; }s;
This statement allocates space in memory and makes available space to hold structure elements. A structure main()
ACCESSING and INITIALIZATION of STRUCTURE can be declared in any of the format given below. {
Format one: struct tag *t
Structure variable uses dot (.) operator to access structure element. Syntax to access the structure elements is
struct student { t = &s;
structure_name . structure_element_name
char name[10]; printf(“\nEnter the first name.”);
for example, To set the value to the structure element
int rollno; scanf(“%s”,t-> fname);
collegestu.rollno = 1125;
char sex; printf(“\nEnter the last name:”);
collegestu.age = 21;
int age; scanf(“%s”,t-> lname);
for example, To take the value from the structure element
}; printf(“\nAge:”);
int rnumber = colledestu.rollno;
struct student collegestu,schoolstu; scanf(“%d”,&t->age);
int stuage = collegestu.age;
printf(“\nThe details are:”);
The following program illustrates how structure members can be accessed.
Format two: printf(“Name:%s %s\nAge:%d”, t-> fname, t-> lname,t->age);
#include<stdio.h>
struct }
struct stud
{
{
char name[10]; Output:
int rno;
int rollno; Enter the first name:Mahatma
char name[20];
char sex; /* m or f */ Enter the last name:Gandhi
};
int age; Age:60
main()
} collegestu, schoolstu; The details are:Name:Mahatma Gandhi
{
Age:60
struct stud s;
printf(“Enter the student’s name:”); UNIONS
scanf(“%s”,s.name); A union is similar to a structure, except that it shares storage space between different members.Unlike a struct,
printf(“Enter the student’s roll number:”); the variables a_number.i and a_number.l occupy the same location in memory. Thus, writing into one will
scanf(“%d”,&s.rno); overwrite the other. Elements of a union are accessed in the same manner as a struct.
} Example
union int_or_long {
int i;
long l; } a_number;
STANDARD INPUT OUTPUT FILE / WHOLE LINES INPUT OUTPUT CHATECTER INPUT OUTPUT / FORMATTED INPUT OUTPUT FORMATTED INPUT OUTPUT / WHOLE LINE INPUT OUTPUT
The Standard Input File Stream, stdin The most basic way of reading input is by calling the function getchar. getchar reads one character from the We have been using the I/O built-in functions printf() and scanf() which are the primary routines for formatted
To input a value, the easiest way is to use a library function called scanf. There are other functions like getc and ``standard input,'' which is usually the user's keyboard, but which can sometimes be redirected by the operating output and input in C (the ``f'' stands for formatted).
getchar (both used for inputting characters), but scanf is by far the easiest to use. gets is another one that is system. getchar returns (rather obviously) the character it reads, or, if there are no more characters available, printf() expects arguments giving a format string and values to be printed. The printf() prototype, in stdio.h, is:
covered later. scanf is actually a simplified version of a function called fscanf which requires the programmer to the special value EOF (``end of file''). int printf(char *, ...);
specify an INPUT FILE STREAM. A companion function is putchar, which writes one character to the ``standard output.'' (The standard output is, The first argument of printf() is the format string.
This is basically a series of bytes that is transferred from the input source to the program (recall from the data again not surprisingly, usually the user's screen, although it, too, can be redirected. printf, like putchar, prints to The number of remaining arguments depends on the number of conversion specifiers in the format string.
types section that each character is one byte large, so a stream can be thought of as a series of characters). In the standard output; in fact, you can imagine that printf calls putchar to actually print each of the characters it In C, an ellipsis, i.e. ``...'', is used to indicate an arbitrary number of arguments. The return value of printf() is an
C, stdin is the standard input file stream and links to the keyboard. formats.) int giving the number of bytes output, if successful; otherwise it returns EOF. This information from printf() is not
The Standard Output File Stream, stdout Using these two functions, we can write a very basic program to copy the input, a character at a time, to the generally very useful, and we often simply ignore the return value.
output: The function, printf(), converts, formats, and prints its arguments on the standard output using the conversion
putc, putchar, puts and printf are all used to output values. The latter is the simplest to use.
#include <stdio.h> specifications given in the format string.
Some of these require an OUTPUT FILE STREAM, which is a series of bytes that is transferred from the output
/* copy input to output */ The format string is made up of two kinds of characters: regular characters, which are simply copied to the output,
source to the program. stdout is the standard output file stream and refers to the monitor.
main() and conversion specification characters.
stderr is also an output file stream but makes sure that the output, usually an error message, is seen.
{ A conversion specification indicates how the corresponding argument value is to be converted and formatted
getc() and getchar()
int c; before being printed.
These functions allow the programmer to input a character and assign it to a variable.
c = getchar(); The number of conversion specifications in the format string must match exactly the number of arguments that
getc requires the programmer to specify an input file stream like stdin. getchar is EXACTLY the same as getc
while(c != EOF) follow; otherwise, the results are undefined.
with the input file stream set to stdin.
{ The data type of the argument should also match the data type it will be converted to; for example, integral types
Both functions return integer values, which could be assigned to variables for later use.
putchar(c); for decimal integer formats, float or double types for floating point or exponential formats, and so on.
putc() and putchar()
c = getchar(); If the proper type is not used, the conversion is performed anyway assuming correct data types and the results
To output a character, one of these two functions can be used:
} can be very strange and unexpected. Of course, character values are integral types; so characters can be
putc requires to specify two things - the variable whose character value should be printed out, and the file output
return 0; converted to ASCII integer values for printing, or printed as characters.
stream.
} The syntax of a complete conversion specifier
putchar is exactly the same as putc, but with the output file stream set to stdout. It is only needed to specify the
This code is straightforward, and I encourage you to type it in and try it out. It reads one character, and if it is not %-DD.ddlX
character value to print out.
the EOF code, enters a while loop, printing one character and reading another, as long as the character read is
The other format characters must appear in the order specified above and represent the following formatting
The following example demonstrates the previous four functions:
not EOF. This is a straightforward loop, although there's one mystery surrounding the declaration of the variable
information: (the corresponding characters are shown in parentheses).
Example:
c: if it holds characters, why is it an int?
#include <stdio.h> Justification ( -)
FORMATTED INPUT OUTPUT
int main() The first format character is the minus sign. If present, it specifies left justification of the converted argument in
We have been using the I/O built-in functions printf() and scanf() which are the primary routines for formatted
{ its field. The default is right justification, i.e. padding on the left with blanks if the field specified is wider than the
output and input in C (the ``f'' stands for formatted).
char a,b; converted argument.
printf() expects arguments giving a format string and values to be printed. The printf() prototype, in stdio.h, is:
printf("Enter a 2 letter word "); Field Width ( DD)
int printf(char *, ...);
printf("and press return: "); The field width is the amount of space, in character positions, used to print the data item. The digits, DD, specify
The first argument of printf() is the format string.
a = getc(stdin); the minimum field width. A converted argument will be printed in a field of at least this size, if it fits into it; otherwise,
The number of remaining arguments depends on the number of conversion specifiers in the format string.
b = getchar(); the field width is made large enough to fit the value. If a converted argument has fewer characters than the field
In C, an ellipsis, i.e. ``...'', is used to indicate an arbitrary number of arguments. The return value of printf() is an
printf("The first letter was: "); width, by default it will be padded with blanks to the left, unless left justification is specified, in which case, padding
int giving the number of bytes output, if successful; otherwise it returns EOF. This information from printf() is not
putc(a, stdout); is to the right.
generally very useful, and we often simply ignore the return value.
printf("\nFollowed by: "); Separator ( .)
The function, printf(), converts, formats, and prints its arguments on the standard output using the conversion
putchar(b); A period is used as a separator between the field width and the precision specification.
specifications given in the format string.
putchar(10); Precision ( dd)
The format string is made up of two kinds of characters: regular characters, which are simply copied to the output,
printf("Goodbye!\n");
and conversion specification characters. A conversion specification indicates how the corresponding argument The digits, dd, specify the precision of the argument. If the argument is a float or double, this specifies the number
}
value is to be converted and formatted before being printed. of digits to the right of the decimal point. If an argument is a string, it specifies the maximum number of characters
Suppose YO is entered and pressed return.
The number of conversion specifications in the format string must match exactly the number of arguments that to be printed from the string.
The output generated would be:
follow; otherwise, the results are undefined. Length Modifier ( l)
Enter a 2 letter word and press return: YO
The data type of the argument should also match the data type it will be converted to; for example, integral types The length modifier, l, (ell) indicates that an integer type argument is a long rather than an int type.
The first letter was: Y
for decimal integer formats, float or double types for floating point or exponential formats, and so on.
Followed by: O
If the proper type is not used, the conversion is performed anyway assuming correct data types and the results
Goodbye!
can be very strange and unexpected. Of course, character values are integral types; so characters can be
After declaring two character variables, two printf statements were used to display the first line of text.
converted to ASCII integer values for printing, or printed as characters.
As soon as the user enters a character, it gets assigned to the variable a because the getc function was INVOKED
- a term meaning the calling of a function. Notice how the standard input stream, stdin had to be PASSED into
Character Conversion The syntax of a complete conversion specifier getc. Values passed into a function are called ARGUMENTS - a function sometimes needs extra information for
d The argument is taken to be an integer and converted to decimal integer notation. %-DD.ddlX it to work.
o The argument is taken to be an integer and converted to unsigned octal notation without a As soon as the user enters a second character, it gets assigned to b - notice how getchar requires no arguments.
The other format characters must appear in the order specified above and represent the following formatting
leading zero. The program continues when return is pressed - any additional characters after the second aren't stored.
information: (the corresponding characters are shown in parentheses).
x The argument is taken to be an integer and converted to unsigned hexadecimal notation without The putc function takes a char or int variable as its first argument, followed by the standard output stream, stdout
Justification ( -)
a leading 0x. and prints out the specified character.
The first format character is the minus sign. If present, it specifies left justification of the converted argument in
u The argument is taken to be an unsigned integer and converted to unsigned decimal notation. putchar only requires one argument, and also prints out the specified character.
its field. The default is right justification, i.e. padding on the left with blanks if the field specified is wider than the
c The argument is taken to be an ASCII character value and converted to a character. As a reminder, \n is the NEWLINE character and is the equivalent to a carriage return. It has an ASCII code of
converted argument.
s The argument is taken to be a string pointer. Unless a precision is specified as discussed below, 10, so putchar(10) inserts a newline before printing "Goodbye!".
Field Width ( DD)
characters from the string are pointed out until a NULL character is reached printf and scanf
The field width is the amount of space, in character positions, used to print the data item. The digits, DD, specify
f The argument is taken to be a float or double. It is converted to decimal notation of the form [-] printf
the minimum field width. A converted argument will be printed in a field of at least this size, if it fits into it; otherwise,
ddd.dddddd, where the minus sign shown in square brackets may or may not present. The printf gives the programmer the power to print output onto the screen, and is relatively simple to use.
the field width is made large enough to fit the value. If a converted argument has fewer characters than the field
number of digits, d, after the decimal point is 6 by default if no precision is specified. The number The number of arguments required varies, but the first argument that is passed should be a STRING - a string
width, by default it will be padded with blanks to the left, unless left justification is specified, in which case, padding
of digits, d, before the decimal is as required for the number. can be assumed as a sequence of characters.
is to the right.
e The argument is taken to be a float or double. It is converted to decimal notation of the form Recall that a string must be surrounded by double quote marks. Here's printf in action once again:
Separator ( .)
[-]d.ddddddE[+/-]xxx, where the leading minus sign may be absent. There is one digit before the printf("Hello World!\n");
A period is used as a separator between the field width and the precision specification.
decimal point. The number of digits, Notice how the string, "Hello World!\n" is enclosed in double quote marks.
d, after the decimal point is 6 if no precision is specified. The E signifies the exponent, ten followed Precision ( dd)
by a plus or minus sign, followed by an exponent. The number of digits in the exponent, x, is The digits, dd, specify the precision of the argument. If the argument is a float or double, this specifies the number
implementation dependent, but not less than two. of digits to the right of the decimal point. If an argument is a string, it specifies the maximum number of characters WHOLE LINES INPUT OUTPUT
g The same as %e or %f whichever is shorter and excludes trailing zeros. to be printed from the string. Where we are not too interested in the format of our data, or perhaps we cannot predict its format in advance,
Length Modifier ( l) we can read and write whole lines as character strings. This approach allows us to read in a line of input, and
A complete conversion specification starts with the character % and ends with a conversion character. Between The length modifier, l, (ell) indicates that an integer type argument is a long rather than an int type. then use various string handling functions to analyse it at our leisure.
these two characters, special format characters may be used which can specify justification, field width, field gets
separation, precision, and length modification. Character Conversion gets reads a whole line of input into a string until a newline or EOF is encountered. It is critical to ensure that the
The characters that follow the % character and precede the conversion characters are called format characters. string is large enough to hold any expected input lines. When all input is finished, NULL as defined in stdio.h is
d The argument is taken to be an integer and converted to decimal integer notation.
All format characters are optional, and if they are absent their default values are assumed. returned.
o The argument is taken to be an integer and converted to unsigned octal notation without a
leading zero. puts
x The argument is taken to be an integer and converted to unsigned hexadecimal notation without puts writes a string to the output, and follows it with a newline character.
WHOLE LINES INPUT OUTPUT a leading 0x. Example: Program which uses gets and puts to double space typed input.
u The argument is taken to be an unsigned integer and converted to unsigned decimal notation. #include <stdio.h>
Where we are not too interested in the format of our data, or perhaps we cannot predict its format in advance,
c The argument is taken to be an ASCII character value and converted to a character. main()
we can read and write whole lines as character strings. This approach allows us to read in a line of input, and
s The argument is taken to be a string pointer. Unless a precision is specified as discussed below, { char line[256]; /* Define string sufficiently large to
then use various string handling functions to analyse it at our leisure.
characters from the string are pointed out until a NULL character is reached store a line of input */
gets
f The argument is taken to be a float or double. It is converted to decimal notation of the form [-] while(gets(line) != NULL) /* Read line */
gets reads a whole line of input into a string until a newline or EOF is encountered. It is critical to ensure that the
ddd.dddddd, where the minus sign shown in square brackets may or may not present. The { puts(line); /* Print line */
string is large enough to hold any expected input lines. When all input is finished, NULL as defined in stdio.h is
number of digits, d, after the decimal point is 6 by default if no precision is specified. The number printf("\n"); /* Print blank line */
returned.
of digits, d, before the decimal is as required for the number. }
puts e The argument is taken to be a float or double. It is converted to decimal notation of the form }
puts writes a string to the output, and follows it with a newline character. [-]d.ddddddE[+/-]xxx, where the leading minus sign may be absent. There is one digit before the Note that putchar, printf and puts can be freely used together. So can getchar, scanf and gets.
Example: Program which uses gets and puts to double space typed input. decimal point. The number of digits,
#include <stdio.h> d, after the decimal point is 6 if no precision is specified. The E signifies the exponent, ten followed
main() by a plus or minus sign, followed by an exponent. The number of digits in the exponent, x, is
{ char line[256]; /* Define string sufficiently large to implementation dependent, but not less than two.
store a line of input */ g The same as %e or %f whichever is shorter and excludes trailing zeros.
while(gets(line) != NULL) /* Read line */
{ puts(line); /* Print line */ A complete conversion specification starts with the character % and ends with a conversion character. Between
printf("\n"); /* Print blank line */ these two characters, special format characters may be used which can specify justification, field width, field
} separation, precision, and length modification.
} The characters that follow the % character and precede the conversion characters are called format characters.
Note that putchar, printf and puts can be freely used together. So can getchar, scanf and gets. All format characters are optional, and if they are absent their default values are assumed.
FORMAT SPECIFIERS / INPUTING MULTIPLE VALUES MINIMUM FIELD WIDTH / MAKING IT LOOK NEATER MORE PRECISION
To print the value of variables requires the programmer to embed a format specifier in the text string, and to pass Suppose if need arises for the program to display output that occupies a minimum number of spaces on the More control with the displaying of integers can be gained by placing a dot, followed byMore control with the
extra arguments to the printf function. screen, this can be achieved by adding an integer value after the percent sign of a format specifier. displaying of integers can be gained by placing a dot, followed by an integer, after the minimum field specifier.
example: For example, if an integer is to be displayed using a minimum of 8 spaces, %8d should be written in the printf The dot and this integer are known as a PRECISION SPECIFIER.
printf("x equals %d \n", x); statement. The integer added specifies the maximum field width when displaying an integer or string. If %f is used, the format
This statement prints the value of x out. The value of x is to be passed into the printf function. When arguments This example gives a demonstration: specifier for floating point numbers, it is possible to control the number of decimal places that is displayed (which
are passed to functions, each one should be separated with a comma - here, "x equals %d \n" is an argument, #include <stdio.h> is 6 by default). Using the precision specifier does this. This time, the number after the dot is the number of
so is x. There are several format specifiers - the one that is used should depend on the type of the variable that int main() { decimal places. The number before the dot is still the minimum field width.
is to be printed out. Here are the common ones: int x = 123; This example should help clarify things:
Format Specifier Type printf("Printing 123 using %%0d displays %0d\n", x); #include <stdio.h>
%d (or %i) int printf("Printing 123 using %%1d displays %1d\n", x); int main() {
%c char printf("Printing 123 using %%2d displays %2d\n", x); float x = 3.141592;
%f float / double return 0; printf("Printing 3.141592 using %%f \t displays %f\n", x);
%s string } printf("Printing 3.141592 using %%1.1f \t displays %1.1f\n", x);
To display a number in scientific notation, %e should be used. To display a percent sign, %% should be used. Output: printf("Printing 3.141592 using %%1.2f \t displays %1.2f\n", x);
Caution: Don't try to display a decimal number using the integer format specifier, %d, as this displays unexpected Printing 123 using %0d displays 123 printf("Printing 3.141592 using %%3.3f \t displays %3.3f\n", x);
values. Similarly, don't use %f for displaying integers. Mixing %d with char variables, or %c with int variables is Printing 123 using %1d displays 123 printf("Printing 3.141592 using %%4.4f \t displays %4.4f\n", x);
all right, as shown in this example: Printing 123 using %2d displays 123 printf("Printing 3.141592 using %%4.5f \t displays %4.5f\n", x);
Example: Notice that in the first 4 cases, 123 is displayed in the same way as when %d is normally used. This is because printf("Printing 3.141592 using %%09.3f displays %09.3f\n", x);
#include <stdio.h> the number of spaces on the screen that 123 can be displayed is greater than or equal to 3. printf("Printing 3.141592 using %%-09.3f displays %-09.3f\n", x);
int main() But also, if %09d is written, the program will display zeros before the number itself. In the above example, it will printf("Printing 3.141592 using %%9.3f displays %9.3f\n", x);
{ display: printf("Printing 3.141592 using %%-9.3f displays %-9.3f\n", x);
int a = 72; Printing 123 using %09d displays 000000123 return 0;
char b = 'A'; An advantage of using this is that it is possible to count the minimum field of the number! }
printf("a equals %d \n", a); Making It Look Neater Output:
printf("a equals %c \n", a); The output from the example above doesn't look very neat because the numbersare aligned to the right of the Printing 3.141592 using %f displays 3.141592
printf("b equals %d \n", b); minimum field. In other words, 1,2 and 3 are the digits in the furthest 3 spaces of the minimum field. Printing 3.141592 using %1.1f displays 3.1
printf("b equals %c \n", b); To align the output on the left, a minus sign before the number in the format Printing 3.141592 using %1.2f displays 3.14
} specifier should be inserted. But if this to done to the previous example, all the output Printing 3.141592 using %3.3f displays 3.142
Output: lines will be the same. Printing 3.141592 using %4.4f displays 3.1416
a equals 72 A better example: Printing 3.141592 using %4.5f displays 3.14159
a equals H #include <stdio.h> Printing 3.141592 using %09.3f displays 00003.142
b equals 65 int main() { Printing 3.141592 using %-09.3f displays 3.142
b equals A int x = 12; Printing 3.141592 using %9.3f displays 3.142
The reason why this works is because a character constant is just an integer from 0 to 255. int y = 123; Printing 3.141592 using %-9.3f displays 3.142
Two or More Format Specifiers printf("Printing 12 using %%9d \t\t displays %9d\n", x);
As many format specifiers can be used, as needed with printf - just as long as the correct number of arguments printf("Printing 12 using %%09d \t\t displays %09d\n", x); If a negative value for the minimum width specifier is used, a zero after the minus sign will not affect the output.
are passed. printf("Printing 123 using %%9d \t\t displays %9d\n", y); Also, in the case for decimal numbers, the decimal point occupies a character space on the screen.
The ordering of the arguments matters. The first one should correspond to the first format specifier in the string printf("Printing 123 using %%09d \t displays %09d\n", y);
and so on. Take this example: return 0;
printf("a=%d, b=%d, c=%d\n", a,b,c); }
If a, b and c were integers, this statement will print the values in the correct order. Rewriting the statement as...
printf("a=%d, b=%d, c=%d\n", c,a,b); Output:
... would still cause the program to compile OK, but the values of a,b and c would be displayed in the wrong order! Printing 12 using %9d displays 12
scanf Printing 12 using %09d displays 000000012
scanf is a lot more flexible to use than the getchar and getc functions, simply because it is possible input numbers Printing 123 using %9d displays 123
and strings, as well as characters. Printing 123 using %09d displays 000000123
Here is an example: \t acts like a standard tab. Notice how it begins with a backslash, \ - just like the new line character.
writes the string pointed to by line to the stream fp. Like puts, fputs returns a nonnegative value or EOF on error. putchar( c ); When the above program is executed, it reads the data from the file called temp.txt and displays the content of
Unlike puts, fputs does not automatically append a \n. Here is a program which demonstrates the use of fputs(). } the file.
In the following program, the file “t.t” contains 17 characters. Input: (Enter the characters)
The function fgets accepts a number which is 1 more than the number of characters to be read.That is why it God helps those who help themselves
#include<stdio.h> The following program illustrates how the functions getc() and putchar() can be used to read information from a
main() #include<stdio.h>
{ main()
FILE *a; {
} putchar( c );
Output: }
The text from file is: This is a test Output: God helps those who help themselves
character, which is usually one of: declaring it as an array of char. The data is formatted according to a control string of the same form as that for
OUTPUT:
The text copied into file sampledup.txt as follows
This is my first program.
REVERSE AN ARRAY USING POINTERS REVERSE OF A STRING USING POINTERS CONCATENATE TWO STRINGS USING POINTERS
#include <stdio.h> #include <stdio.h> #include <stdio.h>
#include <string.h> void stringConcat(char *dest, const char *src)
#define SIZE 10 {
void reverseString(char *str) { while (*dest != '\0') {
int main() { char *start = str; dest++;
int arr[SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; char *end = str + strlen(str) - 1; }
int *startPtr = arr; char temp; while (*src != '\0')
int *endPtr = arr + SIZE - 1; {
while (start < end) { *dest = *src;
// Reverse the array using pointers temp = *start; src++;
while (startPtr < endPtr) { *start = *end; dest++;
int temp = *startPtr; *end = temp; }
*startPtr = *endPtr; *dest = '\0';
*endPtr = temp; start++; }
startPtr++; end--; int main() {
endPtr--; } char str1[100] = "Hello, ";
} } char str2[] = "world!";
stringConcat(str1, str2);
// Display the reversed array int main() { printf("Concatenated string: %s", str1);
printf("Reversed Array: "); char str[100]; return 0;
for (int i = 0; i < SIZE; i++) { printf("Enter a string: "); }
printf("%d ", arr[i]); gets(str);
}
reverseString(str);
return 0; printf("Reversed string: %s", str);
TO FIND ODD or EVEN NUMBER
} return 0; #include<stdio.h>
} #include<conio.h>
int flag; printf("Enter two integers > "); printf("\nSum of %d natural numbers = %d", n, sum);
flag = 0; }
PRINT MULTIPLICATION TABLE - number entered by the user
else MULTIPLY TWO NUMBERS.
#include<stdio.h>
i++; #include<stdio.h>
#include<conio.h>
} #include<conio.h>
void main ( )
if (flag) void main ()
{
printf("%d is prime\n", n); {
int num,i;
else int number1, number2; /* Numbers to be multiplied*/
clrscr();
printf("%d has %d as a factor\n", n, i); int result; /* Result stores the result of multiplication*/
printf(“Enter the number”);
} clrscr();
scanf(“%d”,&num);
printf (“Enter two numbers”);
for (i=1;i<=10;i++)
scanf(“%d%d”, &number1,&number2);
{
result=(number1*number2);
printf(“\n%d*%d = %d”,num,i,num*i);
printf(“The result is:%d”, result);
}
getch();
getch();
}
}