Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
2 views

C Programming (1)

The document provides an overview of computer programming, focusing on the C programming language, its features, data types, and programming concepts. It explains the differences between high-level and low-level languages, the structure of C programs, and various programming constructs such as conditional statements, loops, and functions. Additionally, it covers pointers, arrays, and user-defined data types, along with examples and syntax for better understanding.

Uploaded by

Naresh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

C Programming (1)

The document provides an overview of computer programming, focusing on the C programming language, its features, data types, and programming concepts. It explains the differences between high-level and low-level languages, the structure of C programs, and various programming constructs such as conditional statements, loops, and functions. Additionally, it covers pointers, arrays, and user-defined data types, along with examples and syntax for better understanding.

Uploaded by

Naresh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 179

Computer Programming

CS101
What is a computer program?
A set of instructions that is given to a computer to achieve some particular tasks.

There are two types of programming languages:-

1) High level languages


2) Low level languages
HLL vs LLL
Easy for any users Experts
High Level Language (HLL)
1. Easy to understand
2. Easy to write
3. Easy fixing
4. Portable
5. Often platform independent/machine independent
6. These are primary choices of programming

E.g. print(“Hello World!!”)

Python, java, c, c++


Low Level Language (LLL)
1. Difficult to understand
2. Difficult to write
3. Difficult to debug
4. Not portable
5. Machine dependent
6. Primary choices for machine programming
7. Comparatively fast
Eg: Assembly language, machine code, ada, c, fortran etc.
100100 011100
LDA addr
C Program
● general-purpose programming language
● created by Dennis Ritchie
● the Bell Laboratories in 1972.

Easy for the users to write and understand (HLL)


Also, used to write program for kernel, machine hardware,
databases etc. (LLL)
Middle Level Language (like fortran)
Compiler vs (/ Interpreter)

● C is a compiler based programming language.


● It lists all the errors at once. (/does not stop at any error in line)
● Scans the code completely. (/ execute line by line)
● Creates an intermediate object code (/directly executed by the
interpreter)
C-programming
#include <stdio.h>

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:

❏ Comparatively difficult for the users than the other programming


languages.
❏ Lack concepts of OOP
❏ Not suitable for the modern age problems (AI, Big data, web
technology etc.)
❏ Manual memory management (/ use of pointers)
❏ Lack of exception handling etc.
Elements of C-Programming Language

❏ 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';

printf("a=%d, b=%f, c=%c, d=%lf", a, b, c, d);

return 0;

>>>a=5, b=5.400000, c=c, d=4.560000


Derived Data Types
❏ These are formed from primitive data types.
❏ These provides more flexibility in assigning values.
❏ These data types enhances the functionality of the program.
❏ Examples :- function , array, pointer etc.
Derived Data Types
#include<stdio.h>

void greeting(int a[], int size){

printf("Hello World!!\n");

for (int i=0; i<size; i++)

{ 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

❏ User define these data types as per their requirements.


❏ It provides more flexibility and abstraction.
❏ It can be consisting of primitive as well as derived data types.
Example of derived data type: struct
#include <stdio.h>
#include <stdlib.h> // For malloc

struct node {
int val;
struct node *next;
};
Main function
int main() {

// Allocate memory for root and leaf nodes

struct node* root = malloc(sizeof(struct node));

struct node* leaf = malloc(sizeof(struct node));


Main function continues…
// Check if memory allocation was successful

if (root == NULL || leaf == NULL) {

fprintf(stderr, "Memory allocation failed\n");

return 1; // Exit with an error code

}
Main function continues…

// Initialize the nodes


root->val = 5;
leaf->val = 6;
root->next = leaf;
leaf->next = NULL;
Main function ends….
// Print the values
printf("root=%d, leaf=%d\n", root->val, root->next->val);

// Free allocated memory


free(root);
free(leaf);

return 0;
}
Topics

❏ Identifiers: correct form of writing


❏ Data types modifier
❏ Format specifier
❏ Scope
❏ Storage class
Data Type Modifier
These modifier modifies the storage of the primitive data types.

❏ 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

Eg:- printf(“the value of integer a=%d”, a); scanf(“%d”, &a);


scope
❏ Global
❏ Local
● Global scope means the variable is accessible to all the function in the program.
● Local variable means the lifetime of the variable is confined to the block {} it is
defined in.
● The priority is given to local variables over the global variable with the same name.
● Local variables are initialized with garbage value, while global are initialized with 0.
● Multiple declarations of local variables cause errors unlike global variables.
Storage classes
Void

❏ 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.

The precedence of operators decides with operator will be executed first.

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

{otherwise this block is executed.}


If else if else ladder
If (a>b){printf(“true block”);}

else {printf(“false block”);}

If (a>b){printf(“true block”);}

else if (a>c) {printf(“second if block”);}

else if (a>d) {printf(“third if block”);}

else {printf(“else block”)}


Nested if else
If (a>b) { if (c>d){printf(“inner if if”);} else {printf(“inner if else”);} }

else { if (d>c){printf(“inner else if”);} else {printf(“inner else else”);} }

switch(v)

{ case 1: printf(“case 1”); break;

case 2: printf(“case 2”); break;

default: printf(“case 3”);}


(condition)? When condition is true : when condition is false;

E.g.

(5>3)?printf(“true case”); : printf(“false case”);

(-5)?printf(“true case”); : printf(“false case”);

(0)?printf(“true case”); : printf(“false case”);


Loop: When some statement or a block of code needs to be executed
multiple number of times till a condition is met, then looping statements
are used.

1. For loop
2. Do while
3. while
Conditional Jump
❏ for(initialization; condition; increment/decrement)

{ block }

❏ Do { block } while (condition);

❏ While (condition){block;}
syntax
for(int i=0; i<5; i=i+1)

{ printf(“repetition made =%d”, i);}

do{printf(“executed once always if condition is false”);}while (3>5);

while(4>3){printf(“executed only if condition is true”);}


Unconditional Jump keywords
❏ Break;
❏ Continue;
❏ goto <label>;
❏ return; // return < return_type>
break & continue
for(int i=0; i<10; i++)

printf(“\n i=%d”, i);

if(i==5)

break;

//continue;

printf(“\n again i=%d”,i);

}
goto <label>
void even(int num)
divisible:
{
printf("\n%d is even", num);
if (num % 2 == 0) // return if even
// jump to even //return;

goto divisible; indivisible:


printf("\n%d is odd", num);
int main()
else
{
//return;
// jump to odd int num = 12;
new_label: even(num);
goto indivisible; return 0;
printf("\n%d executed for both",
num); }
}
Array and Pointer
Array is a data structure which stores an ordered list of similar data types at a
contiguous location in memory.

E.g. int ary[<size_of_array>]={1, 2, 3, 4, 5}; //The above is an integer array with


size_of_array =5.

Char c_ary[10]; // declaration of character data type which reserves 10 Bytes in


memory.

Array name is a pointer variable.


Passing an array
int main()
#include<stdio.h> {
void show_array(int* a, int size)
int a[5]={1, 2, 3, 4, 5};
{ int size=sizeof(a)/sizeof(a[0]);
show_array(a, size);
printf(“ %d ”, a[3]);
}
//int size=sizeof(a)/sizeof(a[0]);

}
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.

Syntax: <datatype>* pointer_var; //declaration

<datatype>* pointer_var = & <variable>; // initialization

E.g. int * ptr=&a; //where int a=10

Increasing a’s value by 1: *ptr=*ptr+1


Pointer example
#include<stdio.h>

int main()

int a=10;

printf("\n value of a=%d",a);

int* ptr=&a;

*ptr=*ptr+2;

printf("\n value of a=%d",a);

printf("\n accessing a by ptr=%d",*ptr);

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:

int sum(int a, int b) int main()


{
{
int a=3;
printf(“ task = sum”); int b=4;
int c=sum(a, b); // call to function
return a+b; return a+b;
}
}
Different Function definition
1. If no return type is there then 2. No arguments
void function(arg)
void function(void)
{ //code
{
} //codes
void function(arg) }
{ int function(void)
//code {
return;
//codes
return 0;
} }
Function with arguments and return
<return_type> function(<arguments>)

// 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()

{ {

a=a+1; int a=5;

printf(“a inside function %d”,a); sum(a);

} printf(“a inside calling function %d”, a);

return 0;

}
Arguments Pass by reference
void sum(int* a) int main()

{ {

*a=*a+1; int a=5;

printf(“a inside function %d”, *a); sum(&a);

} printf(“a inside calling function %d”, a);

return 0;

}
Pointer to function: a pointer to a function name
#include<stdio.h> int main(void)
{

void fun() void (*ptr)()=&fun; //initializing function pointer

{ (*ptr)(); //calling the function through function pointer


printf("\n inside function"); return 0;
} }
Nested function
Function with variable arguments
Arguments to main function
String
preprocessor
Memory management
File handling
Accessing Global and local variables
int x = 50;

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.

Else it returns -ve number in case of error.

#include <stdio.h>

int main()
{
char st[] = "CODING";

printf("While printing ");


printf(", the value returned by printf() is : %d",
printf("%s", st));

return 0;
}
Nested function:A nested function is a function defined inside the definition of another function.
int fun()
#include <stdio.h>
{

//auto int view(); //declaration


int main(void)
//view(); //function call {
printf("\n fun"); printf("\n Main");
// defining view() function inside fun() function.
fun();
return 0;
int view() { printf("\n view"); }
}
view(); //call after fun definition if no declaration.

return 1;

}
Variadic function: function which takes variable no. of inputs.

printf(<string>,...)

scanf(<>, …)

are the examples of


variadic function.
It has ellipsis(…) in its
arguments.
Variadic function
int addition(int n, ...){
#include <stdio.h>
va_list args; #include <stdarg.h>
int i, sum = 0;

va_start (args, n); int main(){

printf("Sum = %d ", addition(5, 1, 2, 3, 4,


for (i = 0; i < n; i++){
5));
sum += va_arg(args, int);

//sum += printf("<%d>", va_arg (args, int)); return 0;


} }
va_end (args);

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:-

type function_name (args) {

// function statements

// base condition

// recursion case (recursive call)

}
Recursive function…
#include <stdio.h> int sum(int k) {
int sum(int k);
if (k > 0) {

int main() { return k + sum(k - 1);


int result = sum(10); } else {
printf("%d", result);
return 0;
return 0;
} }
}
Command line arguments: main(int argc, char* argv[])

● 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>

// defining main with arguments


int main(int argc, char* argv[])
{
printf("You have entered %d arguments:\n", argc);

for (int i = 0; i < argc; i++) {


printf("i=%d, %s\n",i, argv[i]);
}
return 0;
}
Switch case range:
A range of value can be provided to “case” to handle the scenario when a similar set of codes
need to be executed for a multiple case values, all in a range.

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:

return 0; printf("%d not in range\n", arr[i]);


break;
}
}
}
Preprocessor Directives (#)
❏ The ‘#’ symbol indicates that whatever statement starts with a ‘#’ will go
to the preprocessor program to get executed.
❏ It works before compilation.
❏ It changes source code to extended source code.
❏ The preprocessor program executes the command written after #.
❏ It is preferred when a common statement needs to be written at many
places in the same program. So, it is written once and implemented
everywhere.
❏ These are not terminated with a semicolon.
Types of ‘#’ preprocessor Directives

1. Macros
2. File inclusion
3. Conditional compilation
4. Miscellaneous directives
Preprocessor Directives (#)

Preprocessor Directives Description

#define Used to define a macro

#undef Used to undefine a macro

Used to include a file in the source code


#include
program

Used to include a section of code if a


#ifdef
certain macro is defined by #define
#if Check for the specified condition

Alternate code that executes when


#else
#if fails

Combines else and if for another


#elif
condition check
Source code and extended source code
#include <stdio.h> #include <stdio.h>

// macro definition

#define LIMIT 5

int main() int main()


{ {
for (int i = 0; i < LIMIT; i++) { for (int i = 0; i < 5; i++) {
printf("%d \n", i); printf("%d \n", i);
} }
return 0; return 0;
} }
Macros
In C, Macros are pieces of code in a program that is given some name. Whenever this
name is encountered by the compiler, the compiler replaces the name with the actual
piece of code. The ‘#define’ directive is used to define a macro.

Syntax:

#define token value

Macros with arguments:-

#define token(arguments) expression


Macros
#include<stdio.h>
#define AND &&
#define OR ||
void main( )
{
int f = 1, x = 4, y = 90 ;
if ( ( f < 5 ) AND ( x <= 20 OR y <= 45 ) )
printf ( "\nYour PC will always work fine..." ) ;
else
printf ( "\nIn front of the maintenance man" ) ;
}
Macros with arguments
#include <stdio.h>
#include<stdio.h>
#define NUM 3.0
#define AND &&
#define EXP(l, b) ((l * b)/NUM) #define ARANGE ( a > 25 AND a < 50 )
int main() void main( )
{ {
double l1 = 12.0, l2 = 5.0, value;
int a = 30 ;
if ( ARANGE )
value = EXP(l1, l2);
printf ( "within range" ) ;
printf("\n NUM=%lf\n", NUM);
else
printf("\n value of expression is: %lf", value); printf ( "out of range" ) ;
return 0; }
}
What’s the output?
#include<stdio.h>
#define SQUARE(n) n * n
void main( )
{
int j ;
j = 64 / SQUARE ( 4 ) ;
printf ( "j = %d", j ) ;
}
Macros or Functions

❏ 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

The meaning of each of these forms is given below:


#include "goto.c" : This command would look for the file goto.c in the
current directory as well as the specified list of directories as mentioned in
the include search path that might have been set up.
#include <goto.c> : This command would look for the file goto.c in the
specified list of directories only.
Inclusion order
❏ Order of Inclusion: The inclusion order in your code determines which headers are
processed first.
❏ File Paths: The use of double quotes ("header.h") will prioritize the current directory
before searching the system directories, while angle brackets (<header.h>) search only in
system directories.
❏ The preprocessor does not inherently prioritize user-defined headers over standard headers;
rather, it processes them based on the order and the inclusion path specified.
Conditional #: is a type of directive that helps to compile a specific portion of the program or to skip the
compilation of some specific part of the program based on some conditions.

#ifdef macro_name

// Code to be executed if macro_name is


defined

1. #if Directive #ifndef macro_name

2. #ifdef Directive
// Code to be executed if macro_name is not
defined

3. #ifndef Directive #if constant_expr

4. #else Directive // Code to be executed if constant_expression


is true

5. #elif Directive #elif another_constant_expr

6. #endif Directive // Code to be excuted if


another_constant_expression is true

#else

// Code to be excuted if none of the above


conditions are true

#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:

1. #undef Directive: undefine a previously defined macro


2. #pragma Directive: This directive is a special purpose directive and is used to turn on or off some features. These types of directives are
compiler-specific, i.e., they vary from compiler to compiler.

Syntax
#pragma directive

Some of the #pragma directives are discussed below:

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.

int main() { // printf("Value of PI: %f\n", PI);

// Example with conditional check


#ifdef PI
// Use the macro printf("PI is still defined\n");
#else
printf("Value of PI: %f\n", PI);
printf("PI is undefined\n");
#endif

// Undefine the macro return 0;


}
#undef PI
Array :
❏ An array is a collection of similar elements.
❏ The first element in the array is numbered 0, so the last element is 1
less than the size of the array.
❏ An array is also known as a subscripted variable.
❏ Before using an array its type and dimension must be declared.
❏ However big an array its elements are always stored in contiguous
memory locations. This is a very important point
❏ which we would discuss in more detail later on.
array initialisation

int num[6] = { 2, 4, 12, 5, 45, 5 } ;

int n[ ] = { 2, 4, 12, 5, 45, 5 } ;

float press[ ] = { 12.3, 34.2 -23.4, -11.3 } ;


Reaching beyond the array size is entirely the programmer’s botheration and not the compiler’s.

Bound checking:-

void main( )

int num[40], i ;

for ( i = 0 ; i <= 100 ; i++ )

num[i] = i ;

}
/* Demonstration of call by reference */
/* Demonstration of call by value */
main( )
main( ) {

{ int i ;

int i ; int marks[ ] = { 55, 65, 75, 56, 78, 78, 90 } ;

int marks[ ] = { 55, 65, 75, 56, 78, 78, 90 } ; for ( i = 0 ; i <= 6 ; i++ )

for ( i = 0 ; i <= 6 ; i++ ) disp ( &marks[i] ) ;

}
display ( marks[i] ) ;
disp ( int *n )
} {

display ( int m ) printf ( "%d ", *n ) ;

{ }

printf ( "%d ", m ) ;

}
void main( ) void show(?)

{ {

int i ; printf(“%d”, ?);

int marks[ ] = { 55, 65, 75, 56, 78, 78, 90 } ; }

for ( i = 0 ; i <= 6 ; i++ )

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.

E.g. <datatype> *<identifier>=&<variable>

int *ptr=&x; where int x=5;


Array as Pointer
In a any array, we can access each element by using two subscripts, where the first subscript represents the
row number and the second subscript represents the column number.

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>

int main(){ void main( )


{
int arr[3][4] = {

{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}
{
};

int (*ptr)[4]; printf ( "\naddress = %u ", &num[i] ) ;


ptr = arr;
printf ( "element = %d %d ", num[i], *( num + i ) ) ;
printf("%p %p %p\n", ptr, ptr + 1, ptr + 2);

printf("%p %p %p\n", *ptr, *(ptr + 1), *(ptr + 2)); printf ( "%d %d", *( i + num ), i[num] ) ;

printf("%d %d %d\n", **ptr, *(*(ptr + 1) + 2), *(*(ptr + 2) + 3)); }


printf("%d %d %d\n", ptr[0][0], ptr[1][2], ptr[2][3]);
}
return 0;}
Pointer as array
int num[ ] = { 24, 34, 12, 44, 56, 17 } ;

This means that all the following notations are same:


num[i]
*( num + i )
*( i + num )
i[num]
Arithmetic operations on pointer
#include <stdio.h>
Not allowed int main()
{
(a) Addition of two pointers int arr[5] = {10, 20, 30, 40, 50};

(b) Multiplication of a pointer with a int *ptr1 = &arr[1]; // Points to 20


constant int *ptr2 = &arr[4]; // Points to 50

// Pointer subtraction
(c) Division of a pointer with a constant int diff = ptr2 - ptr1; // This gives the number of
elements between ptr2 and ptr1

printf("Difference between ptr2 and ptr1: %d\n", diff);

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.

(b) A pointer when incremented always points to an immediately

next location of its type


An array of pointers is useful in a wide range of cases. Some of these applications are listed below:
● It is most commonly used to store multiple strings.
● It is also used to implement LinkedHashMap in C and also in the Chaining technique of collision
resolving in Hashing.
● It is used in sorting algorithms like bucket sort.
● It can be used with any pointer type so it is useful when we have separate declarations of multiple
entities and we want to store them in a single place.
The array of pointers also has its fair share of disadvantages and should be used when the advantages
outweigh the disadvantages. Some of the disadvantages of the array of pointers are:
● Higher Memory Consumption: An array of pointers requires more memory as compared to plain
arrays because of the additional space required to store pointers.
● Complexity: An array of pointers might be complex to use as compared to a simple array.
● Prone to Bugs: As we use pointers, all the bugs associated with pointers come with it so we need
to handle them carefully.

You might also like