0% found this document useful (0 votes)
56 views46 pages

C Module 1 Notes

The document provides an overview of the C programming language, detailing its history, characteristics as a middle-level and structured language, and its significance in programming. It discusses the evolution of C from earlier languages, its standards, and the features that make it suitable for system-level programming. Additionally, it covers the structure of C programs, the role of compilers and interpreters, and the concept of separate compilation for efficient code management.

Uploaded by

kashishraj1308
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views46 pages

C Module 1 Notes

The document provides an overview of the C programming language, detailing its history, characteristics as a middle-level and structured language, and its significance in programming. It discusses the evolution of C from earlier languages, its standards, and the features that make it suitable for system-level programming. Additionally, it covers the structure of C programs, the role of compilers and interpreters, and the concept of separate compilation for efficient code management.

Uploaded by

kashishraj1308
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

1BEIT105

Module 1

Overview of C

A Brief History of C.
➢ C was invented and first implemented by Dennis Ritchie on a DEC PDP-11 that used the Unix
operating system.
➢ C is the result of a development process that started with an older language called BCPL.
➢ Martin Richards developed BCPL(“Basic Combined Programming Language”), which
influenced a language called B, invented by Ken Thompson.
➢ B led to the development of C in the 1970s.
➢ For many years, the de facto standard for C was the version supplied with the Unix operating
system.
➢ It was first described in The C Programming Language by Brian Kernighan and Dennis Ritchie
➢ In 1983, a committee was established to create an ANSI (American National Standards Institute)
standard that would define the C language.
➢ The standardisation process took six years (much longer than expected).
➢ The ANSI C standard was finally adopted in December 1989, with the first copies becoming
available in early 1990.
➢ The standard was also adopted by ISO (International Standards Organisation), and the resulting
standard was typically referred to as ANSI/ISO Standard C.
➢ In 1995, Amendment 1 to the C standard was adopted, which added several new library functions.
➢ The 1989 standard for C, along with Amendment 1, became a base document for Standard C++,
defining the C subset of C++.
➢ The version of C defined by the 1989 standard is commonly referred to as C89.

➢ work on C continued quietly, leading to a new standard — the 1999 standard for C, usually
referred to as C99. C99 retained nearly all of the features of C89.

➢ The C99 standardization committee focused on two main areas:


o Addition of several numeric libraries.
o Development of innovative new features such as variable-length arrays and the restrict
pointer qualifier.

BIT, Bengaluru-04 1
1BEIT105

C Is a Middle-Level Language

➢ C is called a middle-level language.


This doesn’t mean that C is weaker or harder to use than other high-level languages like
ASIC or Pascal. It also doesn’t mean C is as difficult as low-level languages like assembly
language.
➢ C is called a middle-level language because it combines the features of high-level languages
and the control of assembly language. It gives both ease of programming and hardware-
level control.

➢ C as a middle-level language, allows the programmers to work directly with bits, bytes, and
memory addresses.

➢ C code is also very portable. Portability means that it is easy to adapt software written for
one type of computer or operating system to another type.

➢ All high-level programming languages support the concept of data types. A data type
defines a set of values that a variable can store along with a set of operations that can be
performed on that variable.

➢ Common data types: int (integer), char (character), and float (decimal numbers). C also
allows automatic type conversions.

➢ Although C has several built in data types, it is not a strongly typed language, as are
Pascal and Ada.

➢ C is special in that it allows the direct manipulation of bits, bytes, words, and pointers. This
makes it well suited for system-level programming.

BIT, Bengaluru-04 2
1BEIT105

➢ C has only a small number of keywords (reserved words used by the language). C89 has 32
keywords, and C99 adds 5 more (total 37). In comparison, BASIC has over 100 keywords!
fewer keywords make C simpler and more flexible.

C Is a Structured Language

➢ Structured Language: A structured language helps you organize a program into smaller, clear
parts.C is called a structured language, even though it’s not fully block-structured. It is similar
to other structured languages like Pascal, ALGOL, and Modula-2.
➢ C is Not Fully Block-Structured: In block-structured languages, one function can be declared
inside another function. But in C, we cannot create a function inside another function because
of this C is called as structured, but not fully block-structured.
➢ Compartmentalization: C programming language supports compartmentalization means
dividing a program into small sections (modules). Each section performs one specific task.
This makes programs easy to understand, test, and debug. One way to achieve
compartmentalization is by using subroutines that employ local (temporary) variables.
➢ Functions and Local Variables: The main structural unit in C is the function. A function
performs one specific task. Each function can work independently without affecting others.
This makes C programs modular and reusable. We can use functions to divide the program
into smaller parts. Local variables (declared inside a function) are used only in that function.
This prevents side effects (changes that affect other parts of the program). Using too many
global variables (variables known throughout the entire program) can cause errors or confusion
in large programs.
➢ Features of Structured Languages: Structured languages provide different loops: while, do-
while, for. The use of goto is discouraged (it makes code confusing). Structured languages are
modern and easier to maintain. Old languages are usually non-structured and harder to use.
➢ Code Blocks in C: Another way to structure code is by using blocks — a group of
statements inside curly braces { }.

printf ("Too low, try again.\n");


scanf("%d", &x);

BIT, Bengaluru-04 3
1BEIT105

C is a Programmer's Language

➢ Programming Languages for Non-Programmers


o COBOL and BASIC were designed mainly for non-programmers.
o COBOL: Created to make programs readable by people without deep technical
knowledge.
o Focused on readability, not on speed or programming efficiency.
o BASIC: Designed to allow non-programmers to write simple programs and solve small
problems easily.
➢ The Birth and Purpose of C
o C was developed by programmers for programmers.
o It provides:
▪ Few restrictions (gives programmers more control)
▪ Few complaints (easy to use for practical coding)
▪ Block structure (organizing code using braces {})
▪ Stand-alone functions
▪ Compact set of keywords (only around 32)
o C combines the efficiency of assembly language with the structured approach of Pascal
or Modula-2, making it powerful and practical.

BIT, Bengaluru-04 4
1BEIT105

➢ C vs Assembly Language

Feature Assembly Language C Language


Nature Low-level, close to hardware High-level but efficient
Structure Unstructured (spaghetti code) Structured (blocks, functions)
Ease of Debugging Difficult Easier
Portability Not portable (depends on CPU) Portable (runs on many systems)
Efficiency Very fast Nearly as fast as assembly

➢ Early Use of C
o Initially used for systems programming, such as:
▪ Operating systems
▪ Compilers
▪ Editors
▪ Utilities
o As C became popular, it was used for all types of programming due to:
▪ Efficiency
▪ Portability
▪ Programmer preference
➢ Significance of C
o C remains one of the most influential and foundational programming languages.
o It laid the groundwork for many modern languages like C++, Java, and Python.
o It will always be remembered as:
▪ The foundation of C++, and
▪ A powerful, efficient, and universal language for programmers.

Compilers vs. Interpreters

➢ Program Execution Methods


o A computer program can be executed in two general ways:
▪ Compilation
▪ Interpretation
o Although any language can be compiled or interpreted, most are designed and
optimised for one specific method.

BIT, Bengaluru-04 5
1BEIT105

➢ Compiled vs Interpreted Languages

Language Execution Method Note


C Compiled Optimized for compilation
Java Interpreted (via intermediate bytecode) Needs a runtime interpreter (JVM)
BASIC (old versions) Interpreted Executes line by line

➢ C Language and Compilation


o C was specifically optimised to be compiled.
o Although C interpreters exist (used in debugging or testing), in practice, C
programs are compiled using a C compiler.
o This means when you write C programs, you’ll almost always:
▪ Compile the code into machine (object) code.
▪ Execute the compiled program directly on your computer.
➢ What is an Interpreter?
o Reads and executes the source code line by line.
o Executes each instruction immediately after reading it.
o Requires the source code or intermediate code at runtime.
o Used in languages like:
▪ BASIC (line-by-line execution)
▪ Python
▪ Java (interprets bytecode using JVM)
➢ What is a Compiler?
o Reads the entire program and translates it once into object code (machine code /
binary code).
o Object code = translated binary version that the computer executes directly.
o After compilation:
▪ Source code → becomes machine code.
➢ Difference Between Compiler and Interpreter

Feature Compiler Interpreter


Translates the entire program before
Execution Type Translates and executes line by line
running
Output Object (machine) code No separate object code
Speed Faster (compiled once) Slower (interpreted every time)
Errors Displayed after entire program is checked Shown immediately (line by line)
Example Languages C, C++ Python, Java (JVM), BASIC

BIT, Bengaluru-04 6
1BEIT105

The Form of a C Program

➢ C has a set of reserved words often known as keywords.


➢ All keywords are basically a sequence of characters that have a fixed meaning.
➢ All keywords must be written in lowercase (small) letters.
➢ C language has 32 keywords as listed below


➢ They define the syntax and structure of the C programming language.
➢ Keywords cannot be used as variable names, function names, or identifiers.
➢ C89 (ANSI C) Standard
o Defined 32 keywords that form the core of the C language.
o These are also part of the C subset of C++.
➢ C99 Standard
o Added 5 new keywords to enhance functionality.

o
_Bool _Complex _Imaginary inline restrict o
➢ Total C keywords after C99 = 37
➢ Case Sensitivity
o C treats uppercase and lowercase letters as different.
▪ else → valid keyword
▪ ELSE → invalid
o Therefore, be careful while writing C code — keywords must be in lowercase.
➢ Structure of a C Program
o Every C program consists of one or more functions.
o The main( ) function is essential — it is the starting point of execution.
o Execution begins with:

int main()
{
// statements
return 0;
}

o main() is not a keyword, but it should be treated like one

BIT, Bengaluru-04 7
1BEIT105

o Do not use main as a variable name or function name elsewhere.

Concept Details
Total Keywords (C89) 32
Keywords Added in C99 5
Total Keywords (C99) 37
Case Sensitivity Yes (else ≠ ELSE)
Nonstandard Keywords Compiler-specific (e.g., asm, far, pascal)
Essential Function main() — entry point of program
Program Structure Header → main() → function calls

The Library and Linking

➢ C keywords do not handle:


o Input/Output (I/O) operations
o High-level mathematical computations
o Character or string handling
➢ To perform these operations, C uses function
➢ C Standard Library
o Every C compiler comes with a standard library — a collection of predefined
functions for common tasks.
o These functions make it easier to perform:
▪ Input and output (printf(), scanf())
▪ Mathematical operations (sqrt(), pow())
▪ String handling (strlen(), strcpy())
▪ File operations (fopen(), fclose())
▪ Memory management (malloc(), free())
➢ Calling Library Functions
o When a call to library function is done, the compiler recognizes its name.
o The actual machine code for the function already exists in the library file.
o After compilation, your code and library functions are combined by another program
called the linker.
➢ Linking Process
o Linking is the process of combining:
o Compiled program (object file)
o With the precompiled standard library code
o The linker ensures that your program can use library functions by connecting
function calls in your program to their definitions in the library.

BIT, Bengaluru-04 8
1BEIT105

o Some compilers include a built-in linker, while others rely on the linker from the
operating system.
o During linking, the linker assigns actual memory addresses based on where the
program will run.
o This process ensures that the same library code can be used by many programs
without rewriting it.
o We can also create your own library by collecting functions that you use frequently.
Example:
If we write several programs that all use a factorial() function,
we can store it in a library and reuse it in multiple programs.

#include <stdio.h>
#include <math.h>
int main()
{
double num = 16.0;
double result = sqrt(num); // sqrt() is a standard library function
printf("Square root of %f = %f", num, result);
return 0;
}

o #include <math.h> — tells the compiler to use the math library.


o sqrt(num)  library function is recognized by the compiler.
o The linker attaches the math library code during the linking stage.
o The program runs successfully using both your code and library code.
➢ General form of C program is given below

C program is composed of processor command, global declarative section and one or more function
blocks. The preprocessor directives are instructions that indicate how the program has to be compiled.
include is one the preprocessor command through which the compiler include the needed information from
the specified header file to the particular code.
In Global variables or constants can be declared in the global declaration part.
C program contains one or more functions. Functions are defined as a group of statements that are executed
together. Function can be either system defined or user defined functions. All functions are divided into
two parts:
Local declaration section: Data will be visible only within that function. Stated in other terms, the life-
time of the data will be only till the function ends.
Statement section: Contains the code that manipulates the data to perform a specified task.
main() function is a system defined function from which the C program execution begins.

BIT, Bengaluru-04 9
1BEIT105

Every C program must include one main function, where as user defined functions can be of any number
which can be included based on the tasks to be performed.

Separate Compilation

➢ In small programs, all code is usually written in one source file (e.g., program.c).
➢ As programs grow larger, compiling the entire program every time becomes slow and
inefficient.
➢ To solve this, C allows separate compilation — meaning the program can be split across
multiple source files, and each file can be compiled separately.
➢ Each source file (e.g., main.c, file1.c, file2.c) is compiled individually into an object file (.obj
OR .o).
➢ After all files are compiled, the linker combines:
▪ All object files
▪ Any required library routines to form one final executable file.
➢ Advantages of Separate Compilation

Advantage Explanation
Faster recompilation Only changed files need recompilation. Saves time on large projects.
Team collaboration Multiple programmers can work on different files simultaneously.
Better organization Code can be divided into logical modules, making maintenance easier.

BIT, Bengaluru-04 10
1BEIT105

Advantage Explanation
Efficient debugging Errors can be traced in smaller, individual files.

Compiling a C Program

➢ Creating an executable program in C involves three key steps:


o Step 1: Create the Program
▪ Write the source code using a text editor.
▪ Save it with the .c extension (example: hello.c).
▪ Note:
• Compilers only accept plain text files.
• Files created in word processors (like MS Word) contain control
codes and cannot be compiled.
o Step 2: Compile the Program
▪ The compiler checks your source code for:
• Syntax errors
• Semantic errors
▪ If no errors are found, it generates an object file (.o or .obj), which contains
machine-readable code.
o Step 3: Link the Program
▪ The linker combines:
• The object file(s)
• Required library functions (like printf(), scanf(), etc.)
▪ Produces the final executable file (e.g., hello.exe or a.out).

C's Memory Map

BIT, Bengaluru-04 11
1BEIT105

When a C program is compiled and executed, it uses four logically distinct regions of memory.
Each region serves a specific purpose during program execution.

Region Description / Purpose


- Contains the compiled executable code of the program.
1. Program Code (Text This is the section that holds all your functions and instructions.
Segment) It is usually read-only, to prevent accidental modification of code during
execution.
- Stores all global and static variables.
These variables exist throughout the program’s execution.
2. Global Variables (Data
This area is further divided into:
Segment)
Initialized data (variables with assigned values)
Uninitialized data (BSS) (variables declared but not initialized)
- A region of free memory used for dynamic memory allocation.
- Memory here is allocated and freed manually using: malloc(),
3. Heap
calloc(), realloc(), and free().
- The heap grows upward (toward higher memory addresses).
- Used during program execution for:
Function call management
Local variables
4. Stack Function arguments
Return addresses
CPU state information
- The stack grows downward (toward lower memory addresses).

The terms to remind


• Source code the text of a program that a user can read, commonly thought of as the program. The source
code is input into the C compiler.
• Object code Translation of the source code of a program into machine code, which the computer can read
and execute directly. Object code is the input to the linker.
• Linker A program that links separately compiled modules into one program. It also combines the
functions in the Standard C library with the code that you wrote. The output of the linker is an executable
program.
• Library The file containing the standard functions that your program can use. These functions include
all I/O operations as well as other useful routines.
• Compile time The time during which your program is being compiled.
• Run time The time during which your program is executing.

BIT, Bengaluru-04 12
1BEIT105

The Basic Data Types

➢ Basic Data Types in C89


o C89 defines five fundamental data types:

Data Type Keyword Description


Character char Used to store a single character (like ‘A’, ‘b’, etc.). Size is always 1 byte.
Used to store whole numbers (positive or negative). Size depends on the
Integer int
system.
Floating-point float Used to store decimal (real) numbers.
Double floating-
double Used to store larger decimal numbers with more precision.
point
Valueless void Used when a function returns no value or for generic pointers.

➢ Size and Range


o The size and range of these data types depend on the compiler and processor.
o Example:
▪ In a 16-bit system (like DOS), int is 2 bytes (16 bits).
▪ In a 32-bit system (like Windows 95/98/NT/2000), int is 4 bytes (32 bits).
➢ Additional Data Types in C99
o C99 introduced three new data types:

Data Type Keyword Description


Boolean _Bool Stores only 0 (false) or 1 (true).
Complex _Complex Used for complex number calculations (real + imaginary parts).
Imaginary _Imaginary Used for purely imaginary numbers.

➢ Floating-Point Representation
o The exact format of float and double depends on how the compiler implements them.
o Minimum range for floating-point numbers: 1E–37 to 1E+37.
o float and double differ in precision (number of digits they can represent accurately).
➢ Character Data
o char usually represents ASCII characters.
o Values outside the ASCII range may behave differently depending on the compiler.
➢ Void Type
o void is used for:

BIT, Bengaluru-04 13
1BEIT105

▪ Declaring functions that do not return any value.


Example: void display();
▪ Declaring generic pointers that can point to any data type.
Example: void *ptr;

Modifying the Basic Types

➢ Except for the type void, all basic data types in C can have modifiers.
A type modifier changes the meaning of a base type to better fit a specific need.
➢ The available modifiers are:
o signed
o unsigned
o long
o short
➢ The base type int can be modified by:
→ signed, unsigned, short, long
➢ The base type char can be modified by:
→ signed, unsigned
➢ The base type double can be modified by:
→ long
➢ In C99, long long is also allowed for larger integer values.

Type Typical Size (bits) Minimal Range


char 8 –127 to 127
unsigned char 8 0 to 255
signed char 8 –127 to 127
int 16 or 32 –32,767 to 32,767
unsigned int 16 or 32 0 to 65,535
signed int 16 or 32 Same as int
short int 16 –32,767 to 32,767
unsigned short int 16 0 to 65,535
signed short int 16 Same as short int
long int 32 –2,147,483,647 to 2,147,483,647
long long int (C99) 64 –(2⁶³ – 1) to 2⁶³ – 1
signed long int 32 Same as long int
unsigned long int 32 0 to 4,294,967,295
unsigned long long int (C99) 64 0 to 2⁶⁴ – 1
float 32 1E–37 to 1E+37 (≈ 6 digits precision)

BIT, Bengaluru-04 14
1BEIT105

Type Typical Size (bits) Minimal Range


double 64 1E–37 to 1E+37 (≈ 10 digits precision)
long double 80 1E–37 to 1E+37 (≈ 10 digits precision)

➢ Using signed with integers is allowed but redundant, since integers are signed by default.
➢ The keyword signed is mainly used with char when the compiler defaults to unsigned char.
➢ Difference Between Signed and Unsigned
➢ Signed integers use the high-order bit (leftmost bit) as a sign flag:
o 0 → positive number
o 1 → negative number
➢ Most systems represent negative numbers using two’s complement:
o In two’s complement, all bits are reversed (except the sign bit), then 1 is added.
➢ Example:
o +32,767 in binary:
0 11111111 11111111
o If the high-order bit becomes 1, it represents –1 in signed form.
o But if declared as unsigned, the same bit pattern equals 65,535.
➢ If a modifier is written without a base type, int is assumed.

Specifier Same As
signed signed int
unsigned unsigned int
long long int
short short int

Identifier Names

➢ In C, the names of variables, functions, labels, and various other user-defined items are called
identifiers.
➢ The length of these identifiers can vary from one to several characters.
➢ The first character must be a letter or an underscore, and subsequent characters must be
either letters, digits, or underscores.
➢ Here are some correct and incorrect identifier names

BIT, Bengaluru-04 15
1BEIT105

➢ Types of Identifiers
o C defines two kinds of identifiers:

Type Description Example


External Used in the external link process (shared between files). main, global
Identifier These include function names and global variables. variables
Internal Used only within a single source file or function (not Local variables
Identifier shared externally). These include local variables. inside a function

➢ Significant Characters (C89 vs C99 vs C++)

Standard External Identifier Internal Identifier


At least first 6 characters are At least first 31 characters are
C89
significant significant
At least first 31 characters are At least first 63 characters are
C99
significant significant
At least first 1,024 characters are
C++
significant

➢ In C, uppercase and lowercase letters are treated as different.


o Example:
count, Count, and COUNT are three different identifiers.
➢ The rules to write an identifier are as follows:

1. It must contain only alphabets (A to Z, a to z), numbers (0 to 9) and underscore ( _ ).


2. It must start with alphabet or underscore but not numeric character.
3. It should not contain any special symbols apart from underscore.
4. It should not have any space.
5. Keywords cannot be used as identifiers.
6. Identifiers are case sensitive.
7. Maximum length of an identifier is 31 characters.
Examples of valid identifiers include: roll_number, marks, name, emp_number,
HRA, DA, dept_code, DeptCode, RollNo, EMP_NO

BIT, Bengaluru-04 16
1BEIT105

Examples of invalid identifiers include: 23_student, Xmarks, @name, #emp_number,


basic.pay, - HRA, (DA), &dept_code, auto
Variables:
A variable is defined as a meaningful name given to a data storage location in computer memory.
Variable actually refer to address of the memory where the data is stored.
C language supports two basic kinds of variables—numeric and character.
a) Numeric Variables: Numeric variables can be used to store cither integer values or floating point
values. It can also be associated with modifiers like short, long, signed, unsigned.
b) Character Variables: Character variables are just single characters enclosed within single quotes,
These characters could be any character from the ASCII character set—letters (‗a‘, ‗A‘), numerals
(‗2‘), or special characters (‗&‘).
Declaration of variables:
• Each variable to be used in the program must be declared.
• To declare a variable, specify the data type (specifies what kind of value a variable will store) of the
variable followed by its name.
• In C, variable declaration always ends with a semicolon, for example:
int emp_num;
float salary;
char grade;
double balance_amount;
unsigned short int acc_no;
Initialization of variables:
• While declaring variables, we can also initialize them with some value. For example,
int emp_num = 7;
float salary = 2156.35;
char grade = ‗A‘;
double balance_amount = 100000000;
• The initializer applies only to the variable defined immediately before it, Therefore, the statement
“int count, flag = 1;” initializes the variable flag and not count.
• When variables are declared but not initialized they usually contain garbage values.

Local Variable

➢ In C language, a variable declared within a function or a block of code is called a local


variable. Local variables are frequently used to temporarily store data in a defined scope
where they can be accessed and manipulated.
➢ They are stored in the memory stack, Once the function or block of code in which the local
variable is declared finishes executing. The variable is automatically removed from the
memory.
➢ Characteristics of Local Variable in C

BIT, Bengaluru-04 17
1BEIT105

o Function Scoped Local Variables

➢ The local variable is only accessible inside the function or block of code in which it is
declared. A variable's scope specifies where it can be used and accessible within a program .

The value of localVar is 10

In the above code, When the function is called from the main function, it prints the value of localVar as 10. If
you try to access it outside of its scope( in this example main function )will result in a compilation “error:
'localVar' undeclared”. This is referred to as being out of scope.

o Block Scoped Local Variables

➢ Variables have a specified region or context in which they are valid and can be
manipulated. After a variable goes beyond its scope, it can no longer be accessed or
modified.

BIT, Bengaluru-04 18
1BEIT105

x was declared in the block: 25


x outside the block: 15
Outside of the block, the program defines the variable "x" with a value of 15. Another variable, 'x,' is
defined inside the block with a value of 25. The variable "x" inside the block is printed with a value of
25. We are unable to access the block-defined variable "x" outside of the block.

Advantages of Using Local Variables

• Local variables are only usable within the scope in which they are declared, It avoids naming
conflicts and maintains code organization.
• Local variables are useful for storing temporary data that is only required within a particular
function or block of code.
• Local variables provide more security we can wrap the variables in a code block or function to
limit access of those variables to that scope only.
• Local variables can make the code easy to read.

BIT, Bengaluru-04 19
1BEIT105

Global Variables in C
• The Declaration of a global variable is very similar to that of a local variable. The only difference
is that the global variable is declared outside any function.
• The initialization of these variables occurs automatically to 0 during the time of declaration. Also,
we generally write the global variables before the main() function.

Advantages of Global Variable


• Global variables can be accessed by all the functions present in the program.
• Only a one-time declaration is required.
• Global variables are very useful if all the functions are accessing the same data.

Disadvantages of Global Variable


• The value of a global variable can be changed accidentally as it can be used by any function in the
program.
• If we use a large number of global variables, then there is a high chance of error generation in the
program.

Outut : 25

BIT, Bengaluru-04 20
1BEIT105

❖ The Four C Scopes


Standard C defines four scopes that determine the visibility of an identifier. They are
summarized here:
Scope Meaning
File scope • Starts at the beginning of the file (also called a translation unit) and
ends with the end of the file.
• Refers only to those identifiers that are declared outside of all
functions.
• File scope identifiers are visible throughout the entire file.
• Global variables have file scope
Example:
#include<stdio.h>
int i; // file scope of i begins
void main(void)
{
int a=2;
i = a+2;
printf(“Value of i is %d”, i);
}
O/P:
Value of i is 4
Block scope • Begins with the opening ‘{‘ of a block and ends with its associated
closing ‘}’ [Block includes functions, if-else, loops etc]
• Variables with block scope are local to their block.
• Function parameters will have its scope in a function's block.
Example:
#include <stdio.h>
int main() { //main function block begins
int a = 10; //a variable has block scope throughout main function
printf ("The value of a in main function block: %d\n", a);
{ //Inner Block begins
int a = 20; //a variable has block scope only in inner block
printf ("The value of a in inner block: %d\n", a);
} //Inner Block ends
printf ("The value of a in main function block: %d\n", a);

return 0;
} //main function block ends
O/P:
The value of a in main function block: 10
The value of a in inner block: 20
The value of a in main function block: 10
Function • Identifiers declared in a function prototype; visible within the
prototype scope prototype
Example:
#include<stdio.h>
int add(int a, int b); // 'a' and 'b' have prototype scope

BIT, Bengaluru-04 21
1BEIT105

int add(int x, int y) { // Names can be different


return x + y;
}
void main()
{
printf(“Addition of 5 and 2 is %d”,add(5,2));
}
O/P:
Addition of 5 and 2 is 7
Function scope • Begins with the opening { of a function and ends with its closing }.
• Function scope applies only to labels.
• A label is used as the target of a goto statement, and that label must
be within the same function as the goto.
Example:
#include <stdio.h>
void display() {
goto l1; // You can jump to label ‘l1’ even though it is written later
printf("This line will not be printed.\n");
l1: // l1 is a Label in function display which has function scope
printf("This is inside the same function.\n");
}
int main() {
display();
return 0;
}
O/P:
This is inside the same function
❖ Type Qualifiers
C defines type qualifiers that control how variables may be accessed or modified. C defines
two of these qualifiers: const and volatile.
Syntax: The type qualifiers must precede the datatype names that they qualify.
type_qualifier data_type variable_name;
➢ const
• Variables of type const are called as constant variables.
• Constants are identifiers whose values do not change.
• Compiler knows the value of constant at compile time.
• The compiler is free to place variables of this type into read-only memory (ROM).
• Constants are used to define the values that shouldn’t be changed throughout the program
even by mistake.
Example:
#include <stdio.h>
int main() {
const int a = 10; // Defining a constant variable
int b = 9;
printf("value of a is %d", a);

BIT, Bengaluru-04 22
1BEIT105

printf("value of b is %d", b);


a = 11; // Trying to modify the constant variable
b = 12;
printf("value of a is %d", a);
printf("value of b is %d", b);
return 0;
}
In the above program, we created a constant variable ‘a’ whose value is not expected to be
changed throughout the whole program. But when we try to change the value, the compiler
throws an error.
O/P:
10:11: error: assignment of read-only variable 'a'
10 | a = 11; // Trying to modify the constant variable
• The const qualifier can be used to prevent the object pointed to by an argument to a function
from being modified by that function.
• Constant variables can be used to verify that your program does not modify a variable.
• Remember, a variable of type const can be modified by something outside your program.
➢ volatile
The modifier volatile tells the compiler that a variable's value may be changed in ways not
explicitly specified by the program.
Example:
• Sometimes a variable in a program can be changed by something outside the program’s
control — for example, the operating system might update a global variable with the current
time. In such cases, the value of the variable can change even though the program never
assigns a new value to it.
• Also, some compilers change the order of evaluation of an expression during the
compilation process.
• The volatile modifier prevents these external changes happening on the variable.
You can use const and volatile together.
For example, if 0x30 is assumed to be the value of a port that is changed by external conditions
only, the following declaration would prevent any possibility of accidental side effects
const volatile char *port = (const volatile char *) 0x30;
❖ Storage Class Specifiers
C supports four storage class specifiers:
1. extern
2. static
3. register
4. auto
These specifiers tell the compiler how to store the subsequent variable. The general syntax of
a variable declaration using storage class specifiers is as shown here:
storage_specifier data_type var_name;

BIT, Bengaluru-04 23
1BEIT105

C defines three categories of linkage: external, internal, and none.


• In general, functions and global variables have external linkage. This means they are
available to all files that constitute a program.
• File scope objects declared as static internal linkage. These are known only within the file
in which they are declared.
1. extern:
• Extern storage class simply tells us that the variable is defined elsewhere and not within
the same block where it is used.
• Basically, the value is assigned to it in a different block and this can be
overwritten/changed in a different block as well.
• By preceding a variable name with the extern specifier, you can declare a variable
without defining it, thus you can refer to a variable defined in another part of the
program.
Example:
#include <stdio.h>
int main(void)
{
extern int first, last; /* use global vars */
printf("%d %d", first, last); //first and last takes the value of global variables
return 0;
}
/* global definition of first and last */
int first = 10, last = 20;
Output:
10 20
In the above program extern declaration tells the compiler that first and last are declared
elsewhere in the program, hence program can be compiled without error even though first
and last are used prior to their definition.
• If the compiler finds a variable that isn’t declared in the current block, it looks for it in
the outer blocks. If it still can’t find it, it checks the global variables. Once it finds a
match, it uses that variable.
• The extern keyword is used when you want to refer to a variable that’s defined later in
the file or in another file.
• extern allows you to declare a variable without defining it, if the variable is initialized
with value while declaration, the extern declaration becomes a definition.
• In multi-file C programs, extern is used to share global variables across files. The best
way is to define all global variables in one file and use extern declarations for them in
the others.

BIT, Bengaluru-04 24
1BEIT105

• In File 2, the global variables from File 1 are declared with extern, telling the compiler
they’re defined elsewhere. This prevents creating new storage, and the linker later
connects all references to these external variables.
2. static variables:
• Variables declared as static are permanent variables within their own function or file.
• Static variables keep their values between function calls but are only accessible within
their own function or file.
• They’re useful for creating reusable functions and libraries, and their effect differs for
local and global variables.
➢ static local variables
• A static local variable is stored permanently like a global variable but it will be visible
only within the block it declared, whereas global variable is visible throughout the
program.
• static local variable helps create stand-alone functions that retains its value between
function calls without using global variables.
• Using static variables prevents unwanted side effects from global variables.
• Commonly used in routines like number generators or counters that need to remember
past values.
Example:
Ex1: Ex2:
#include <stdio.h> #include <stdio.h>
void numberSeries() { int num = 0; //global varaiable
static int num = 0;//static local variable void numberSeries() {
num++; num++;
printf("Next number: %d\n", num); printf("Next number: %d\n", num);
} }

int main() { int main() {


numberSeries(); numberSeries();
numberSeries(); numberSeries();
numberSeries(); num++; //global variable incremented
return 0; numberSeries();
} return 0;
}

BIT, Bengaluru-04 25
1BEIT105

Output: Output:
Next number: 1 Next number: 1
Next number: 2 Next number: 2
Next number: 3 Next number: 4

• The function numberSeries() uses a • The program uses a global variable


static local variable num, which num, which is accessible and
retains its value between function modifiable by all functions — both
calls — meaning num is initialized main() and numberSeries() share the
only once and not reset each time same num.
when the function call happens (i.e., • Each call to numberSeries() (and the
function numberSeries() remembers manual increment in main())
the previous value of num). increases num by 1.
• The static local variable num is • The value becomes 3 after num++ in
accessible only by numberSeries() main(), then numberSeries()
function and not by main() function. increments it again to 4.
• If num were declared as a normal (non-static) local variable(i.e., int num = 0; ) in
Ex1, it would be reinitialized to 0 every time when the function call happens. Hence,
each call would start from 0 and increment once. Hence Output would be:
Next number: 1
Next number: 1
Next number: 1
➢ static Global Variables
• Applying the specifier static to a global variable instructs the compiler to create a
global variable known only to the file in which it is declared (i.e., a static global
variable has internal linkage).
• In a program with multiple source files, a global static variable ensures that the
variable is accessible only within the program file where it is declared, not from
other program files.
Example:
#include <stdio.h>
static int counter = 0; // Global static variable – visible only within file1.c
void incrementCounter() {
counter++;
printf("Counter value = %d\n", counter);
}
int main() {
incrementCounter(); // Works on counter in file1.c
incrementCounter();
return 0;
}
Output:
Counter value = 1
Counter value = 2

BIT, Bengaluru-04 26
1BEIT105

Note: The names of local static variables are known only to the block of code in which
they are declared; the names of global static variables are known only to the file in
which they reside.
3. register Variables
• The register specifier tells the compiler to store a variable in the CPU register instead
of normal memory (RAM). This makes access to the variable faster, especially in loops
or frequently used operations.
• In Standard C register specifier can be used with any data type.
• Since register variables are stored in the CPU, reading and updating them takes less
time compared to normal variables in memory.
• You cannot use the address-of operator (&) with register variables because CPU
registers are not usually addressable.
• register specifier can be applied only to local variables and to the formal parameters in
a function. Global register variables are not allowed.
Example:
#include <stdio.h>
void main() {
register int i; // register variable (local)
int sum = 0;

for (i = 1; i <= 5; i++) {


sum += i; // i is accessed quickly from CPU register
}
printf("Sum = %d\n", sum);
}
Output:
Sum = 15
In this program, the variable i is declared as a register variable inside the main function,
so the compiler may store it in a CPU register for faster access — this makes the loop run
more efficiently when repeatedly updating and using i to calculate the sum.
4. auto variables:
• auto variables are local to the function or block in which they are declared. They are
created when the function starts and destroyed when it ends.
• auto variables are known as automatic variable, which are declared with auto keyword
specifier.
• Every local variable in C is auto by default, even if you don’t write the keyword auto.
Example: int x = 5; is automatically an auto variable.
• Auto variables don’t have a default value. If not initialized, they contain garbage
(random) values.
Example:
#include <stdio.h>
void show() {
auto int num = 10; // 'auto' is optional
printf("Value of num = %d\n", num); }
BIT, Bengaluru-04 27
1BEIT105

int main() {
show();
return 0;
}
Output:
Value of num = 10
In this program num is an auto variable, local to show(). It exists only while show()
executes and is destroyed when the function ends.

❖ Variable Initialization:
• Assigning a value to a variable as you declare them by placing an equal sign and a
constant after the variable name is called variable initialization.
• The general form of initialization is
datatype variable_name = constant;
Example:
char ch = 'a'; //initialize ch variable with ‘a’ value
int first = 0; //initialize first variable with 0 value
double balance = 123.23; //initialize balance variable with 123.23 value
❖ Constants:
• Constants are identifiers whose values do not change. A constant is an explicit data value
specified by the programmer. Compiler knows the value of constant at compile time.
• Constants are used to define the values that shouldn’t be changed throughout the program
even by mistake.
• Types of Constants:
a) Integer Constant: A constant of integer type consists of a sequence of digits.
For example: 1, 34, 567, 8907 are valid integer constants.
• A literal integer like 1234 is of type int by default.
• For a Long integer constant the literal is succeeded with either ‘L’ or ‘l’ (like
1234567L).
• Similarly, an unsigned int literal is written with a ‘U’ or ‘u’ suffix (e.g. 12U).
1234L, 12341, 1234U, 1234u, 1234LU, 1234u) are all valid integer constants.
• By default an integer is expressed in decimal notation, Decimal integers consist
of a set of digits, 0 through 9, preceded by an optional - or + sign.
Examples of decimal integer constants include: 123, -123, +123, and 0.

b) Real/Floating Point Constants: A floating point constant consists of an integer part, a


decimal part, a fractional part, and an exponent field containing an e or E (e means
exponent) followed by an integer.
Examples of floating point numbers are: 0,02, -0.23, 123.456, +0.34 123, 0.9, -0.7, 40.8
etc.
• A literal like 0.07 is treated as of type double by default To make it a float
type literal, you must specify it using suffix F or f (Note that suffix L is for
long double.)

BIT, Bengaluru-04 28
1BEIT105

Some valid floating point literals are: 0.02F, 0.34f, 3.141592654L,


0.002146, 2.14E-3.
• A floating point number may also be expressed in terms of scientific
notation. Mantissa can be integer or floating point number and exponent is
an integer with an optional plus or minus sign.
Examples are: 0.5e2, 14E-2, 1.2e+3, 2.1E-3, -5.6e-2.
Note: scientific notation is used to express numbers that are either very
small or very large, For example: 120000000 = 1.2E8 and -0.000000025 =
-2,.5E-8
Some examples of constants
Data Type Constant Examples
int 1, 123, 21000, -234
long int 35000L, –34L
unsigned int 10000U, 987u, 40000U
float 123.23F, 4.34e–3f
double 123.23, 1.0, –0.9876324
long double 1001.2L

c) Octal and hexadecimal constants.


• An number preceded by a zero (0) is an octal constant, Octal integers consist of a
set of digits, 0 through 7.
Examples of octal integers: 012, 0, 01234.
• integer constant is expressed in hexadecimal notation if it is preceded with 0x or 0x.
Hexadecimal numbers contain digits from 0-9 and letters A through F, which
represent numbers 10 through 15.
Examples of hexadecimal integers are 0X12, 0x7F, 0xABCD, 0X1A38.
Example:
int hex = 0x80; //128 in decimal
int oct = 012; //10 in decimal
d) Character Constants: A character constant consists of a single character enclosed in
single quotes. For example, ‘a’ and ‘@’ are character constants. In computers,
characters are stored using machine's character set using ASCII (American Standard
Code for Information Interchange) codes.
• C defines both multibyte characters, which consist of one or more bytes, and wide
characters (which are usually 16 bits long).
• To specify a multibyte character, enclose the characters within single quotes, for
example, 'xy'.
• To specify a wide character constant, precede the character with an L.
For example:
wchar_t wc; // wchar_t, wide character type is defined in the <stddef.h> header
file
wc = L'A'; // wc is assigned the wide-character constant equivalent of A

BIT, Bengaluru-04 29
1BEIT105

Printable characters: All characters are printable except backslash(\) character .

The above table shows the decimal and hexadecimal ASCII value of each character.
e) String Constants: A string constant is a sequence of characters enclosed in double
quotes.
• When a string constant is encountered in a C program, the compiler records the
address of the first character and appends a null character (“\0”) to the string to
mark the end of the string.
• Thus, length of a string constant is equal to number of characters in the string plus
+ (for the null character), Therefore, the length of string literal "hello" is 6.
Example: “HELLO”
H E L L O \0
0 1 2 3 4 5

BIT, Bengaluru-04 30
1BEIT105

f) Backslash Character Constants: Backslash characters are also known as non


printable characters. These are also referred to as escape sequences.
List of backslash characters code.

Example:
#include <stdio.h>
int main(void)
{
printf("\n\tThis is a test."); //prints newline, tab space and “This is a test.” characters.
return 0;
}
Output:

This is a test.
❖ Declaring Constants:
• To declare a constant, precede the normal variable declaration with const keyword
and assign it a value.
For example, “const float pi = 3.14;”
Note: The const keyword specifies that the value of pi cannot change.
• Another way to define constant is to use the pre-processor command define using ‘#’.
Example: “#define pi 3.14159”
• Rules that need to be applied to a #define statement which defines a constant:
Rule 1: No blank spaces are permitted between the # symbol and define keyword.
Rule 2: Blank space must be used between define and constant name and between
constant name and constant value.
Rule 3: #define is a pre-processor compiler directive and not a statement. Therefore, it
does not end with a semi-colon.

BIT, Bengaluru-04 31
1BEIT105

❖ Operators in C
An operator is a symbol that tells the compiler to perform specific mathematical, logical
or relational operations to be performed. The different operators supported in ‘C’ are:
1. Assignment Operator
2. Arithmetic Operator
3. Relational Operators
4. Logical Operators
5. Bitwise Operators
6. Ternary (?, :) Operator
7. Comma Operator
8. Compile-Time Operator sizeof
9. & and * Pointer Operators
10. Dot (.) and Arrow (–>) Operators
11. [ ] and ( ) Operators
a) Assignment Operator:
• Assignment operator ‘=’ can be used within any valid expression.
The general form of the assignment operator is
variable_name = expression;

lvalue rvalue
• lvalue is an object. If that object can occur on the left side of an assignment
statement, it is called a modifiable lvalue (means ''variable.").
• The term rvalue refers to expressions on the right side of an assignment and
simply means the value of an expression
➢ Type Conversion in Assignments:
• When variables of one type are mixed with variables of another type, a type
conversion will occur.
• In an assignment statement, the type conversion rule is easy: The value of the
right side (expression side) of the assignment is converted to the type of the left
side (target variable), as illustrated here:
#include<stdio.h>
void main()
{
int x;
char ch;
float f;
ch = x; //integer value is converted to character
x = f; //float value is converted to integer
f = ch; //character value is converted to float
f = x; //integer value is converted to float
}
▪ In ch=x, the left high-order bits of the integer variable x are lopped off,
leaving ch with the lower 8 bits.
▪ In x=f, x will receive the nonfractional part of f.
▪ In f = ch, f will convert the 8-bit integer value(of character) stored in ch to the
same value in the floating-point format.
▪ In f=x, convert an integer value into floating-point format.

BIT, Bengaluru-04 32
1BEIT105

➢ Multiple Assignments
We can assign many variables the same value by using multiple assignments in a
single statement.
For example, below program fragment assigns x, y, and z the value 0
x = y = z = 0;
➢ Compound Assignments
Compound assignment operators exist for all the binary operators (those that require
two operands). Compound assignment is also sometimes referred to as shorthand
assignment.
In general, statements like
variable1 = variable1 operator expression
can be rewritten as
variable1 operator = expression
Example 1:
x = x+10; ➔ can be rewritten as x+=10;
Example 2:
x = x-100; ➔ can be rewritten as x-=100;

b) Arithmetic Operator
• The operators that are used to perform arithmetic operations such as
addition, subtraction, multiplication, division, modulus, increment and
decrement operations are called Arithmetic operators.
• These operators perform operations on two operands and hence they are binary
operators.
The different arithmetic operators are:
Operator Name Result Syntax Example (b=5, c=2)
+ Addition Sum a=b+c a=7
- Subtraction / Difference a=b-c a=3
unary minus
* Multiplication Product a=b*c a = 10
/ Division Quotient a=b/c a=2
% Modulus Remainder a=b%c a=1
++ Increment Value a++ a=2
incremented by 1
-- Decrement Value a-- a=1
decremented by 1
• The modulus operator(%) finds the remainder of an integer division. This
operator can be applied only to the integer operands and cannot be used for
float or double operands.
• While performing modulo division, the sign of the result is always the sign
of first operand(the dividend).
16%3=1 16%-3=1 -16%3=-1 -16%-3=-1
• All the arithmetic operators bind from left to right. The multiplication,
division and modulus operators have higher precedence over addition and
subtraction.
BIT, Bengaluru-04 33
1BEIT105

➢ Unary Minus (-) Operator:


When a operand is preceded by a minus sign, the unary operator negates its value.
For example: If a number is a Positive then it becomes negative when preceded
with a unary minus operator.
int a, b=10;
a= -(b);
then a holds -10

➢ The Increment and Decrement Operators


1. Increment (+ +): ++ is an increment operator.
• As the name indicates, increment means increase, i.e. this operator is used to
increase the value of a variable by 1.
• The increment operator is classified into 2 categories:
▪ Post increment Ex: b++
As the name indicates, post-increment means first use the value of variable
and then increase the value of variable by 1.
▪ Pre increment Ex: ++b
As the name indicates, pre-increment means first increase the value of
variable by 1 and then use the updated value of variable.
For Example:1) if x is 10, then
z = x++; sets z to 10 and increase the value of x by 1
2) if x is 10, then
z = ++x; increase the value of x by 1 and assign the update
value to z, so z will be 11.
2. Decrement operator (- -): - - is a decrement operator.
• As the name indicates, decrement means decrease, i.e. this operator is used to
decrease the value of a variable by 1.
For Example: if b=5; => then, b-- or --b becomes 4
• Similar to increment operator, the decrement operator are classified into 2 types:
▪ Post decrement (b--)
First value of the operand is used for evaluation then, it is decremented
(subtracted) by 1.
Example: if x is 10, then
z = x--; sets z to 10, then decreases the value of x by 1(x=9)
▪ Pre decrement (--b)
First value of the operand is decremented(subtracted) by 1 then, it is used
for evaluation.
Example: if x is 10, then
z = --x; decrease the value of x by 1 and assign the update
value to z, so z will be 9

BIT, Bengaluru-04 34
1BEIT105

➢ Precedence of arithmetic operator

• Operators on the same level of precedence are evaluated by the compiler from
left to right.
• parentheses to alter the order of evaluation. Parentheses force an operation,
or set of operations, to have a higher level of precedence.
c) Relational Operators
• We often compare two quantities and depending on their relation take
certain decisions. For example, we might compare the age of two persons,
or the price of two items, and so on. These comparisons can be done with
the help of relational operators.
• These operators are also known as comparison operator.
• The output will be either 0 (False) or 1 (True).
For example
a>b //If a is greater than b, then a>b returns 1 else a>b returns 0.
• The expression containing a relational operator is returned as a relational
expression.
• The 2 operands may be constants, variables or expressions.
• C supports two kinds of equality operators to compare their operands for strict
equality or inequality. They are equal to(= =) and not equal to(!=) operators.
• The equal to (= =) operator returns True if both the operands have same
value, else it returns False.
• The not equal to (!=) operator returns True if both the operands have
different value else it returns False.
• Relational operators are as listed below
Operator Name Syntax Example (b=5, c=2)
< Lesser than a=b<c a = 0 (False)
> Greater than a=b>c a = 1 (True)
<= Lesser than or Equal to a = b <= c a = 0 (False)
>= Greater than or Equal to a = b >= c a = 1 (True)
== Equal to a=b==c a = 0 (False)
!= Not equal to a = b != c a = 1 (True)

A program to illustrate the use of relational operators is as given below,


#include<stdio.h>
void main()
{
int x=10, y=20;

BIT, Bengaluru-04 35
1BEIT105

printf(“%d < %d = %d \n”, x, y, x<y);


printf(“%d <= %d = %d \n”, x, y, x<=y);
printf(“%d > %d = %d \n”, x, y, x>y);
printf(“%d >= %d = %d \n”, x, y, x>=y);
printf(“%d == %d = %d \n”, x, y, x==y);
printf(“%d != %d = %d \n”, x, y, x!=y);
}
Output:
10 < 20 = 1
10 <= 20 = 1
10 > 20 = 0
10 >= 20 = 0
10 == 20 = 0
10 != 20 = 1
d) Logical Operators
• These are used to test more than one condition and make decision. The different
logical operators are: NOT(!), AND(&&), OR(||)
• Logical operators return 0 for false and 1 for true.
Note: In C, true is any value other than zero. False is zero
• Logical NOT (!) The output is true when input is false and vice versa. It
accepts only one input.
Input Output
X !X
0 1
1 0
• Logical AND (&&) The output is true only if both inputs are true. It accepts two or
moreinputs.
Input Output
X Y X && Y
0 0 0
0 1 0
1 0 0
1 1 1
• Logical OR (| |) The output is true only if any of its input is true. It accepts two
or more inputs.
Input Output
X Y X || Y
0 0 0
0 1 1
1 0 1
1 1 1
For example: int a=10, b;
b = !a; => result b = 0 (since a = 10 and !a = 0)
Let x=8, y=0; (x > 9) && (y + 1) => results in 0
(x > 9) || (y + 1) => results in 1

BIT, Bengaluru-04 36
1BEIT105

• We can combine several operations into one expression, as shown here:


10>5 && !(10<9) | | 3<=4 ➔ the result is true (1).
Example program for XOR gate implementation:
An XOR (Exclusive OR) gate outputs 1 only when its input are different, when its
inputs are the same XOR gate outputs 0.

Input Output
X Y X (xor) Y
0 0 0
0 1 1
1 0 1
1 1 0
Program
#include<stdio.h>
void main()
{
int a, b, xor;
a=0, b=1;
xor = (a || b)&& !(a && b);
printf("%d xor %d = %d\n",a,b,xor);
a=1, b=1;
xor = (a || b)&& !(a && b);
printf("%d xor %d = %d\n",a,b,xor);
}
Output:
0 xor 1 = 1
0 xor 0 = 0
• Both the relational and logical operators are lower in precedence than the
arithmetic operators
• Precedence of the relational and logical operators:

Example:
1. 10 > 1+12 → Result is False(0) because ‘+’ operator have higher precedence
than ‘>’ operator.
2. !0 && 0 | | 0 → Evaluated to False(0)
3. !(0 && 0) | | 0 → Evaluated to True(1), because parentheses have higher
precedence level.
e) Bitwise Operators
• These works on bits and performs bit by bit operations.
• The different types of bitwise operators are:
i. Bitwise NOT (~) → One's complement
ii. Bitwise AND (&)

BIT, Bengaluru-04 37
1BEIT105

iii. Bitwise OR (|)


iv. Bitwise XOR (^)-> Output is True when odd number of 1’s are present.
v. Bitwise left shift (<<)
vi. Bitwise right shift (>>)

i. Bitwise AND (&) : The truth table is same as shown in logical AND operation. The
bitwise AND operator compares each bit of its first operand with the corresponding bit
of its second operand. If both bits are 1,the corresponding bit in result is 1 otherwise 0.
Example:
Binary value of 10 → 1010 (8 bit representation is ‘00001010’)
Binary value of 20 → 10100 (8 bit representation is ‘00010100’)
int a=10, b=20,c; a&b→ 00001010
c = a & b; → c = 0 00010100
___________________

00000000

ii. Bitwise OR ( | ): The bitwise OR operator compares each bit of its first operand with
the corresponding bit of its second operand. If both bits are 0, the corresponding bit in
result is 0 otherwise 1.
Example:
Binary value of 10 → 1010 (8 bit representation is ‘00001010’)
Binary value of 20 → 10100 (8 bit representation is ‘00010100’)
int a=10, b=20, c; a | b→ 00001010
c = a | b; → c = 30 00010100
___________________

00011110

iii. Bitwise XOR (^): The bitwise XOR operator compares each bit of its first operand
with the corresponding bit of its second operand. If one of the bit is 1, the corresponding
result bit is 1 otherwise 0.
Example:
Binary value of 10 → 1010 (8 bit representation is ‘00001010’)
Binary value of 20 → 10100 (8 bit representation is ‘00010100’)
int a=10, b=20, c; a ^ b→ 00001010
c = a ^ b; → c = 30 00010100
___________________

00011110

iv. Bitwise NOT (~): It is a unary operator, performs logical negation on each bit of
the operand i.e., one’s complement of each bit.
Example:
Binary value of 10 → 1010 (8 bit representation is ‘00001010’)
int a=10, c; ~a → 00001010
c = ~a; → c = -11 ___________________

11110101

BIT, Bengaluru-04 38
1BEIT105

v. Bitwise Left Shift (<<) : Shift specified number of bits to left side.
General form: variable << number of bit positions
Note: one left shift multiplies the number by 2.
Example:

X= 10 0 0 0 0 1 0 1 0
X<<2 → X=40 0 0 1 0 1 0 0 0

vi. Bitwise Right Shift (>>) : Shift specified number of bits to right side.
General form: variable >> number of bit positions
Note: one right shift divides the number by 2.
Example:

X= 10 0 0 0 0 1 0 1 0
X>>2 → X=2 0 0 0 0 0 0 1 0

Note: As bits are shifted off from one end, zeroes are brought in the other end. The bits
shifted off are lost.

f) Ternary (?, :) Operator


• C contains a powerful and convenient operator that replaces certain statements of
the if-then-else form. The ternary operator ? takes
• The general form: It takes three arguments.
Expression1 ? Expression2 : Expression3
Where, Expression1 = Condition
▪ Working: Expression1 is evaluated. If it is true, Expression2 is evaluated
and becomes the value of the expression. If Expression1 is false,
Expression3 is evaluated, and its value becomes the value of the expression.
Example:
x = 10;
if(x>9) { //checks for condition if x>9
y = 100; // if condition is true then 100 is assigned to y
}
else {
y = 200; // if condition is false then 200 is assigned to y
}
Result → y=100

BIT, Bengaluru-04 39
1BEIT105

The above if-else statement can be rewritten with ternary operator


x = 10;
y = x>9 ? 100 : 200; //exp1→(x>9), exp2→y=100, exp3→y=200
In the above statement if condition (x>9) is evaluated true then y is assigned
with 100, else if condition (x>9) is evaluated false then y is assigned with 200.
Result → y=100
Example 2:
large = (4 > 2) ? 4: 2 // the condition 4>2 holds True hence the value 4 is assigned
to variable large so,
large = 4
g) Comma Operator
• It takes two operands It can be used as operator in expression and as separator
in declaring variables.
• The left side of the comma operator is always evaluated as void. This means that
the expression on the right side becomes the value of the total comma-separated
expression.
• It has lowest precedence.
Example 1:
x = (y=3, y+1); // first assigns y the value 3 and then assigns x the value 4
Example 2:
int a=2, b=3, x=0;
x = (++a , b+=a ); → x is assigned with 6
Note: The parentheses are necessary because the comma operator has a lower
precedence than the assignment operator.

h) Compile-Time Operator sizeof


• sizeof is a unary compile-time operator that returns the length, in bytes, of the
variable or parenthesized type specifier that it precedes.
• It is used to determine the amount of memory space the variable/data type will
take.
• It is a unary operator it can be applied to all the data types.
• To compute the size of a datatype, you must enclose the datatype name in
parentheses. This is not necessary to compute the size using variable names.
Example:
double f;
int a;
printf("%d ", sizeof f); // prints 8 since size of float datatype is 8 bytes
printf("%d", sizeof(int)); // prints 4 since size of int datatype is 4 bytes
printf("%d", sizeof(a)); // prints 4 since size of variable is integer type
i) & and * Pointer Operators
• A pointer is the memory address of an object.
• A pointer variable is a variable that is specifically declared to hold a pointer
(memory address) to an object of its specified type.
• The first pointer operator is &, a unary operator that returns the memory address
of its operand (i.e., & as meaning ''the address of").

BIT, Bengaluru-04 40
1BEIT105

Example:
Assume that the variable count is at memory location 2000. And count has a
value of 100.
int count=100, *m; // m is an integer pointer
m = &count; // m receives the address of variable count.
Result → m = 2000.
• The second pointer operator is *, a unary operator that returns the value of the
object located at the address that follows it (i.e., * as meaning "at address").
Example:
int count=100, *m, q; // m is an integer pointer
m = &count; // m receives the address of variable count.
q = *m // q has the value stored at location 2000
Result → q = 100
Example program:
#include <stdio.h>
int main(void)
{
int target, source;
int *m;
source = 10;
m = &source;
target = *m;
printf("%d", target);
return 0;
}
Output:
10
j) Dot (.) and Arrow (–>) Operators
• The . (dot) and the –> (arrow) operators access individual elements of structures
and unions.
• Structures and unions are compound data types that may be referenced under a
single name.
• The dot operator is used when working with a structure or union directly.
• The arrow operator is used with a pointer to a structure or union.
Example:
struct employee {
char name[80];
int age;
float wage;
} emp;
struct employee *p = &emp; // address of emp into p

o Dot (.) is used to assign the value 123.23 to the wage member of structure
variable emp:
emp.wage = 123.23;
o Arrow (->) is used to assign the value 123.23 to the wage member of
structure variable emp using pointer to emp (i.e., p):
p->wage = 123.23;

BIT, Bengaluru-04 41
1BEIT105

k) [ ] and ( ) Operators
• Parentheses are operators that increase the precedence of the operations inside
them.
Example:
int result = 5 + 3 * 2; // Evaluates to 11
int result = (5 + 3) * 2; // Evaluates to 16 since () increases the precedence
• Square brackets perform array indexing. Given an array, the expression within
square brackets provides an index into that array.
Example:
#include<stdio.h>
char s[80];
void main( ) {
s[3] = 'X'; // stores value 'X' to the fourth element of array s.
printf(''%c", s[3]); //prints the value stored in fourth element of array s
}
Output:
X
❖ Expressions
• Operators, constants, functions, and variables are the constituents of expressions.
An expression in C is any valid combination of these elements
• Precedence: The order in which operators are evaluated is based on the priority
value.
• Associativity: It is the parsing direction used to evaluate an expression. It can be
left to right orright to left.
• Evaluation of expressions: Expressions are evaluated using an assignment
statement.
Example: variable = expression
sum = a + b
❖ Precedence Summary:
Below table lists the precedence of all operators defined by C.
Note: All operators, except the unary operators and ?, associate from left to right. The
unary operators (*, &, –) and ? associate from right to left.

Precedence Operator Description Associativity


() Parentheses (function call)
[] Array Subscript (Square Brackets)
1 Left-to-Right
. Dot Operator
-> Structure Pointer Operator
++ , -- Postfix increment, decrement
++ / -- Prefix increment, decrement
+/- Unary plus, minus
!,~ Logical NOT, Bitwise complement
2
(type) Cast Operator Right-to-Left
* Dereference Operator
& Addressof Operator
sizeof Determine size in bytes

BIT, Bengaluru-04 42
1BEIT105

3 *, /,% Multiplication, division, modulus Left-to-Right


4 +,- Addition, subtraction Left-to-Right
5 << , >> Bitwise shift left, Bitwise shift right Left-to-Right
< , <= Relational less than, less than or equal to
6 Left-to-Right
> , >= Relational greater than, greater than or equal to
7 == , != Relational is equal to, is not equal to Left-to-Right
8 & Bitwise AND Left-to-Right
9 ^ Bitwise exclusive OR Left-to-Right
10 | Bitwise inclusive OR Left-to-Right
11 && Logical AND Left-to-Right
12 || Logical OR Left-to-Right
13 ?: Ternary conditional Right-to-Left
= Assignment
+= , -= Addition, subtraction assignment
*= , /= Multiplication, division assignment
14 Right-to-Left
%= , &= Modulus, bitwise AND assignment
^= , |= Bitwise exclusive, inclusive OR assignment
<<=, >>= Bitwise shift left, right assignment
15 , comma (expression separator) Left-to-Right

❖ TYPE CONVERSION

• In C language, the programmer can instruct the compiler to convert the data from one
data type to another data type. Sometimes, the compiler itself will convert the data from
1 data type to another data type this process of converting the data from one data type
to another data type is called as type conversion.
• It occurs when mixed data occurs.
• Type conversion is performed by a compiler.
• In type conversion, the destination data type can’t be smaller than the source data type.
• Generally, takes place when in an expression more than one data type is present. In
such conditions type conversion (type promotion) takes place to avoid loss of data.

There are two types of Conversion:


i. Automatic Type Conversion (Implicit) Widening Conversion
• C can evaluate the expressions if and only if the data types of two operands are same.
• So, When constants and variables of different types are mixed in an expression, they are
all converted to the same type. In this case C compiler converts the data type with a lower
rank to the data type with higher rank.
• This process of conversion of data from lower rank to higher rank automatically by the C
compiler is known as implicit conversion
• Below figure shows the hierarchy of implicit type conversion

BIT, Bengaluru-04 43
1BEIT105

Type conversion algorithm


IF an operand is a long double
THEN the second is converted to long double
ELSE IF an operand is a double
THEN the second is converted to double
ELSE IF an operand is a float
THEN the second is converted to float
ELSE IF an operand is an unsigned long
THEN the second is converted to unsigned long
ELSE IF an operand is long
THEN the second is converted to long
ELSE IF an operand is unsigned int
THEN the second is converted to unsigned int

Figure 2.2 shows the type conversion example: First, the character ch is converted to an
integer. Then the outcome of ch/i is converted to a double because f*d is double. The
outcome of f+i is float, because f is a float. The final result is double

BIT, Bengaluru-04 44
1BEIT105

Advantages and Disadvantages of Implicit Conversion:


Advantages:
➢ Compiler does conversion from lower rank to higher rank. So,
programmer need not worry about the conversion procedure or the
syntax.
Disadvantages:
➢ Conversion from higher rank to lower rank is not performed
automatically by the compiler

ii. Casts/Type Casting /Manual Type Conversion (Explicit) Narrow Conversion

• The programmer can instruct the compiler to change the type of the operand from one data
type to another data type.
• This forcible conversion from one data type to another data type is called as explicit type
conversion or casts
• In typing casting, a data type is converted into another data type by the programmer using
the casting operator during the program design
• The general form of a cast is:
(type) expression
Where,
• type is a valid data type.
• expression can be an operand such as variables or a constant.
Example:
i = (int)8.999 //8.999 is truncated to 8 and is stored in i. So, i=8
i =(int)5.99 / (int)2.4 //5.99 is truncated to 5 and 2.4 is truncated to 2 which results in 5/2=2
So, i=2
(float) x/2 // expression x/2 to evaluate to type float

BIT, Bengaluru-04 45
1BEIT105

Example program:
#include <stdio.h>
int main() {
int a = 9, b = 4;
float x = 3.5;
double result;
// Expression combining int, float, and double with explicit conversions
result = (double)a / b + (int)x * 2.0 + (float)(a + b) / 3;
printf("Result = %.2lf\n", result);
return 0;
}
Output:
Result = 12.58
In this program, explicit type conversions are used to control how different data types (int,
float, and double) interact in a complex expression, ensuring accurate arithmetic results and
preventing unwanted integer division.

❖ Expressions:
Examples of Expressions Using the Precedence Chart
If we have the following variable declarations:
int a = 0, b = 1, c = –1;
float x = 2.5, y = 0.0;
then,
(a) a && b = 0 (h) (x > y) + !a || c++
(b) a < b && c < b = 1 = ((x > y) + (!a)) || (c++)
(c) b + c || ! a = (1 + 1) || 0
= ( b + c) || (!a) =1
= 0 ||1 (i) a += b - = c *= 10
=1 a = a + (b = (b – (c = c * 10))
(d) x * 5 && 5 || ( b / c) a = a + (b = 1 – (-10))
= ((x * 5) && 5) || (b / c) a = a + (b = 11)
= (12.5 && 5) || (1/–1) a = 0 + 11
=1 a = 11
(e) a <= 10 && x >= 1 && b (j) –a * (5 + b) / 2 – c++ * b
= ((a <= 10) && (x >= 1)) && b = --a * 6 / 2 – c++ * b
= (1 && 1) && 1 = -1 * 6 / 2 – (-1) * 1
=1 = -1 * 3 – (-1)
(f) !x || !c || b + c = -2
= ((!x) || (!c)) || (b + c) (k) a * b * c
= (0 || 0) || 0 = (a * b) * c
=0 =0
(g) x * y < a + b || c (l) e = 3 * 4 + 5 * 6 → e = 42
= ((x * y) < (a + b)) || c (m) e = 3 * (4 + 5) * 6 → e = 162
= (0 < 1) || –1 → 1 (n) e = 3 * (4 % 5) / 2 → e = 6
(o) e = 3 * 4 % (5 / 2) → e = 0

BIT, Bengaluru-04 46

You might also like