1.Difference between arrays and pointers?
- Pointers are used to manipulate data using the address.
Pointers use * operator to access the data pointed to by them
- Arrays use subscripted variables to access and manipulate
data.Array variables can be equivalently written using pointer
expression.
2. What are the advantages of the functions?
Answer - Debugging is easier
- It is easier to understand the logic involved in the program
- Testing is easier
- Recursive call is possible
- Irrelevant details in the user point of view are hidden in
functions
- Functions are helpful in generalizing the program
3 How can I open a file so that other programs can
update it at the same time?
Answer Your C compiler library contains a
low-level file function called sopen() that can be used to
open a file in shared mode. Beginning with DOS 3.0, files
could be opened in shared mode by loading a special program
named SHARE.EXE. Shared mode, as the name implies, allows a
file to be shared with other programs as well as your own.
Using this function, you can allow other programs that are
running to update the same file you are updating.
The sopen() function takes four parameters: a pointer to the
filename you want to open, the operational
mode you want to open the file in, the file sharing mode to
use, and, if you are creating a file, the mode to create the
file in. The second parameter of the sopen() function, usually
referred to as the “operation flag”parameter, can have the
following values assigned to it:
Constant Description O_APPEND Appends all writes to the end of
the file
O_BINARY Opens the file in binary (untranslated) mode
O_CREAT If the file does not exist, it is created
O_EXCL If the O_CREAT flag is used and the file exists,
returns an error
O_RDONLY Opens the file in read-only mode
O_RDWR Opens the file for reading and writing
O_TEXT Opens the file in text (translated) mode
O_TRUNC Opens an existing file and writes over its contents
O_WRONLY Opens the file in write-only mode
The third parameter of the sopen() function, usually referred
to as the “sharing flag,” can have the following values
assigned to it:
Constant Description
SH_COMPAT No other program can access the file
SH_DENYRW No other program can read from or write to the file
SH_DENYWR No other program can write to the file
SH_DENYRD No other program can read from the file
SH_DENYNO Any program can read from or write to the file
If the sopen() function is successful, it returns a
non-negative number that is the file’s handle. If an error
occurs, –1 is returned, and the global variable errno is set
to one of the following values:
Constant Description
ENOENT File or path not found
EMFILE No more file handles are available
EACCES Permission denied to access file
EINVACC Invalid access code
Constant Description
4. Can static variables be declared in a header file?
You can’t declare a static variable without defining it as
well (this is because the storage class modifiers
static and extern are mutually exclusive). A static variable
can be defined in a header file, but this would cause each
source file that included the header file to have its own
private copy of the variable, which is probably not what was
intended.
6.How can you check to see whether a symbol is defined?
You can use the #ifdef and #ifndef preprocessor directives
to check whether a symbol has been defined
(#ifdef) or whether it has not been defined (#ifndef).
7.How do you override a defined macro?
Answer
You can use the #undef preprocessor directive to undefine
(override) a previously defined macro.
10. Can a variable be both const and volatile?
Yes. The const modifier means that this code cannot change
the value of the variable, but that does not mean that the
value cannot be changed by means outside this code. For
instance, in the example in
FAQ 8, the timer structure was accessed through a volatile
const pointer. The function itself did not change the value of
the timer, so it was declared const. However, the value was
changed by hardware on the computer, so it was declared
volatile. If a variable is both const and volatile, the two
modifiers can appear in either order.
11. Can include files be nested?
Yes. Include files can be nested any number of times. As long
as you use precautionary measures , you can avoid including
the same file twice. In the past, nesting header files was
seen as bad programming practice, because it complicates the
dependency tracking function of the MAKE program and thus
slows down compilation. Many of today’s popular compilers make
up for this difficulty by implementing a concept called
precompiled headers, in which all headers and associated
dependencies are stored in
a precompiled state.
Many programmers like to create a custom header file that has
#include statements for every header needed for each module.
This is perfectly acceptable and can help avoid potential
problems relating to #include files, such as accidentally
omitting an #include file in a module.
12. Can static variables be declared in a header file?
Yes there is difference between declaring a static
variable as global and local. If it is local, it can be
accessed only in the function where it's declared. But if it
is global, all functions can access it. But, what ever be the
case, its value will be retained between functions.
13. When does the compiler not implicitly generate the
address of the first element of an array?
Whenever an array name appears in an expression such as
- array as an operand of the sizeof operator
- array as an operand of & operator
- array as a string literal initializer for a character array
Then the compiler does not implicitly generate the address of
the address of the first element of an array.
14.What is the difference between #include <file> and
#include “file”?
When writing your C program, you can include files in two
ways. The first way is to surround the file you
want to include with the angled brackets < and >. This method
of inclusion tells the preprocessor to look for the file in
the predefined default location. This predefined default
location is often an INCLUDE environment variable that denotes
the path to your include files. For instance, given the
INCLUDE variable
INCLUDE=C:\COMPILER\INCLUDE;S:\SOURCE\HEADERS;
using the #include <file> version of file inclusion, the
compiler first checks the C:\COMPILER\INCLUDE
directory for the specified file. If the file is not found
there, the compiler then checks the
S:\SOURCE\HEADERS directory. If the file is still not found,
the preprocessor checks the current directory.
The second way to include files is to surround the file you
want to include with double quotation marks. This method of
inclusion tells the preprocessor to look for the file in the
current directory first, then look for it in the predefined
locations you have set up. Using the #include “file” version
of file inclusion and applying it to the preceding example,
the preprocessor first checks the current directory for the
specified file. If the file is not found in the current
directory, the C:COMPILERINCLUDE directory is searched. If the
file is still not found, the preprocessor checks the
S:SOURCEHEADERS directory.
The #include <file> method of file inclusion is often used to
include standard headers such as stdio.h or
stdlib.h. This is because these headers are rarely (if ever)
modified, and they should always be read from your compiler’s
standard include file directory.
The #include “file” method of file inclusion is often used to
include nonstandard header files that you have created for use
in your program. This is because these headers are often
modified in the current directory, and you will want the
preprocessor to use your newly modified version of the header
rather than the older, unmodified version.
15.When function say abc() calls another function say
xyz(), what happens in stack?
When some function xyz() calls function abc(). all the
local variables, static links, dynamic links and function
return value goes on the top of all elements of function xyz()
in the stack. when abc() exit it's return value has been
assigned to xyz().
16.How do you print an address?
we can print the address of a variable or a function using
the following specifiers %u,%p here %u prints address in
decimal form and %p prints in hexa decimal form,but remember
these two format specifiers print only offset adress but they
doesn't print code segment address
there is a another specifier %Fp which prints both the code
segment and offset address
18.How to find entered number is EVEN or ODD without
using conditional statement(not using if.. else,if.. , else
if..,while, do... while...., for....)
We can find a number is odd or even by a simple
programmain(){int a[2],i;a[0]=0; //0--means Even Numbera[1]=1;
//1--means Odd numberscanf("%d",&i);printf("%d",a[i%2]);getch();}
19.How to break cycle in circular single link list?
we can delete an intermediate one
20.How can I convert a number to a string?
We can convert number to string using built in function
itoa().
21.How to swap the content oftwo variables without a
temporary variable
void swap(int a,int b)
{
a =a+b;
b=a-b;
a=a-b;
}
22. How can send unlimited no of arguments to a
function, eg printf function can take any no of arguments
using va_list variables in stdarg.h headerfile
23.What is the benefit of using #define to declare a
constant?
Using the #define method of declaring a constant enables you
to declare a constant in one place and use it throughout your
program. This helps make your programs more maintainable,
because you need to maintain only the #define statement and
not several instances of individual constants throughout your
program.
For instance, if your program used the value of pi
(approximately 3.14159) several times, you might want to
declare a constant for pi as follows:
#define PI 3.14159
Using the #define method of declaring a constant is probably
the most familiar way of declaring constants to traditional C
programmers. Besides being the most common method of declaring
constants, it also takes up the least memory. Constants
defined in this manner are simply placed directly into your
source code, with no variable space allocated in memory.
Unfortunately, this is one reason why most debuggers cannot
inspect constants created using the #define method.
24.How do you write a C program which can calculate
lines of code but not counting comments?
Using file concept with Command line arguments.declare a
variable (lcnt) used to count the no of lines.Open a file in
read made and then using while loop check the condition for
not equal to EOF.Later using if condition check check for new
line and increment the variable for counting the lines.
Then using while,check for the character '/','*' (as the
comments start with these characters) and end with ('*' and
'/').if condition of this is true then break and come out of
the block else increment the line.
25.How can I search for data in a linked list?
Unfortunately, the only way to search a linked list is
with a linear search, because the only way a linked list’s
members can be accessed is sequentially. Sometimes it is
quicker to take the data from a linked list and store it in a
different data structure so that searches can be more
efficient.
26.How to write a C program to find the power of 2 in a
normal way and in single step?
U can take logarithm base 2, and check the result is in
interger form or floating point form, u can check whether it
is power of 2 or not.
27.What is hashing?
To hash means to grind up, and that’s essentially what hashing
is all about. The heart of a hashing algorithm is a hash
function that takes your nice, neat data and grinds it into
some random-looking integer.
The idea behind hashing is that some data either has no
inherent ordering (such as images) or is expensive to compare
(such as images). If the data has no inherent ordering, you
can’t perform comparison searches.
If the data is expensive to compare, the number of comparisons
used even by a binary search might be too many. So instead of
looking at the data themselves, you’ll condense (hash) the
data to an integer (its hash value) and keep all the data with
the same hash value in the same place. This task is carried
out by using the hash value as an index into an array.
To search for an item, you simply hash it and look at all the
data whose hash values match that of the data you’re looking
for. This technique greatly lessens the number of items you
have to look at. If the parameters are set up with care and
enough storage is available for the hash table, the number of
comparisons needed to find an item can be made arbitrarily
close to one.
One aspect that affects the efficiency of a hashing
implementation is the hash function itself. It should ideally
distribute data randomly throughout the entire hash table, to
reduce the likelihood of collisions. Collisions occur when two
different keys have the same hash value. There are two ways to
resolve this problem. In “open addressing,” the collision is
resolved by the choosing of another position in the hash table
for the element inserted later. When the hash table is
searched, if the entry is not found at its
hashed position in the table, the search continues checking
until either the element is found or an empty position in the
table is found
The second method of resolving a hash collision is called
“chaining.” In this method, a “bucket” or linked list holds
all the elements whose keys hash to the same value.
When the hash table is searched, the list must be searched
linearly.
28.Diffence arrays and pointers?
To access data using pointers we use the *.
to access data stored in array we use indexes such as a[0].
30.Can a variable be both const and volatile?
This is possible and mostly used in embedded system.The
example is Interrupt Status Register.As it is a status
register , in the program we should not modify this
variable.So it should be a constant.But this variable can be
changed by the processor or hardware based on the interrupt
condition.So when in the program ,we want to read the value of
this varible , it should read the actual value with out any
optimisation.For this reason ,the variable can be declared as
volatile too
31.Why should we assign NULL to the elements (pointer)
after freeing them?
Answer
This is paranoia based on long experience. After a pointer has
been freed, you can no longer use the pointed-to data. The
pointer is said to “dangle”; it doesn’t point at anything
useful. If you “NULL out” or “zero out” a pointer immediately
after freeing it, your program can no longer get in trouble by
using that pointer. True, you might go indirect on the null
pointer instead, but that’s something your debugger might be
able to help you with immediately. Also, there still might be
copies of the pointer that refer
to the memory that has been deallocated; that’s the nature of
C. Zeroing out pointers after freeing them won’t solve all
problems;
32.What is a “null pointer assignment” error? What are
bus errors, memory faults, and core dumps?
These are all serious errors, symptoms of a wild pointer or
subscript.
Null pointer assignment is a message you might get when an
MS-DOS program finishes executing. Some
such programs can arrange for a small amount of memory to be
available “where the NULL pointer points to” (so to speak). If
the program tries to write to that area, it will overwrite the
data put there by the compiler.
When the program is done, code generated by the compiler
examines that area. If that data has been changed, the
compiler-generated code complains with null pointer
assignment.
This message carries only enough information to get you
worried. There’s no way to tell, just from a null
pointer assignment message, what part of your program is
responsible for the error. Some debuggers, and some compilers,
can give you more help in finding the problem.
Bus error: core dumped and Memory fault: core dumped are
messages you might see from a program running under UNIX.
They’re more programmer friendly. Both mean that a pointer or
an array subscript was wildly out of bounds. You can get these
messages on a read or on a write. They aren’t restricted to
null pointer problems.
The core dumped part of the message is telling you about a
file, called core, that has just been written in your current
directory. This is a dump of everything on the stack and in
the heap at the time the program was running. With the help of
a debugger, you can use the core dump to find where the bad
pointer was used.
That might not tell you why the pointer was bad, but it’s a
step in the right direction. If you don’t have write
permission in the current directory, you won’t get a core
file, or the core dumped message.
33.What are storage class in c
Answer
There r of 4 type of storage class in C
static
auto
register
extern
34.Following declarations are different from one another
const char *const s;
char const *const s;
Answer
There is no difference between the two declarations.
35.When should a type cast be used?
There are two situations in which to use a type cast. The
first use is to change the type of an operand to an arithmetic
operation so that the operation will be performed properly.
The second case is to cast pointer types to and from void * in
order to interface with functions that expect or return void
pointers. For example, the following line type casts the
return value of the call to malloc() to be a pointer to a foo
structure.
struct foo *p = (struct foo *) malloc(sizeof(struct foo));
36.What is a null pointer?
There are times when it’s necessary to have a pointer that
doesn’t point to anything. The macro NULL, defined in <stddef.h>,
has a value that’s guaranteed to be different from any valid
pointer. NULL is a literal zero, possibly cast to void* or
char*. Some people, notably C++ programmers, prefer to use 0
rather than NULL.
The null pointer is used in three ways:
1) To stop indirection in a recursive data structure
2) As an error value
3) As a sentinel value
36.What is a const pointer?
There are cases when you need to define a constant pointer to
a variable/object; for instance, when taking a function
address, or when you want to protect a pointer from unintended
modifications such as assignment of new address, pointer
arithmetic, etc. In fact, an object’s this is a constpointer.
A constant pointer is declared:
37.when should the volatile modifier be used?
The volatile modifier is a directive to the compiler’s
optimizer that operations involving this variable should not
be optimized in certain ways. There are two special cases in
which use of the volatile modifier is desirable. The first
case involves memory-mapped hardware (a device such as a
graphics adaptor that appears to the computer’s hardware as if
it were part of the computer’s memory), and the second
involves shared memory (memory used by two or more programs
running simultaneously).
Most computers have a set of registers that can be accessed
faster than the computer’s main memory. A good compiler will
perform a kind of optimization called “redundant load and
store removal.” The compiler looks for places in the code
where it can either remove an instruction to load data from
memory because the value is already in a register, or remove
an instruction to store data to memory because the value can
stay in a register until it is changed again anyway.
If a variable is a pointer to something other than normal
memory, such as memory-mapped ports on a
peripheral, redundant load and store optimizations might be
detrimental. For instance, here’s a piece of code that might
be used to time some operation:
time_t time_addition(volatile const struct timer *t, int a)
{
int n;
int x;
time_t then;
x = 0;
then = t->value;
for (n = 0; n < 1000; n++)
{
x = x + a;
}
return t->value - then;
}
In this code, the variable t->value is actually a hardware
counter that is being incremented as time passes. The function
adds the value of a to x 1000 times, and it returns the amount
the timer was incremented by while the 1000 additions were
being performed. Without the volatile modifier, a clever
optimizer might assume that the value of t does not change
during the execution of the function, because there is no
statement that explicitly changes it. In that case, there’s no
need to read it from memory a second time and subtract it,
because the answer will always be 0. The compiler might
therefore “optimize” the function by making it always return
0.
If a variable points to data in shared memory, you also don’t
want the compiler to perform redundant load and store
optimizations. Shared memory is normally used to enable two
programs to communicate with each other by having one program
store data in the shared portion of memory and the other
program read the same portion of memory. If the compiler
optimizes away a load or store of shared memory, communication
between the two programs will be affected.
38.What is the benefit of using an enum rather than a
#define constant?
The use of an enumeration constant (enum) has many
advantages over using the traditional symbolic constant style
of #define. These advantages include a lower maintenance
requirement, improved program readability, and better
debugging capability.
1) The first advantage is that enumerated constants are
generated automatically by the compiler. Conversely, symbolic
constants must be manually assigned values by the programmer.
For instance, if you had an enumerated constant type for error
codes that could occur in your program, your enum definition
could look something like this:
enum Error_Code
{
OUT_OF_MEMORY,
INSUFFICIENT_DISK_SPACE,
LOGIC_ERROR,
FILE_NOT_FOUND
};
In the preceding example, OUT_OF_MEMORY is automatically
assigned the value of 0 (zero) by the compiler because it
appears first in the definition. The compiler then continues
to automatically assign numbers to the enumerated constants,
making INSUFFICIENT_DISK_SPACE equal to 1, LOGIC_ERROR equal
to 2, and FILE_NOT_FOUND equal to 3, so on.
If you were to approach the same example by using symbolic
constants, your code would look something like this:
#define OUT_OF_MEMORY 0
#define INSUFFICIENT_DISK_SPACE 1
#define LOGIC_ERROR 2
#define FILE_NOT_FOUND 3
values by the programmer. Each of the two methods arrives at
the same result: four constants assigned numeric values to
represent error codes. Consider the maintenance required,
however, if you were to add two constants to represent the
error codes DRIVE_NOT_READY and CORRUPT_FILE. Using the
enumeration constant method, you simply would put these two
constants anywhere in the enum definition. The compiler would
generate two unique values for these constants. Using the
symbolic constant method, you would have to manually assign
two new numbers to these constants. Additionally, you would
want to ensure that the numbers you assign to these constants
are unique.
2) Another advantage of using the enumeration constant method
is that your programs are more readable and thus can be
understood better by others who might have to update your
program later.
3) A third advantage to using enumeration constants is that
some symbolic debuggers can print the value of an enumeration
constant. Conversely, most symbolic debuggers cannot print the
value of a symbolic constant. This can be an enormous help in
debugging your program, because if your program is stopped at
a line that uses an enum, you can simply inspect that constant
and instantly know its value. On the other hand, because most
debuggers cannot print #define values, you would most likely
have to search for that value by manually looking it up in a
header file.
39.When is a switch statement better than multiple if
statements?
The switch statement is better than multiple if statements
when there are more than two alternatives to be selected
whether the case value matches to the variable of either
character or integer type.
40.What is the difference between a string copy (strcpy)
and a memory copy (memcpy)? When should each be used?
The strcpy() function is designed to work exclusively with
strings. It copies each byte of the source string to the
destination string and stops when the terminating null
character () has been moved. On the other hand, the memcpy()
function is designed to work with any type of data. Because
not all data ends with a null character, you must provide the
memcpy() function with the number of bytes you want to copy
from the source to the destination.
41.How can I convert a string to a number?
The standard C library provides several functions for
converting strings to numbers of all formats (integers, longs,
floats, and so on) and vice versa.
The following functions can be used to convert strings to
numbers:
Function Name Purpose
atof() Converts a string to a double-precision floating-point
value.
atoi() Converts a string to an integer.
atol() Converts a string to a long integer.
strtod() Converts a string to a double-precision
floating-point value and reports any “leftover” numbers that
could not be converted.
strtol() Converts a string to a long integer and reports any
“leftover” numbers that could not be converted.
strtoul() Converts a string to an unsigned long integer and
reports any “leftover” numbers that could not be converted.
41.How can I convert a number to a string?
The standard C library provides several functions for
converting numbers of all formats (integers, longs, floats,
and so on) to strings and vice versa The following functions
can be used to convert integers to strings:
Function Name Purpose
itoa() Converts an integer value to a string.
ltoa() Converts a long integer value to a string.
ultoa() Converts an unsigned long integer value to a string.
The following functions can be used to convert floating-point
values to strings:
Function Name Purpose
ecvt() Converts a double-precision floating-point value to a
string without an embedded decimal point.
fcvt() Same as ecvt(), but forces the precision to a specified
number of digits.
gcvt() Converts a double-precision floating-point value to a
string with an embedded decimal point.
42.Is it possible to execute code even after the program
exits the main() function?
The standard C library provides a function named atexit() that
can be used to perform “cleanup” operations when your program
terminates. You can set up a set of functions you want to
perform automatically when your program exits by passing
function pointers to the atexit() function.
What is the stack?
The stack is where all the functions’ local (auto) variables
are created. The stack also contains some
information used to call and return from functions.
A “stack trace” is a list of which functions have been called,
based on this information. When you start using a debugger,
one of the first things you should learn is how to get a stack
trace.
The stack is very inflexible about allocating memory;
everything must be deallocated in exactly the reverse order it
was allocated in. For implementing function calls, that is all
that’s needed. Allocating memory off the stack is extremely
efficient. One of the reasons C compilers generate such good
code is their heavy use of a simple stack.
There used to be a C function that any programmer could use
for allocating memory off the stack. The
memory was automatically deallocated when the calling function
returned. This was a dangerous function to call; it’s not
available anymore.
How do you print an address?
The safest way is to use printf() (or fprintf() or sprintf())
with the %P specification. That prints a void
pointer (void*). Different compilers might print a pointer
with different formats. Your compiler will pick
a format that’s right for your environment.
If you have some other kind of pointer (not a void*) and you
want to be very safe, cast the pointer to a void*:
printf( “%Pn”, (void*) buffer );
45.When should the register modifier be used? Does it
really help?
The register modifier hints to the compiler that the
variable will be heavily used and should be kept in the CPU’s
registers, if possible, so that it can be accessed faster.
There are several restrictions on the use of the register
modifier.
First, the variable must be of a type that can be held in the
CPU’s register. This usually means a single value of a size
less than or equal to the size of an integer. Some machines
have registers that can hold floating-point numbers as well.
Second, because the variable might not be stored in memory,
its address cannot be taken with the unary & operator. An
attempt to do so is flagged as an error by the compiler. Some
additional rules affect how useful the register modifier is.
Because the number of registers is limited, and because some
registers can hold only certain types of data (such as
pointers or floating-point numbers), the number and types of
register modifiers that will actually have any effect are
dependent on what machine the
program will run on. Any additional register modifiers are
silently ignored by the compiler.
Also, in some cases, it might actually be slower to keep a
variable in a register because that register
then becomes unavailable for other purposes or because the
variable isn’t used enough to justify the overhead of loading
and storing it.
So when should the register modifier be used? The answer is
never, with most modern compilers. Early C compilers did not
keep any variables in registers unless directed to do so, and
the register modifier was a valuable addition to the language.
C compiler design has advanced to the point, however, where
the compiler will usually make better decisions than the
programmer about which variables should be stored in
registers.
In fact, many compilers actually ignore the register modifier,
which is perfectly legal, because it is only a hint and not a
directive.
46.Can a file other than a .h file be included with
#include?
The preprocessor will include whatever file you specify in
your #include statement. Therefore, if you have the line
#include <macros.inc>
in your program, the file macros.inc will be included in your
precompiled program. It is, however, unusual programming
practice to put any file that does not have a .h or .hpp
extension in an #include statement.
You should always put a .h extension on any of your C files
you are going to include. This method makes it easier for you
and others to identify which files are being used for
preprocessing purposes. For instance, someone modifying or
debugging your program might not know to look at the
macros.inc file for macro definitions. That person might try
in vain by searching all files with .h extensions and come up
empty. If your file had been named macros.h, the search would
have included the macros.h file, and the searcher would have
been able to see what macros you defined in it.
47.What is Preprocessor?
The preprocessor is used to modify your program according
to the preprocessor directives in your source code.
Preprocessor directives (such as #define) give the
preprocessor specific instructions on how to modify your
source code. The preprocessor reads in all of your include
files and the source code you are compiling and creates a
preprocessed version of your source code. This preprocessed
version has all of its macros and constant symbols replaced by
their corresponding code and value assignments. If your source
code contains any conditional preprocessor directives (such as
#if), the preprocessor evaluates the condition and modifies
your source code accordingly.
The preprocessor contains many features that are powerful to
use, such as creating macros, performing conditional
compilation, inserting predefined environment variables into
your code, and turning compiler features on and off. For the
professional programmer, in-depth knowledge of the features of
the preprocessor can be one of the keys to creating fast,
efficient programs.
48.How can you restore a redirected standard stream?
The preceding example showed how you can redirect a standard
stream from within your program. But what if later in your
program you wanted to restore the standard stream to its
original state? By using the standard C library functions
named dup() and fdopen(), you can restore a standard stream
such as stdout to its original state.
The dup() function duplicates a file handle. You can use the
dup() function to save the file handle
corresponding to the stdout standard stream. The fdopen()
function opens a stream that has been
duplicated with the dup() function.
53.What is the heap?
The heap is where malloc(), calloc(), and realloc() get
memory.
Getting memory from the heap is much slower than getting it
from the stack. On the other hand, the heap is much more
flexible than the stack. Memory can be allocated at any time
and deallocated in any order. Such memory isn’t deallocated
automatically; you have to call free().
Recursive data structures are almost always implemented with
memory from the heap. Strings often come from there too,
especially strings that could be very long at runtime. If you
can keep data in a local variable (and allocate it from the
stack), your code will run faster than if you put the data on
the heap. Sometimes you can use a better algorithm if you use
the heap—faster, or more robust, or more flexible. It’s a
tradeoff.
If memory is allocated from the heap, it’s available until the
program ends. That’s great if you remember to deallocate it
when you’re done. If you forget, it’s a problem. A “memory
leak” is some allocated memory that’s no longer needed but
isn’t deallocated. If you have a memory leak inside a loop,
you can use up all the memory on the heap and not be able to
get any more. (When that happens, the allocation functions
return a null pointer.) In some environments, if a program
doesn’t deallocate everything it allocated, memory stays
unavailable even after the program ends.
54.How do you use a pointer to a function?
The hardest part about using a pointer-to-function is
declaring it.
Consider an example. You want to create a pointer, pf, that
points to the strcmp() function.
The strcmp() function is declared in this way:
int strcmp(const char *, const char * )
To set up pf to point to the strcmp() function, you want a
declaration that looks just like the strcmp() function’s
declaration, but that has *pf rather than strcmp:
int (*pf)( const char *, const char * );
After you’ve gotten the declaration of pf, you can #include <string.h>
and assign the address of strcmp() to pf: pf = strcmp;
55.What is the purpose of realloc( )?
The function realloc(ptr,n) uses two arguments.the first
argument ptr is a pointer to a block of memory for which the
size is to be altered.The second argument n specifies the
new size.The size may be increased or decreased.If n is
greater than the old size and if sufficient space is not
available subsequent to the old region, the function realloc(
)
may create a new region and all the old data are moved to the
new region.
56.What is the purpose of main( ) function?
The function main( ) invokes other functions within it.It is
the first function to be called when the program starts
execution.
- It is the starting function
- It returns an int value to the environment that called the
program
- Recursive call is allowed for main( ) also.
- It is a user-defined function
- Program execution ends when the closing brace of the
function main( ) is reached.
- It has two arguments 1)argument count and 2) argument vector
(represents strings passed).
- Any user-defined name can also be used as parameters for
main( ) instead of argc and argv
|