Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
What is C ?
Ans: C is a programming language developed at AT & T’s BELL laboratories of USA in
1972 and it was designed and written by Dennis Ritchie. It is reliable,simple and easy to
use that’s why C seems to so popular. C wasn’t mean to win prizes; it was meant to be
friendly and reliable. The following fig-1.1 shows the evolution of C language:
ALGOL
Year: 1960
Developed by:
International committee
Remarks: Too general
CPL
Year: 1963
Developed by:
Cambridge University
Remarks: Difficult to
implement, Hard to learn
BCPL
Year:1967
Developed By: Martin
Richards at Cambridge
Remarks: Too specific and
less powerful
B
Year:1970
Developed By: Ken
Thompson at AT & T
Remarks: Too specific
Traditional C
Year: 1972
Developed by: Denis
Ritchie at AT & T
Remarks: lost generality
of BCPL and B restored
What are the different stages involved in the execution of a C source program?
Ans: There are several steps involved from the stage of writing a c program to the stage of
getting it executed. Fig-1.2 shows these different stages:
Text Editor
C Source Code
Preprocessor
Compiler
Object Code
Linker
Executable Code
Fig-1.2
What is compiler?
Ans: A program can not be run by the computer directly. This is because a computer can
understand and execute only those programs that are written in machine language. Thus a C
program has to convert into machine language before execution. A C Compiler translates a C
program into a machine language program.
Ans: The machine language of a computer consists of a set of instructions, each of which
corresponds to a relatively simple operation such as add two numbers, go to a particular
instruction and so on. All these instructions are encoded in binary, and they can be executed by
the computer directly.
Ans: Assembly language is one step higher than machine language. Here every machine
language instruction is given by a given symbolic name, so that programs can be written easily
using these names instead of binary instructions. Assembly language is a low-level language.
A large number of instructions must be written in low-level language even for a simple task
such as computing and printing roots of quadratic equation.
What is Linker?
Ans: Previously i have said that a C source program has to convert into machine language
before execution. This process actually takes place in two stages: compiling and linking. The
compiler performs the basic translation from C statements into machine language
instructions .The output of the compiler is called the object file. The linker combines different
object files to produce the actual executable file.
Why should not the Compiler itself produce the executable file directly?
#include<stdio.h>
int main(void)
{
Created by sukumar Paul 3
Complete C Handbook
Printf(“Hello World\n”);
Printf(“Bye”);
return(0);}
What is Preprocessor?
Ans: Previously I have said how a compiler and linker interact6 each other to give the
executable file of a C source program. Actually before compiling, a process called
preprocessing is done on the source code by a program called the preprocessor.
#include<stdio.h>
This above line is a preprocessor directive. All lines in the program beginning with a hash(#)
sign are processed by the preprocessor. The #include directive causes the preprocessor to insert
the stdio.h file into the C source program. When the compiler compiles the program, it sees the
contents of the stdio.h file instead of the preprocessor directive. Preprocessor performs the
following activities:
Macro substitution
Conditional compilation
Inclusion of named files
Error generation
Pragmas
Predefined names
Ans: many non-english keyboard don’t support all characters. ANSI C introduces the concept
of trigraph sequences to provide a way to enter the certain character that are not avaible on
some keyboard. Each trigraph sequence consists of three characters.fig-1.3 shows some
ANSI C trigraph sequences:
3. ??- ~ Tilde
Fig-1.3
What is variable and what are the rules for constructing variable names?
Ans: A variable is a data name that may be used to store a data value. A variable may take
different values at different times during execution.
Rules for constructing a variable name:
1. A variable name is any combination of 1-8 alphabets, digits or underscores.
2. They must begin with a letter. Some system permits underscore as a first character.
3. No commas or blanks are allowed within a variable name.
4. No special symbol other than an underscore can be used in the variable name.
5. Uppercase and lowercase are significant. That is TOTAL is not same as total or as Total.
6. It should not be a keyword.
7. But keyword may be part of a name. That is int_type is a valid variable name.
8. Average_height and Average _weight will be the same variable as only first eight characters
are recognized by the compiler.
New line \n
Horizontal tab \t
Vertical tab \v
Back space \b
Audible alert \a
Backlash \\
Question mark \?
Single Quote \’
Double Quote \”
What is Typedef?
Ans: C provides a facility called Typedef for creating new data type names. It takes general
form: typedef type identifier; where type refers to the existing data type and identifier
refers to the new name given to the data type. The may also belongs to the user defined data
type. For example: the declaration
typedef int integer
makes the name integer as a synonym for int. The main advantage of typedef is that we can
create the meaningful data type names for increasing the readability of the program.
What is storage class and how many types of storage class are there?
Ans: Storage class specifier inform the compiler how and where to store the variables.
There are four storage class in C:
1. Automatic storage class : The features of this storage class is given below:
Storage: Memory
Default initial value: Garbage value
Scope: Local to the block in which the variable is declared
Life: Till the control remains within the block in which the
variable is defined
Keyword: auto
Application: General purpose
2. Register storage class: the features of this storage class is given below:
3. Static storage class: the features of this storage class is given below:
Storage: Memory
Default initial value: Zero
Scope: local to the block in which it is defined
Life: Value of the variable persists between different
function calls
Keyword: static
Application: in case of recursive functions
4. External storage class: the features of this storage class is given below:
Storage: Memory
Default initial value: Zero
Scope: Global
Life: As long as program execution doesn’t comes to end
Keyword: extern
Application: in case of Global variable
Operator Associativity:
The operators of the same precedence are evaluated either from ‘left to right’ or from ‘right to
left’ depending on the level. This is known as associativity property of an operator.
Actually associativity rules decides the order in which multiple occurrence of the same level
operator are applied.
Ans: C is one of the few languages to allow coercion, which is forcing one variable of one type
to be another type. If we did want to divide two integers together to produce a decimal, you can
use the process called COERCION or TYPECASTING. Take a look at this example:
#include <stdio.h>
int main ()
{
int a,b;
float c;
a = 6;
b = 4;
c = (float)a/b;
printf("6 divided by 4 is %f\n", c);
return 0;
}
This example might seem a little confusing at first - if that's the case, ignore the printf line for
now. Anyway, the line that does the coercion business is:
c = (float)a/b;
Variables a and b are both declared as integers and have 4 and 6 assigned to them respectively.
c is a floating point number. The (float) part of the line, mentioned above, forces the floating
point value of a/b into c, which is already of the type float.
Which two characters helps the compiler to determine the difference between
function header and function prototype?
Ans: There are some difference between function header and function prototype:
1.The prototype has a semicolon, but function header has no semicolon:
int print_table(int,float,char *);
2.But the function header has a open brace and has no semicolon:
int print_table(int,float char *)
{
What is Heap?
Ans: An executing program is divided into four parts:
1. Stack: provides storage for local variables, alters size as the program executes
2. Data Segment: Global variables and strings are stored here and size is fixed
3. Code segment: Functions main, printf, scanf, etc. are stored here. It’s read-only.
4. Heap: otherwise known as “dynamic memory”. The heap is aviable for us to use and may
alter size as the program executes
A program executing in memory may be represented by the following diagram:
When I set a float variable to, say, 3.1, why is printf printing
it as 3.0999999?
Ans: Most computers use base 2 for floating-point numbers as well as for integers. It is well-
known that in base 10, a fraction like 1/3=0.33333333……repeats infinitely. In base 2,
one divided by ten is an infinitely-repeating fraction (0.0001100110011...), so fractions
such as 3.1 (which look like they can be exactly represented in decimal) can not be
represented exactly in binary. Depending on how carefully the compiler's
binary/decimal conversion routines (such as those used by printf) have been written.
Ans: The array declaration char [6] request that the space for 6 characters be set aside ,to be
known by the name by a. That is there is a location named a at which six characters can sit.
The pointer declaration char *p, on the other hand, request a place that holds a pointer, to be
known by the name p.
The declarations char a[]=”Hello”; and char *p=”world”; would initialize the data
structure that could be represented like this:
H e l l o \0
p w o l d \0
It is important to realize that a reference like x[3] generates different code b, depending on
whether x is an array or pointer. When compiler will see a[3], it emits code to start at location
a, move three past it, and fetch the character there. When it sees the expression p[3], it emits
to start at location p, fetch the pointer value there, add three to the pointer, and finally fetch
the character pointed to. In our example, both a[3] and p[3] happen to be the character ‘l’, but
the compiler gets there differently.
void exit_fn1(void)
{
printf("Exit function #1 called\n");
}
void exit_fn2(void)
{
printf("Exit function #2 called\n");
}
int main(void)
{
/* post exit function #1 */
atexit(exit_fn1);
/* post exit function #2 */
atexit(exit_fn2);
return 0;
}
#include<stdio.h>
#include<conio.h>
void main() //sizeof() is a operator not a function
{
Output:
11...2...1...1
...10..2
....2..1..2..1
A program to implement the sizeof operator:
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
/* Find the size of an variable */
#define sizeof_var( var ) ((size_t)(&(var)+1)-(size_t)(&(var)))
/* Find the size of a data type */
#define sizeof_type( type ) (size_t)((type*)1000 + 1 )-(size_t)((type*)1000)
int main (void)
{
int a;
int b[10];
clrscr();
printf ( "%lu\n", sizeof ( b ) );
printf ( "%lu\n", sizeof ( b+0 ) );
printf ( "%lu\n", sizeof_var ( b ) );
printf ( "%lu\n", sizeof_type ( int ) );
return (EXIT_SUCCESS);
}
#include<stdio.h>
#define f(g,g2) g##g2
void main()
{
int var1314=200;
printf("%d \t%d",f(var,1314),var);
}
Advantages:
Now a million dollar question ….why actually c programmer uses macro? Actually macro
increases the readability of the program. But there is perhaps another important reason for
using macro definition. Suppose a constant like 3.1415 appears many times in our program.
This value may have to be changed some day to 3.141592. ordinarily we have to go through
the program and manually change the each occurrence of the constant. However if we defined
PI in a #define directive, we need to only one change, in the #define directive itself:
#define PI 3.141592
Disadvantages: It makes the program larger. If we use a macro 100 times in a program, the
macro expansion goes into our source code at 100 different places, thus increasing the program
size.
#include<stdio.h>
What is ternary operator? Write a program to get the greatest number among three
numbers using ternary operator?
Ans: The C language has an unusual operator, useful for making two-way decision. The
general form of this operator is:
expression1 ? expression2 : expression3;
The above statement says that: if expression1 is true, then the value returned will be
expression2 otherwise the value returned will be expression3.
/*a program calculate greatest value among three numbers using ternary operator*/
#include<stdio.h>
int main()
{
int a=1,b=17,c=-2,d;
d = (a>b)?((a>c)?a:c):((b>c)?b:c);
printf(“Greatest number is= %d”,d) ;
return(0);
}
What are the files which are automatically opened when a c file is executed?
Ans: stdin, stdout, stderr (standard input, standard output, standard error)
What do you mean by void? Can you declare a void type variable?
Ans: When ‘void’ used as a function return type, then it means that the function does not return
any value. For example:
Void display(char *name)
{
printf(“Hello %s”,name);
}
Here display function will not return any value.
When ‘void’ is found in the argument list of the function, then it means that it doesn’t take any
argument. For example:
int init(void)
{ return(1);
}
Here init function doesn’t take any argument but return an integer.
No, we can not declare any void type variable unlike integer type variable because the sizeof that
variable is totally unknown to the compiler, so there will be a compiler error.
Calloc: calloc is a another memory allocation function that is normally used for requesting
memory space at run time for storing derived data types. While malloc allocates a single block
of memory, calloc allocates multiple block of memory, each of same size, and then set all
bytes to zero. The general form of calloc is:
Ptr=(cast-type *)calloc(n,element-size) ;
Free: Compile time storage of a variable is allocated and released by the system in accordance
with it’s storage class. But with the dynamic run-time allocation , it is our responsibility to
release the space when it is not required. We may use free() function for this purpose:
Free(ptr);
Here ptr is a pointer to a memory block which has already been created by malloc or calloc.
use of an invalid pointer in the call may create problems and cause system crash.
Realloc: if we discover later that the previously allocated memory is not sufficient and we
need to additional space for more elements or the previously allocated memory is much larger
than necessary and we want to reduce it, in both these cases we can change the memory size by
the function realloc(). For example: if the original allocation is done by the statement:
Ptr=(cast-type *) malloc(size);
Then reallocation of space may be done by the statement:
Ptr=realloc(ptr,new-size);
In case, it is not able to find additional space in the same region, it will create the same in an
entirely new region and move the contents of the old block into the new block. The functions
guarantees that the old data will remain intact. But if the function unsuccessful in allocating
additional space, it returns a NULL pointer and the original block is lost or freed.
Here we can’t use ptr.name or ptr.author because ptr is not a structure variable but a pointer to
a structure, and the ‘dot operator’ requires a structure variable on it’s left. In such cases C
provides an ‘arrow operator’ to refer to the structure elements.
On the left hand side of the ‘.’ Structure operator, there must always be a structure variable,
whereas on the left hand side of the -> operator, there must always be a pointer to structure.
What is the difference between const char *p, char const *p and char * const p?
Ans: The first two are interchangeable; they declare a pointer to a constant character (which
means that we can’t change the character). On the other hand, char * const p declares a
constant pointer to a character (i.e. we can’t change the pointer).
How do you write a program that produces it’s own source code as it’s output?
Ans: consider the following self-reproducing program:
#include<stdio.h>
char *s="char *s=%c%s%c;void main() {printf(s,34,s,34);}";
void main(){printf(s,34,s,34);}
printf("\nGender=%d\nMarital status=%d"
"\nBytes occupied by e=%d",e.gender,e.mar_stat,sizeof(e));
}
Output: Gender=0
We have seen that console oriented I/O functions, such as printf(), scdanf() can be used
to read input from keyboard and write output to VDU. These process is fine as long as data is
small. However in real life problems involve large volumes of data, in such situation two major
problems occur for using console I/O functions are:
1. it becomes time consuming to handle large volumes of data through terminals.
2. The entire data is lost when either program is terminated or the computer is turned off.
It is therefore necessary to have more flexible approach where data can be stored on the disks
and read when necessary, without destroying the data. This method employs the concept of
files to store data.
Actually, main() can take two arguments called argc and argv and the information contained in
the command line is passed on to the program through these arguments, when main is called by
the system.
Here the variable argc is an argument counter that counts the no. of arguments on the
command line. The argv is an array of character pointer that points to the command line
argument. The size of the array will be equal to the value of argc. For the command line given
above, argc is 3 and argv is an array of three pointer to strings:
argv[0] => PROGRAM>EXE
argv[1] => orig_file
argv[2] => copy_file
It is not necessary that we should always use the variable names agrc and argv.
To be able to successfully read a file, information like mode of opening, size of the file, place
of the file from where the next read operation would be performed, etc. has to be maintained.
Since all this information is inter-related, all of it is gathered together by fopen() in a structure
called FILE. fopen returns the address of this structure, which we usually collect in the
structure pointer called fp.