Académique Documents
Professionnel Documents
Culture Documents
MODULE 1
Topic Page Number
Introduction to C Language
C Program structure
Preprocessor directives
Header files
Data Types
Introduction to C Language
C is a general-purpose high level language that was originally developed by Dennis
Ritchie for the UNIX operating system.
UNIX stands for Uniplexed Information and Computing System, is a popular operating
system developed at Bell Labs in the early 1970s. The name was intended as a pun (joke)
on an earlier system called “Multics” (Multiplexed Information and Computing Service).
C was first implemented on the Digital Equipment Corporation PDP-11 computer in
1972.
The UNIX operating system and virtually all UNIX applications are written in the C
language. C has now become a widely used professional language for various reasons.
o Easy to learn
o Structured language
o It produces efficient programs.
o It can handle low-level activities.
o It can be compiled on a variety of computers.
Facts about C
o C was invented to write an operating system called UNIX.
o C is a successor of B language which was introduced around 1970.
o The language was formalized in 1988 by the American National Standard
Institute (ANSI).
o By 1973 UNIX Operating system almost totally written in C.
o Today C is the most widely used System Programming Language.
o Most of the state of the art software have been implemented using C
o It is a small language, with just 32 keywords.
o It provides “high-level” structured programming constructs such as statement
grouping, decision making and looping, as well as “low level” capabilities such as
the ability to manipulate bytes and addresses.
C achieves its compact size by providing basic services within the language proper,
foregoing many of the higher-level features commonly built-in to other languages.
For example C provides no operations to deal directly with composite objects such as
lists or arrays.
There are no memory management facilities apart from static definition and stack
allocation of local variables.
There are no input/output facilities, such as for printing to the screen or writing to a
file.
C Program File: All the C programs are written into text files with extension ".c" for
example hello.c. You can use "vi" editor to write your C program into a file.
C Compilers: When you write any program in C language, to run that program you
need to compile that program using a C Compiler which converts your program into a
language understandable by a computer. This is called machine language (i.e. binary
format). The compiler gcc comes along with all flavors of UNIX and Linux. Knowing
how compilation works can be very helpful both when writing code and debugging.
Figure 1.1
1. Preprocessing:
The first stage of compilation is called preprocessing. C Preprocessor is just a text
substitution tool. In this stage, lines starting with a # character are interpreted by the
preprocessor as preprocessor commands. These commands form a simple macro
language with its own syntax and semantics. This language is used to reduce repetition in
source code by providing functionality to inline files, define macros and to conditionally
omit code. Before interpreting commands, the preprocessor does some initial processing.
This includes joining continued lines (lines ending with a \) and stripping comments. To
print the result of the preprocessing stage, pass the -E option to gcc:
gcc -E hello_world.c
Given the “Hello, World!” example (Figure 1.2,the preprocessor will produce the
contents of the stdio.h header file joined with the contents of the hello_world.c file,
stripped free from its leading comment: The result is shown in Figure 1.2
Figure 1.2
2. Compilation
The second stage of compilation is confusingly enough called compilation. In this stage,
the preprocessed code is translated to assembly instructions specific to the target
processor architecture. These form an intermediate human readable language.
The existence of this step allows for C code to contain inline assembly instructions and
for different assemblers to be used. Some compilers also support the use of an integrated
assembler, in which the compilation stage generates machine code directly, avoiding the
overhead of generating the intermediate assembly instructions and invoking the assembler.
To save the result of the compilation stage, pass the -S option to cc:
cc -S hello_world.c
This will create a file named hello_world.s, containing the generated assembly
instructions. The output similar to Figure 1.3 will be generated:
Figure 1.3
3. Assembly
During the assembly stage, an assembler is used to translate the assembly instructions to
machine code, or object code. The output consists of actual instructions to be run by the
target processor.To save the result of the assembly stage, pass the -c option to gcc:
gcc -c hello_world.c
Running the above command will create a file named hello_world.o, containing the object
code of the program. The contents of this file are in a binary format and can be inspected
using hexdump or od by running either one of the following commands:
hexdump hello_world.o
od -c hello_world.o
4. Linking
The object code generated in the assembly stage is composed of machine instructions that the
processor understands but some pieces of the program are out of order or missing. To produce an
executable program, the existing pieces have to be rearranged and the missing ones filled in. This
process is called linking.
The linker will arrange the pieces of object code so that functions in some pieces can
successfully call functions in other pieces. It will also add pieces containing the instructions for
library functions used by the program. In the case of the “Hello, World!” program, the linker will
add the object code for the puts function.
The result of this stage is the final executable program. When run without options, gcc
will name this file a.out. To name the file something else, pass the -o option to gcc:
cc -o hello_world hello_world.c
NB: After successful compilation to execute the program, run the executable file (a.out or
hello_world).
The Figure 1.4 shows the steps involved in the process of building the C program starting from
the preprocessing until the loading of the executable image into the memory for program
running.
Figure 1.4
C - Program Structure
A C program basically has the following form:
Preprocessor Commands
Functions
Variables
Statements & Expressions
Comments
Figure 1.5
Preprocessor Commands: These commands tell the compiler to do preprocessing before doing
actual compilation. Like #include <stdio.h> is a preprocessor command which tells a C compiler
to include stdio.h file before going to actual compilation.
Functions: are main building blocks of any C Program. Every C Program will have one or more
functions and there is one mandatory function which is called main() function. This function is
prefixed with keyword int which means this function returns an integer value when it exits. This
integer value is returned using return statement.
The C Programming language provides a set of built-in functions. In the above example printf()
is a C built-in function which is used to print anything on the screen. You can write your own
functions (user defined functions) and use them in the program.
Variables: are used to hold numbers, strings and complex data for manipulation.
Statements & Expressions: Expressions combine variables and constants to create new values.
Statements are expressions, assignments, function calls, or control flow statements which make
up C programs.
Comments: are used to give additional useful information inside a C Program. All the comments
will be put inside /*...*/ as given in the example above. A comment can span through multiple
lines.
Preprocessor Directives
The C Preprocessor is not part of the compiler, but is a separate step in the compilation process.
In simplistic terms, a C Preprocessor is just a text substitution tool.
replace instances of MAX_ARRAY_LENGTH with 20. Use #define for constants to increase readability.
Example 2: The first line of the following statements tells the preprocessor to get stdio.h from System
Libraries and add the text to this file. The next line tells the preprocessor to get myheader.h from the
local directory and add the text to the file.
#include<stdio.h>
#include “myheader.h”
Example 3: The preprocessor uses the following lines to undefine FILE_SIZE and define it for 42.
#undef FILE_SIZE
#define FILE_SIZE 42
Example 4: The preprocessor statements to “define MESSAGE only if MESSAGE isn't defined
already”
#ifndef MESSAGE
#define MESSAGE “You Wish!”
#endif
Example 5: The preprocessor statements to “do the following statements if DEBUG is defined”
#ifdef DEBUG
/* Your debugging statements here */
#endif
Example 6: To ensure that the macro TEST is always defined, irrespective of whether it has
been defined in the header file (DEFINE.H) or not.
#include “DEFINE.H”
#ifndef TEST
#define TEST 1
#endif
NB: For more about “The Preprocessor”, Refer Chapter 14 of Programming in C (4th Edition)
by Balagurusamy.
Header Files
A header file is a file with extension .h which contains C function declarations and macro
definitions to be shared between several source files. There are two types of header files: the files
that the programmer writes and the files that come with your compiler.
You request to use a header file in your program by including it with the C preprocessing
directive #include, like the inclusion of stdio.h header file, which comes along with your
compiler. Including a header file is equal to copying the content of the header file but we do not
do it because it will be error-prone and it is not a good idea to copy the content of a header file in
the source files, especially if we have multiple source files in a program. A simple practice in C
programs is that we keep all the constants, macros, system wide global variables, and function
prototypes in the header files and include that header file wherever it is required.
Syntax of include
Both the user and the system header files are included using the preprocessing directive
#include. It has the following two forms
#include <file>
This form is used for system header files. It searches for a file named 'file' in a standard list of
system directories. You can prepend directories to this list with the -I option while compiling
your source code.
#include "file"
This form is used for header files of your own program. It searches for a file named 'file' in the
directory containing the current file. You can prepend directories to this list with the -I option
while compiling your source code.
Operation of include
The #include directive works by directing the C preprocessor to scan the specified file as
input before continuing with the rest of the current source file. The output from the preprocessor
contains the output already generated, followed by the output resulting from the included file,
followed by the output that comes from the text after the #include directive. For example, if you
have a header file header.h as follows
char *test (void);
Let the main program given below called program.c that uses the header file,
int x;
#include "header.h"
the compiler will see the same token stream as it would if program.c read.
int x;
Computed Includes
Sometimes it is necessary to select one of the several different header files to be included into
your program. For instance, they might specify configuration parameters to be used on different
sorts of operating systems. You could do this with a series of conditionals as follows –
#if SYSTEM_1
#include "system_1.h"
#elif SYSTEM_2
#include "system_2.h"
#elif SYSTEM_3
...
#endif
But as it grows, it becomes tedious; instead the preprocessor offers the ability to use a macro for
the header name. This is called a computed include.
Identifiers
Identifiers (i.e., variable names function names, etc) are made up of letters and digits, and
are case-sensitive. The first character of an identifier must be a letter or underscore (_). The C
language has 32 keywords which are reserved and may not be used as identifiers (eg: int, while,
for, etc). Furthermore, it is a good idea to avoid redefining identifiers used by the C standard
library (such as standard function names printf, scanf, etc.). By convention, Use lowercase for
variable names and uppercase for symbolic constants. Local variable names should be short and
external names should be longer and more descriptive. Variable names can begin with an
underscore (_), but this should be avoided as such names, by convention, are reserved for library
implementations.
Types
C is a typed language. Each variable is given a specific data type which defines what values it
can represent, how its data is stored in memory, and what operations can be performed on
it. By forcing the programmer to explicitly define a type for all variables and interfaces, the type
system enables the compiler to catch type-mismatch errors, thereby preventing a significant
source of bugs.
There are three basic types in the C language: characters, integer numbers and floating-point
numbers. The numerical types come in several of sizes. Table 1.1 shows a list of C types and
their typical sizes, although the sizes may vary from platform to platform.
Nearly all current machines represent an int with at least 32-bits and many now use 64-bits. The
size of an int generally represents the natural word-size of a machine; the native size with which
the CPU handles instructions and data. With regard to size, the standard merely states that a
short int be at least 16-bits, a long int at least 32-bit, and short int ≤ int ≤ long int.
The standard says nothing about the size of floating-point numbers except that
float ≤ double ≤ long double.
C Data Types
Type Size
char usually 8-bits (1 byte)
int usually the natural word size for a machine or OS (e.g.,
16, 32, 64 bits)
short int at least 16-bits
long int at least 32-bits
float(Single precision floating point) usually 32-bits
Double (Double precision floating usually 64-bits
point)
long double usually at least 64-bits
Table 1.1: C Data Types
A program to print the range of values for certain data types is shown below. The parameters
such as INT_MIN can be found in standard headers limits.h and float.h.
Note: The size of a type in number of characters (which is usually equivalent to number of
bytes) can be found using the sizeof operator. This operator is not a function, although it often
appears like one, but a keyword. It returns an unsigned integer of type size_t, which is defined
in header-file stddef.h.
#include<stdio.h>
int main()
{
printf("void\tchar\tshort\tint\tlong\tfloat\tdouble\n");
Note: Integer types are signed by default (example: writing short is equivalent to writing signed
short int). However, plain char’s are signed or unsigned by default is machine dependent.
The qualifier const means that the variable to which it refers cannot be changed.
const int num= 5;
num = 6; /* Error: will not compile */
The qualifier volatile refers to variables whose value may change in a manner beyond the normal
control of the program. This is useful for, say, multi-threaded programming or interfacing to
hardware. The volatile qualifier is not directly relevant to standard-conforming C programs.
Finally, there is a type called void, which specifies a “no value” type. It is used as an argument
for functions that have no arguments, and as a return type for functions that return no value.
Constants
Constants refer to fixed values that the program may not alter during its execution. These fixed
values are also called literals. Constants can have different types and representations. Constants
can be of any of the basic data types like an integer constant, a floating constant, a character
constant, or a string literal. There are enumeration constants as well.
First, an integer constant 1234 is of type int. A constant of type long int is suffixed by an L,
1234L; (integer constants too big for int are implicitly taken as long). An unsigned int is
suffixed by a U, 1234U, and UL specifies unsigned long. Integer constants may also be
specified by octal (base 8) or hexadecimal (base 16) values, rather than decimal (base 10).
Octal numbers are preceded by a 0 and hex by 0x. Thus, 1234 in decimal is equivalent to 02322
and 0x4D2. It is important to remember that these three constants represent exactly the same
value (0101 1101 0010 in binary). For example, the following code
prints
NB: C does not provide a direct binary representation. However, the hex form is very useful in
practice as it breaks down binary into blocks of four bits.
Floating-point constant is a number that contains either a decimal point or an exponent (or
both). For example: 1. and 1.3 are of type double, 3.14f and 2.f are of type float, and 7.4L is of
type long double. Floating point numbers can also be written using scientific notation, such as
1.65e-2 (which is equivalent to 0.0165).
Constant expressions, such as 3+7+9.2, are evaluated at compile-time and replaced by a single
constant value, 19.2. Thus, constant expressions incur no runtime overhead.
Character constants, such as ’a’, ’\n’, ’7’, are specified by single quotes. Character constants
are noteworthy because they are, in fact, not of type char, but of int. Thus, sizeof(’Z’) will
equal 4 on a 32-bit machine, not one. Most platforms represent characters using the ASCII
(American Standard Code for Information Interchange) character set, which associates the integers
0 to 127 with specific characters (e.g., the character ’A’ is represented by the integer 65).
There are certain characters that cannot be represented directly, but rather are denoted by an
“Escape sequence”. It is important to recognize that these escape characters still represent single
characters. The list of escape sequence are given in Table 1.2
String constants, such as "This is a test string" are any number of consecutive characters
including none, delimited by double quotes. The quotes are not actually part of the string
constant. They are implicitly appended with a terminating ’\0’ character. Thus, in memory, the
above string constant would comprise the following character sequence: This is a test string\0.
Note:
It is important to differentiate between a character constant (e.g., ’X’) and a NULL
terminated string constant (e.g., "X"). The latter is the concatenation of two characters
X\0. Note also that sizeof(’X’) is four (on a 32-bit machine) while sizeof("X") is two.
char a;
printf("%d %d %d\n", sizeof(a),sizeof('a'),sizeof("a")); results 1 4 2 in a 32
bit machine.
The NULL character constant ‘\0’ is not equivalent to the character constant ‘0’.
Defining Constants
There are two simple ways in C to define constants −
Using #define preprocessor. Syntax: #define identifier value
Using const keyword. Syntax: const type variable = value;
Examples:
#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'
const int L = 10;
const int W = 5;
const char NEWLINE = '\n';
const float PI=3.1416;
Note that it is a good programming practice to define constants in CAPITALS.
Variables
A variable is nothing but a name given to a storage area that our programs can manipulate. Each
variable in C has a specific type, which determines the size and layout of the variable's memory;
the range of values that can be stored within that memory; and the set of operations that can be
applied to the variable. The name of a variable can be composed of letters, digits, and the
underscore character. It must begin with either a letter or an underscore. Upper and lowercase
letters are distinct because C is case-sensitive. Based on the basic types there will be the
following basic variable types
char
int
float
double
void
C programming language also allows defining various other types of variables, like Enumeration,
Pointer, Array, Structure, Union, etc.
Variables can be initialized (assigned an initial value) in their declaration. The initializer
consists of an equal sign followed by a constant expression as follows
rvalue − The term rvalue refers to a data value that is stored at some address in memory.
An rvalue is an expression that cannot have a value assigned to it which means an rvalue
may appear on the right-hand side but not on the left-hand side of an assignment.
Variables are lvalues and so they may appear on the left-hand side of an assignment. Numeric
literals are rvalues and so they may not be assigned and cannot appear on the left-hand side.
Take a look at the following valid and invalid statements −
Arithmetic Operators
Relational Operators
Logical Operators
Bitwise Operators
Assignment Operators
Miscellaneous Operators
Arithmetic Operators
C provides all the basic arithmetic operators: addition (+), subtraction (-), multiplication (*) and
division (/). These can operate on any built-in data type allowed in C. The unary minus (-)
operator, multiplies its operand by -1. Integer division truncates the fractional part. The modulo
division operator (%) produces the remainder of an integer division. the modulo division
operator (%) cannot be used on floating point data. Note that C does not have an operator for
exponentiation. ANSI C supports unary plus operator.
Integer Arithmetic: When both operands in a single arithmetic expression such as a+b, a-b, a*b,
a/b, a%b are integers, the expression is called an integer expression, and the operation is called
integer arithmetic. Integer arithmetic always yields an integer value. The largest integer value
depends on the machine.
During integer division, if both operands are of the same sign, the result is truncated towards
zero. If the operands are of different sign, the direction of truncation is implementation
dependent.
Example: 6/7=0 -6/-7=0 -6/7= 0 or -1(Machine dependent)[in gcc it is 0]
-7/6= -1 (gcc) 7/-6= -1(gcc)
Ganesh.P Asst.Professor & HOD, CSE SIMAT,VAVANOOR
CS100 Computer Programming Page 19 of 32
During modulo division, the sign of the result is always the sign of the first operand (the
dividend). Example: -14 % 3 = -2 -14 % -3 = -2 14 % -13 = 2
Real arithmetic: An operation involving only real operands is called real arithmetic. A real
operand may assume values either in decimal or exponential notation. Since floating point values
are rounded to the number of significant digits permissible, the final value is an approximation of
correct result.
Example: x = 6.0 / 7.0 = 0.857143 y = 6.0 / 2.0 = 3.000000 z= -2.0 / 3.0 = -0.666667
Increment and decrement operators are unary operators that add or subtract one from
their operand, respectively. They are commonly implemented in imperative programming
languages like C. C-like languages feature two versions (pre- and post-) of each operator with
slightly different semantics. The increment operator is written as ++ and the decrement operator
is written as --.
The increment operator increases the value of its operand by 1. The operand must have an
arithmetic or pointer data type, and must refer to a modifiable data object. Similarly, the
decrement operator decreases the value of its modifiable arithmetic operand by 1. Pointers values
are increased (or decreased) by an amount that makes them point to the next (or previous)
element adjacent in memory.
The pre-increment and pre-decrement operators increment or decrement their operand by
1, and the value of the expression is the resulting incremented or decremented value. In contrast,
the post-increment and post-decrement operators increase or decrease the value of their operand
by 1, but the value of the expression is the operand's original value prior to the increment or
decrement operation.
Since the increment/decrement operator modifies its operand, use of such an operand
more than once within the same expression can produce undefined results. For example, in
expressions such as x - ++x, it is not clear in what sequence the subtraction and increment
operations should be performed. Such expressions generally invoke undefined behavior, and
should be avoided.
int x;
int y;
// Increment operators
x = 1;
y = ++x; // x is now 2, y is also 2
y = x++; // x is now 3, y is 2
// Decrement operators
x = 3;
y = x--; // x is now 2, y is 3
y = --x; // x is now 1, y is also 1
NB: The post-increment operator is commonly used with array subscripts. The post-decrement
operator is commonly used with pointers.
Let A=10 and B=20, the result of different arithmetic operators are given in Table 1.3.
Relational Operators
We often compare two quantities and depending on their relation, take certain decisions. These
comparisons can be done with the help of relational operators. For example, we may compare the
age of two persons, or price of two items etc. The value of a relational expression is either one or
zero. There are six relational operators:
greater-than >
less-than <
greater-than-or-equal-to >=
lessthan-or-equal-to <=
equal-to ==
not-equal-to !=.
Relational expressions evaluate to 1 if they are TRUE and 0 if they are FALSE. For example,
2.1 < 7 evaluates to one, and x != x evaluates to zero.
Among the six relational operators, each one is complement of another operator.
> is complement of <=
< is complement of >=
== is complement of !=
Note: A very common programming error is to mistakenly type = (assignment) for == (equality).
Let A=10 and B=20, the result of different relational operators are given in Table 1.4.
Logical Operators
These operators are used to perform logical operations on the given expressions. There are 3
logical operators in C . They are, logical AND (&&), logical OR (||) and logical NOT (!).
Assignment Operators
Assignment operators are used to assign the result of an expression to a variable. The usual
assignment operator is ‘=’. In addition C has a set of shorthand assignment operator s of the form
v OP = exp ;
Where v is the variable, exp is the expression and OP is a binary arithmetic operator. The
operator OP= is known as the shorthand assignment operator.
In C programs, values for the variables are assigned using assignment operators. For example, if
the value “10” is to be assigned for the variable “sum”, it can be assigned as “sum = 10;”
There are 2 categories of assignment operators in C language. They are,
1. Simple assignment operator ( = )
2. Compound assignment operators ( +=, -=, *=, /=, %=, &=, ^= )
Refer Table 1.5 for different shorthand assignment operators and examples.
Bitwise Operators
In the C programming language, operations can be performed on a bit level using bitwise
operators. Bitwise operations are contrasted by byte-level operations which characterize the
bitwise operators' logical counterparts, the AND, OR and NOT operators. Instead of performing
on individual bits, "byte-level" operators perform on strings of eight bits known as bytes at a
time. The reason for this is that a byte is normally the smallest unit of addressable memory (i.e.
data with a unique memory address.) This applies to bitwise operators as well, which means that
even though they operate on only one bit at a time they cannot accept anything smaller than a
byte as their input. C provides six operators for bit manipulation.
& bitwise AND
| bitwise inclusive OR
^ bitwise XOR (eXclusive OR)
<< left shift
>> right shift
bitwise NOT (one's complement) (unary)
~
Table 1.6: Bitwise XOR operator Table 1.7: Bitwise assignment operators
Miscellaneous Operators:
The following are some of the miscellaneous operators used by C.
Arithmetic Expressions
An arithmetic expression is a combination of variables, constants and operators arranged as per
the syntax of the language. C can handle any complex mathematical expressions. Remember
that C does not have an operator for exponentiation.
Algebraic expression C expression
axb-c a*b-c
(m+n)(x+y) (m+n) * (x+y)
ab a*b/c
c
3x 2 x 1
2
3*x*x + 2*x +1
x x/y+c
c
y
Table 1.9: Example for expressions.
Operators Precedence
Operator precedence determines the grouping of terms in an expression and decides how an
expression is evaluated. Certain operators have higher precedence than others; for Example, the
multiplication operator has a higher precedence than addition operator. For example, x=7+3* 2;
here, x is assigned 13, not 20 because operator * has a higher precedence than +, so it first gets
multiplied with 3*2 and then adds into 7.
In Table 1.10, operators with the highest precedence appear at the top of the table, those
with the lowest appear at the bottom. Within an expression, higher precedence operators will be
evaluated first.
Example
int a = 20;
int b = 10;
int c = 15;
int d = 5;
int e;
e = (a + b) * c / d; // ( 30 * 15 ) / 5 = 90
Operator associativity
In programming languages, the associativity (or fixity) of an operator is a property that
determines how operators of the same precedence are grouped in the absence of parentheses.
If an operand is both preceded and followed by operators (for example, "^ 4 ^"), and those
operators have equal precedence, then the operand may be used as input to two different
operations (i.e. the two operations indicated by the two operators). The choice of which
operations to apply the operand to, is determined by the "associativity" of the operators.
Operators may be associative (meaning the operations can be grouped arbitrarily), left
associative (meaning the operations are grouped from the left), right-associative (meaning the
operations are grouped from the right) or non-associative (meaning operations cannot be
chained, often because the output type is incompatible with the input types). The associativity
and precedence of an operator is a part of the definition of the programming language; different
programming languages may have different associativity and precedence for the same type of
operator.
Consider the expression a ~ b ~ c. If the operator ~ has left associativity, this expression
would be interpreted as (a ~ b) ~ c. If the operator has right associativity, the expression would
be interpreted as a ~ (b ~ c). If the operator is non-associative, the expression might be a syntax
error, or it might have some special meaning. Some mathematical operators have inherent
associativity. For example, subtraction and division, as used in conventional math notation, are
inherently left-associative. Addition and multiplication, by contrast, are both left and right
associative. (e.g. (a * b) * c = a * (b * c)).
Type Conversions
When an operator has operands of different types, they are converted to a common type
according to a small number of rules. In type conversion, the data type is promoted from lower to
higher because converting higher to lower involves loss of precision and value. For a binary
expression such as a * b, the following rules are followed (assuming neither operand is
unsigned):
If either operand is long double, convert the other to long double.
Otherwise, if either operand is double, convert the other to double.
Otherwise, if either operand is float, convert the other to float.
Otherwise, convert char and short to int, and, if either operand is long, convert the other
to long.
If the two operands consist of a signed and an unsigned version of the same type, then the
signed operand will be promoted to unsigned, with strange results if the previously signed
value was negative.
Note: The promotion from char to int is implementation-dependent, since whether a plain char
is signed or unsigned depends on the compiler. Some platforms will perform “sign extension” if
the left-most bit is 1, while others will fill the high-order bits with zeros—so the value is always
positive.
Forced conversion occurs when we are converting the value of the larger data type to the value
of the smaller data type or smaller data type to the larger data type. In general, the value of the
expression is promoted or demoted depending on the type of variable on left hand side of =.
Conversion from a larger type to a smaller one results in truncation of the higher-order bits, and
conversion from floating-point to integer causes truncation of any fractional part. For example,
int iresult = 0.5 + 3/5.0; the division 3/5.0 is promoted to type double so that the final result
equals 1.1. The result then is truncated to 1 in the assignment to iresult. The conversion from
double to float is implementation dependent and might be either truncated or rounded. Forced
conversion may decrease the precision. Type casting is the preferred method of forced
conversion.
The first field is a set of flags, which modify the meaning of the conversion operation (e.g.,
make the argument left-justified, or pad with zeros). We can place flags in the printf statement with
in the control string which will affect the appearance of the output. The flag must be placed
immediately after the percent sign (%). Two or more flags can be combined for a single output.
Ganesh.P Asst.Professor & HOD, CSE SIMAT,VAVANOOR
CS100 Computer Programming Page 31 of 32
The second field specifies a minimum width reserved for the converted argument (in characters),
and so provides padding for under-sized values. We can restrict the number of characters or
numbers displayed in the screen by specifying a field width. A minimum field width can be
specified by preceding the conversion character by an unsigned integer. If the number of
characters in the corresponding data item is less than the specified field width then the data item
will be preceded by enough leading blanks to fill the specified field. If the number of characters
in the data item exceeds the specified field width then additional space will be allocated to the
data item so that the entire data item will be displayed.
The third field is a precision specification, which has various different meanings for integers,
floating point values and strings. It specifies the maximum number of decimal places for a
floating point value or the maximum number of characters displayed for a string. The precision is
an unsigned integer. Precision is always preceded by a decimal point. A floating point number
will be rounded if the number of digits exceeds the precision.
The fourth field is a size modifier, which indicates conversion to a longer(l) or shorter type(h)
than the default conversion types (where the default types are, for example, int or double).
Most often printf() involves just the % and a conversion character, and rarely get more
complex than the following example, printf("Value = %-10.3f radians.\n", fval);
which, if passed the floating point value 3.14159, would print Value = 3.142 radians. ,
where the converted floating point value is left-justified (due to the - flag), is padded with
sufficient space for 10 characters, and displays 3 digits after the decimal point.
Ganesh.P Asst.Professor & HOD, CSE SIMAT,VAVANOOR
CS100 Computer Programming Page 32 of 32