C Programming (1)
C Programming (1)
CS101
What is a computer program?
A set of instructions that is given to a computer to achieve some particular tasks.
int main()
printf(“Hello World!!”);
return 0;
}
Steps
❏ User has a task.
❏ User writes a program in C language (called source code)
❏ When program is build and run. Source code is converted into extended
source code by Preprocessing directives.
❏ Extended source code is compiled successfully if there’s no error else all
errors are show by the compiler at once for users to fix.
❏ In case of standard library functions or any external reference linker
helps.
❏ Finally loader loader the executable code into primary memory for
execution.
Features of C Programming Language
1. It is a procedural language.
2. It provides modularity structure hence can be easily extended
3. portable
4. Fast
5. Compiler based
6. Interaction with memory and other hardware connections
7. Rich set of built in operators and libraries.
Limitations:
❏ Keywords : fixed terms that are pre defined in the language e.g.
int a=5;
❏ Identifiers : these are user defined terms that represents a data
type, function etc. e.g. int a=5;
❏ Operators : ++, sizeof(), *, /
❏ Punctuation : (), {}
❏ Literals : tokens that denotes a fixed value that can be int, string,
character, float etc. e.g. int a=5;
Data Types
❏ Primary/ primitive/ fundamental
❏ Int
❏ Float
❏ Double
❏ Void
❏ char
❏ User defined
❏ Struct
❏ Union
❏ Enum, typedef
❏ Derived
❏ Function, array, pointers
Primitive Data Type
❏ These are the most basic data types in C.
❏ These are used to create other data types.
❏ These can be assigned to variables to represent simple values.
❏ Examples: int, float, char, double etc.
❏ These can have the different sizes (word/byte) on different compiler.
❏ Size order:- char<short<int<float<double
Fundamental Data Types
#include<stdio.h>
int main()
int a=5;
float b=5.4f;
double d=4.56;
char c='c';
return 0;
printf("Hello World!!\n");
{ printf("%d", a[i]);}
int main(){
int a[]={1,2,3,4,5};
int size=sizeof(a)/sizeof(a[0]);
greeting(a, size);
return 0;
}
User Defined Data Types
struct node {
int val;
struct node *next;
};
Main function
int main() {
}
Main function continues…
return 0;
}
Topics
❏ Short
❏ Unsigned
❏ Signed
❏ Long
Eg: long long int, long double, long int, unsigned int, short etc.
Format Specifier
These are placeholder which directs the functions of standard input output library
to replace them with the suitable datatype.
%d : int
%f : float
%c : char
%s : string
❏ It represents nothing.
❏ It is a placeholder for showing no data type.
❏ Cannot write : e.g. void var;
❏ But : e.g. void fun(void); is correct
❏ Void pointer can take any pointer data type as reference but to
dereference a typecasting is required
e.g. void* vp; int* var; … vp=var; but printf(*vp); is wrong, but
printf(*(int*)vp); is correct.
NULL Character/pointer
❏ The Null Character in C is a special character with an ASCII value of 0 (zero).
❏ It is not the same as the character ‘0’ which has an ASCII value of 48.
❏ The Null Character in C is used to denote the end of a C string, indicating that
there are no more characters in the sequence after it.
❏ In memory, the Null Character in C is represented by a byte filled with all bits set
to 0
❏ such an expression cast to type void *, is called a null pointer constant.
❏ If a null pointer constant is converted to a pointer type, the resulting pointer,
called a null pointer, is guaranteed to compare unequal to a pointer to any
object or function
Operators
These are symbols that take two or more operands and perform some operations
on them and returning some values.
Associativity tells the compiler which operator is prioritized over the other in a
sequence when the operators have the same precedence.
Conditional Statements: statements in c which can change
the course of execution of the program based on some
condition.
1. If
2. If else
3. Nested if else
4. If else if ladder
5. Switch : expression either integer or character
6. Ternary operator
If (condition)
{if is true this block is executed and not the else block is executed}
Else
If (a>b){printf(“true block”);}
switch(v)
E.g.
1. For loop
2. Do while
3. while
Conditional Jump
❏ for(initialization; condition; increment/decrement)
{ block }
❏ While (condition){block;}
syntax
for(int i=0; i<5; i=i+1)
if(i==5)
break;
//continue;
}
goto <label>
void even(int num)
divisible:
{
printf("\n%d is even", num);
if (num % 2 == 0) // return if even
// jump to even //return;
}
Need for array:-
1. Storing data for processing
2. Implementing data structures like queues and stacks
3. Representing data in tables and matrices
4. Creating dynamic data structures like linked lists and trees.
Operations:-
❏ Traversal
❏ Insertion
❏ Deletion
❏ searching
Pointer
A derived data type which can store the address (memory location) of the
variables, and capable of modifying the value stored at that address.
int main()
int a=10;
int* ptr=&a;
*ptr=*ptr+2;
return 0;
}
Functions
A function is a set of codes that can be called to perform a specific task. It can
accept some input and produces one output and returns the value (output).
It facilitates
❏ Code reproducibility
❏ Modularity
❏ abstraction
Function Syntax
1. Declaration:
<return_type> <function_name> (<arguments>);
e.g. int main(int argc, char** argv) ;
2. Definition :
int main()
{
//code to perform tasks
return 0;
}
Function Syntax
3. Call:
// codes
return <return_type>;
}
Working with functions
1. in program, make the function declaration.
2. Then make function definition.
3. In the other place (like main function) make the function call.
4. Make sure the return type of function should match return type of function
declaration and variable making the function call.
5. When a function is called; the function starts to create according to its
definition in the stack memory. Then function performs tasks and return
data_type and perishes thereafter.
6. Anytime a function is called step 5 is repeated and all local variables inside
the function die after function is destroyed.
Arguments Pass by value
void sum(int a) int main()
{ {
return 0;
}
Arguments Pass by reference
void sum(int* a) int main()
{ {
return 0;
}
Pointer to function: a pointer to a function name
#include<stdio.h> int main(void)
{
int main()
{
// Local variable x
int x = 10;
{
extern int x;
printf("Value of global x is %d\n", x);
}
printf("Value of local x is %d\n", x);
return 0;
}
printf()
It returns the total no of characters successfully printed.
#include <stdio.h>
int main()
{
char st[] = "CODING";
return 0;
}
Nested function:A nested function is a function defined inside the definition of another function.
int fun()
#include <stdio.h>
{
return 1;
}
Variadic function: function which takes variable no. of inputs.
printf(<string>,...)
scanf(<>, …)
return sum;
}
Recursive function
Recursion is the process of a function calling itself repeatedly till the given condition is satisfied. A function that calls itself
directly or indirectly is called a recursive function and such kind of function calls are called recursive calls.
Syntax:-
// function statements
// base condition
}
Recursive function…
#include <stdio.h> int sum(int k) {
int sum(int k);
if (k > 0) {
● argc is an integer variable that stores the number of command-line arguments passed by the user
including the name of the program. So if we pass a value to a program, the value of argc would be 2
(one for argument and one for program name)
● The value of argc should be non-negative.
● argv is an array of character pointers listing all the arguments.
● If argc is greater than zero, the array elements from argv[0] to argv[argc-1] will contain pointers to
strings.
● argv[0] is the name of the program , After that till argv[argc-1] every element is command -line
arguments.
>>>gcc <program_name>
>>>./a “arg1” “arg2” “arg_N”
Command line arguments
#include <stdio.h>
Syntax:
switch(var)
{
case low_value … high_value: statement; break;
case low_value … high_value: statement; break;
default: statement;
}
case 1 ... 6:
#include <stdio.h>
printf("%d in range 1 to 6\n", arr[i]);
int main()
break;
{
// range 19 to 20
int arr[] = { 1, 5, 15, 20 };
case 19 ... 20:
for (int i = 0; i < 4; i++) {
printf("%d in range 19 to 20\n", arr[i]);
switch (arr[i]) { break;
// range 1 to 6 default:
1. Macros
2. File inclusion
3. Conditional compilation
4. Miscellaneous directives
Preprocessor Directives (#)
// macro definition
#define LIMIT 5
Syntax:
❏ In a macro call the preprocessor replaces the macro template with its
macro expansion, in a literal way.
❏ As against this, in a function call the control is passed to a function
along with certain arguments, some calculations are performed in the
function and a useful value is returned back from the function.
❏ Usually macros make the program run faster but increase the
program size,
❏ whereas functions make the program smaller and compact.
❏ If we use a macro N times in a program, the macro expansion goes into our
source code at N different places, thus increasing the program size.
❏ On the other hand, if a function is used, then even if it is called from hundred
different places in the program, it would take the same amount of space in the
program.
❏ Passing arguments to a function and getting back the returned value does
take time and would therefore slow down the program.
❏ This gets avoided with macros since they have already been expanded and
placed in the source code before compilation.
❏ As a convention, avoid large macros (use function) but small and multiplace
occurring.
#include: File Inclusion Directive
This directive causes one file to be included in another. The preprocessor
command for file inclusion looks like this:
#include "filename" : user defined header files
#include <stdio.h> : standard header files
e.g. declaration of printf or scanf is not included in the source code while
header file stdio.h is included to add declaration for these methods.
❏ If we have a very large program, the code is best divided into several different files,
each containing a set of related functions.
❏ It is a good programming practice to keep different sections of a large program
separate.
❏ These files are #included at the beginning of main program file.
❏ There are some functions and some macro definitions that we need almost in all
programs that we write.
❏ These commonly needed functions and macro definitions can be stored in a file, and
that file can be included in every program we write, which would add all the statements
in this file to our program
❏ as if we have typed them in.
❏ It is common for the files that are to be included to have a .h extension.
User defined vs standard header file
#ifdef macro_name
2. #ifdef Directive
// Code to be executed if macro_name is not
defined
#else
#endif
#if and #elif Directives
The #if directive can be used to test whether an expression evaluates to a nonzero
value or not.
If the result of the expression is nonzero, then subsequent lines upto a #else, #elif
or #endif are compiled, otherwise they are skipped.
Conditional (#) Directives
#include <stdio.h>
// #ifndef Directive: Check if FEATURE_B is not defined
// Define some macros
#ifndef FEATURE_B
#define FEATURE_A 1 printf("FEATURE_B is not enabled\n");
#else
// #define FEATURE_B 1 printf("FEATURE_B is enabled\n");
#endif
//#define FEATURE_C 1
// #if Directive: Check if FEATURE_C is defined and has a
int main() { non-zero value
// #ifdef Directive: Check if FEATURE_A is
#if defined(FEATURE_C) && FEATURE_C == 1
defined
printf("FEATURE_C is enabled\n");
#ifdef FEATURE_A
#elif defined(FEATURE_C) && FEATURE_C == 2
printf("FEATURE_C is set to 2\n");
printf("FEATURE_A is enabled\n"); #else
printf("FEATURE_C is not enabled or has an unexpected
#endif value\n");
#endif
return 0;
}
Miscellaneous Directives (#)
Miscellaneous Directives
Apart from the above directives, there are two more directives that are not commonly used. These are:
Syntax
#pragma directive
1. #pragma startup: These directives help us to specify the functions that are needed to run before program startup (before the control passes to
main()).
2. #pragma exit: These directives help us to specify the functions that are needed to run just before the program exit (just before the control
returns from main()).
#undef
#include <stdio.h> // Now, trying to use PI again would cause an error or no
output if checked.
// Define a macro
// Uncommenting the line below would cause a
#define PI 3.14159 compilation error because PI is undefined.
Bound checking:-
void main( )
int num[40], i ;
num[i] = i ;
}
/* Demonstration of call by reference */
/* Demonstration of call by value */
main( )
main( ) {
{ int i ;
int marks[ ] = { 55, 65, 75, 56, 78, 78, 90 } ; for ( i = 0 ; i <= 6 ; i++ )
}
display ( marks[i] ) ;
disp ( int *n )
} {
{ }
}
void main( ) void show(?)
{ {
disp ( &marks[i] ) ;
disp ( int *n )
show ( &n ) ;
}
Pointer
A pointer is defined as a derived data type that can store the address of other C variables or a memory location.
The elements of 2-D array can be accessed with the help of pointer notation also.
Let arr is a 2-D array, we can access any element arr[i][j] of the array using the pointer expression *(*(arr + i)
+ j). Now we’ll see how this expression can be derived.
E.g. int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
Accessing elements of array by pointer
#include<stdio.h>
{10, 11, 12, 13}, int num[ ] = { 24, 34, 12, 44, 56, 17 } ;
int i ;
{20, 21, 22, 23},
for ( i = 0 ; i <= 5 ; i++ )
{30, 31, 32, 33}
{
};
printf("%p %p %p\n", *ptr, *(ptr + 1), *(ptr + 2)); printf ( "%d %d", *( i + num ), i[num] ) ;
// Pointer subtraction
(c) Division of a pointer with a constant int diff = ptr2 - ptr1; // This gives the number of
elements between ptr2 and ptr1
return 0;
}
Subtraction: if both variables point to elements of the same array
❏ The result of the subtraction is a
signed integer of type Comparison:-
ptr_diff_type, which represents
the number of elements. int a = 10, b = 20;
❏ Subtracting pointers from different int *p1 = &a;
arrays or invalid memory locations int *p2 = &b;
results in undefined behavior. int *p3 = &a;
❏ Pointer subtraction is useful when if (p1 == p2)
dealing with array indices and { printf("p1 and p2 point to the same location\n"); }
traversing data structures in memory. else { printf("p1 and p2 point to different locations\n"); }
❏ Pointer variables can be compared if (p1 == p3)
provided both variables point to { printf("p1 and p3 point to the same location\n"); }
objects of the same data type. Such
comparisons can be useful when both
pointer variables point to elements of
the same array.
(a) Array elements are always stored in contiguous memory
locations.