Programming With C - Assignment 1
Programming With C - Assignment 1
Documentation
• Consists of the description of the program
• In a C program, single-line comments can be written using two
forward slashes i.e., //, and we can create multi-line comments
using /* */.
Link
• All header files are included in this section.
• The link section provides instruction to the compiler to link the header
files or functions from the system library.
• It helps us in using others' code in our files. A copy of these header
files is inserted into your code before compilation.
Definition
• Includes preprocessor directive, which contains symbolic constants.
• A preprocessor directive in C is any statement that begins with the "#"
symbol.
• The #define is a preprocessor compiler directive used to create
constants. In simple terms, #define basically allows the macro
definition, which allows the use of constants in our code.
Global Declaration
• This section includes all global variables, function declarations, and
static variables.
• The variables declared in this section can be used anywhere in the
program. They're accessible to all the functions of the program.
Hence, they are called global variables.
Main() Function
• For every C program, the execution starts from the main() function. It
is mandatory to include a main() function in every C program.
• It can use global variables, static variables, inbuilt functions, and user-
defined functions.
• The return type of the main() function can be void also not necessarily
int.
Subprograms
• This includes the user-defined functions called in the main() function.
User-defined functions are generally written after the main() function
irrespective of their order.
• When the user-defined function is called from the main() function, the
control of the program shifts to the called function, and when it
encounters a return statement, it returns to the main() function.
Q.2) Write a short note on characteristics of compiler, linker and
preprocessor.
Ans: Compiler
• The language processor that reads the complete source program
written in high-level language as a whole in one go and translates it into
an equivalent program in machine language is called a Compiler
• In a compiler, the source code is translated to object code successfully if
it is free of errors.
• The compiler specifies the errors at the end of the compilation with line
numbers when there are any errors in the source code. The errors must
be removed before the compiler can successfully recompile the source
code again
Linker
• Linker is a program in a system which helps to link object modules of a
program into a single object file.
• It performs the process of linking. Linkers are also called as link editors.
• Linking is a process of collecting and maintaining piece of code and data
into a single file. Linker also links a particular module into system
library.
• It takes object modules from assembler as input and forms an
executable file as output for the loader.
• Linking is performed at both compile time, when the source code is
translated into machine code and load time, when the program is
loaded into memory by the loader. Linking is performed at the last step
in compiling a program.
• Linking is of two types: Static Linking & Dynamic linking
• Static Linking is performed during the compilation of source program.
Linking is performed before execution in static linking. It takes collection
of relocatable object file and command-line arguments and generates a
fully linked object file that can be loaded and run.
• Static linker performs two major tasks:
• Symbol resolution – It associates each symbol reference with exactly
one symbol definition .Every symbol has a predefined task.
• Relocation – It relocates code and data section and modifies the symbol
references to the relocated memory locations.
• The linker copies all library routines used in the program into
executable image. As a result, it requires more memory space.
• As it does not require the presence of library on the system when it is
run, so it is faster and more portable. No failure chance and less error
chance.
• Dynamic linking is performed during the run time.
• This linking is accomplished by placing the name of a shareable library
in the executable image. There are more chances of errors and failures.
• It require less memory space as multiple programs can share a single
copy of the library.
• Here we can perform code sharing. It means if we are using the same
object a number of times in the program, instead of linking the same
object again and again into the library, each module shares information
of the object with other modules having the same object. The shared
library needed in the linking is stored in virtual memory to save RAM.
• In this linking we can also relocate the code for the smooth running of
code but all the code is not relocatable. It fixes the address at run time.
Preprocessor
• As the name suggests, Preprocessors are programs that process our
source code before compilation. There are a number of steps involved
between writing a program and executing a program in C.
• C provides certain language facilities by means of a preprocessor, which
is conceptually a separate first step in compilation.
• The two most frequently used features are #include, to include the
contents of a file during compilation, and #define, to replace a token by
an arbitrary sequence of characters.
• Preprocessor programs provide preprocessor directives that tell the
compiler to preprocess the source code before compiling.
• These preprocessor directives begin with a ‘#’ (hash) symbol. The ‘#’
symbol indicates that whatever statement starts with a ‘#’ will go to the
preprocessor program to get executed.
• There are 4 Main Types of Preprocessor Directives:
1. Macros
2. File Inclusion
3. Conditional Inclusion
4. Other Directives
1. Macros
◦ 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.
◦ Let us now understand the macro definition with the help of a
program:
Input:
#include <stdio.h>
// macro definition
#define LIMIT 5
int main()
{
for (int i = 0; i <
LIMIT; i++) {
printf("%d \n",i);
}
return 0;
}
Output:
0
1
2
3
4
◦ In the above program, when the compiler executes the word LIMIT, it
replaces it with 5. The word ‘LIMIT’ in the macro definition is called a
macro template and ‘5’ is macro expansion.
◦ Note: There is no semi-colon (;) at the end of the macro definition.
Macro definitions do not need a semi-colon to end.
return 0;
}
Output:
◦ We can see from the above program that whenever the compiler
finds AREA(l, b) in the program, it replaces it with the statement (l*b).
◦ Not only this, but the values passed to the macro template AREA(l, b)
will also be replaced in the statement (l*b). Therefore AREA(10, 5) will
be equal to 10*5.
2. File Inclusion
◦ This type of preprocessor directive tells the compiler to include a
file in the source code program.
◦ There are two types of files that can be included by the user in the
program:
1. Header files or Standard files
2. User-defined files
◦ where file_name is the name of the file to be included. The ‘<‘ and
‘>’ brackets tell the compiler to look for the file in the standard
directory.
User-defined files
◦ When a program becomes very large, it is a good practice to divide
it into smaller files and include them whenever needed.
◦ These types of files are user-defined files.
◦ These files can be included as:
#include “filename”
3. Conditional Compilation
◦ Conditional Compilation directives are 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.
◦ This can be done with the help of the two preprocessing
commands ‘ifdef‘ and ‘endif‘.
Syntax:
#ifdef macro_name
Statement1;
Statement2;
Statement3;
.
.
.
StatementN;
#endif
◦ If the macro with the name ‘macro_name‘ is defined, then the block
of statements will execute normally, but if it is not defined, the
compiler will simply skip this block of statements.
4. Other Directives
◦ Apart from the above directives, there are two more directives that
are not commonly used. These are:
▪ #undef Directive
▪ #pragma Directive
#undef Directive:
• The #undef directive is used to undefine an existing macro. This
directive works as:
#undef LIMIT
• Using this statement will undefine the existing macro LIMIT. After this
statement, every “#ifdef LIMIT” statement will evaluate as false.
#pragma Directive
• This directive is a special purpose directive and is used to turn on or
off some features.
• This type of directives are compiler-specific, i.e., they vary from
compiler to compiler.
• Some of the #pragma directives are discussed below:
◦ #pragma warn -rvl: This directive hides those warnings which are
raised when a function that is supposed to return a value does not
return a value.
◦ #pragma warn -par: This directive hides those warnings which are
raised when a function does not use the parameters passed to it.
◦ #pragma warn -rch: This directive hides those warnings which are
raised when a code is unreachable. For example, any code written
after the return statement in a function is unreachable.
Q.3) Explain typecasting.
Ans: Identifiers:
• ldentifiers are names that are given to various program elements, such
as variables, functions and arrays.
• Identifiers consist of letters and digits, in any order, except that the first
character must be a letter.
• Both Upper- and lowercase letters are permitted, though common
usage favors the use of lowercase letters for most types of identifiers.
• Upper- and lowercase letters are not interchangeable (i.e., an uppercase
letter is not equivalent to the corresponding lowercase letter.)
• The underscore character ( _ ) can also be included, and is considered to
be a letter. An underscore is often used in the middle of an identifier. An
identifier may also begin with an underscore, though this is rarely done
in practice.
e.g.
• An identifier can be arbitrarily long. Some implementations of C
recognize only the first eight characters, though most implementations
recognize more (typically, 31 characters).
• Example: The identifiers file-manager and f ile-management are both
grammatically valid. Some compilers may be unable to distinguish
between them, however, because the first eight letters are the same for
each identifier. Therefore, only one of these identifiers should be used
in a single C program.
• As a rule, an identifier should contain enough characters so that its
meaning is readily apparent. On the other hand, an excessive number of
characters should be avoided.
Keywords:
• There are certain reserved words, called keywords, that have standard,
predefined meanings in C. There are only 32 keywords available in C
• These keywords can be used only for their intended purpose; they
cannot be used as programmer-defined identifiers.
• The standard keywords are the keywords are all lowercase. Since
uppercase and lowercase characters are not equivalent, it is possible to
utilize an uppercase keyword as an identifier. Normally, however, this is
not done, as it is considered a poor programming practice.
Data Types:
• C supports several different types of data, each of which may be
represented differently within the computer’s memory.
• Following are the examples of some very common data types used in C
◦ int: As the name suggests, an int variable is used to store an integer
◦ float: It is used to store decimal numbers (numbers with floating
point value) with single precision.
◦ double: It is used to store decimal numbers (numbers with floating
point value) with double precision.
◦ char: The most basic data type in C. It stores a single character and
requires a single byte of memory in almost all compilers
• (The memory requirements for each data type will determine the
permissible range of values for that data type. Note that the memory
requirements for each data type may vary from one C compiler to
another.)
Data Type Memory (bytes) Range Format Specifier
short int 2 -32,768 to 32,767 %hd
unsigned short int 2 0 to 65,535 %hu
unsigned int 4 0 to 4,294,967,295 %u
int 4 -2,147,483,648 to 2,147,483,647 %d
long int 4 -2,147,483,648 to 2,147,483,647 %ld
unsigned long int 4 0 to 4,294,967,295 %lu
long long int 8 -(2^63) to (2^63)-1 %lld
unsigned long long int 8 0 to 18,446,744,073,709,551,615 %llu
signed char 1 -128 to 127 %c
unsigned char 1 0 to 255 %c
float 4 %
double 8 %lf
long double 16 %Lf
Size:
• The basic data types can be augmented by the use of the data type
qualifiers short, long, signed and unsigned.
• Integer quantities can be defined as short int, long int or unsigned int
(these data types are usually written simply as short, long or unsigned,
and are understood to be integers).
• A short int may require less memory than an ordinary int or it may
require the same amount of memory as an ordinary int, but it will never
exceed an ordinary int in word length.
• Similarly, a long int may require the same amount of memory as an
ordinary int or it may require more memory, but it will never be less
than an ordinary int.
• If short int and int both have the same memory requirements (e.g., 2
bytes), then long int will generally have double the requirements (e.g., 4
bytes).
• Or if int and long int both have the same memory requiremements (e.g.,
4 bytes) then short int will generally have half the memory requirements
(e.g., 2 bytes). Remember that the specifics will vary from one C
compiler to another.
• An unsigned int has the same memory requirements as an ordinary int.
• However, in the case of an ordinary int (or a short int or a long int), the
leftmost bit is reserved for the sign.
• With an unsigned int, all of the bits are used to represent the numerical
value.
• Thus, an unsigned int can be approximately twice as large as an
ordinary int (though, of course, negative values are not permitted).
• For example, if an ordinary int can vary from -32,768 to +32,767 (which
is typical for a 2 byte int) , then an unsigned int will be allowed to vary
from 0 to 65,535.
• The unsigned qualifier can also be applied to other qualified ints, e.g.,
unsigned short int or unsigned long int.
• The char type is used to represent individual characters.
• Hence, the char type will generally require only one byte of memory.
• Each char type has an equivalent integer interpretation, however, so
that a char is a really a special kind of short integer
• With most compilers, a char data type will permit a range of values
extending from 0 to 255.
• Some compilers represent the char data type as having a range of
values extending from -128 to +127.
• There may also be unsigned char data (with typical values ranging from
0 to 255), or signed char data (with values ranging from -128 to +127).
• Some compilers permit the qualifier long to be applied to float or to
double, e.g., long float, or long double
• Thus, long float may be equivalent to double.
• Moreover, long double may be equivalent to double , or it may refer to a
separate, “extra-large” double-precision data type requiring more than
two words of memory.