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 , 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
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));
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 ina 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.
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). How do you override a defined macro?
You can use the #undef preprocessor directive to undefine (override) a previously defined macro. 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.
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.
How’s method overriding different from overloading?
When overriding, you change the method behavior for a derived class. Overloading simply involves having a method with the same name within the class. What is garbage collection?
Suppose some memory space becomes reusable because a node is released from a linked list. Hence, we want the space to be available for future use. One way to bring this about is to immediately reinsert the space into the free-storage list. However, this method may be too time-consuming for the operating system. The operating system may periodically collect all the deleted space onto the free-storage list. The technique that does this collection is called Garbage Collection. Garbage Collection usually takes place in two steps: First the Garbage Collector runs through all lists, tagging whose cells are currently in use, and then it runs through the memory, collecting all untagged space onto the free-storage list. The Garbage Collection may take place when there is only some minimum amount of space or no space at all left in the free-storage list, or when the CPU is idle and has time to do the collection. Generally speaking, the Garbage Collection is invisible to the programmer.. Can we get the remainder of a floating point division ?
Yes. Although the % operator fails to work on float numbers we can still get the remainder of floating point division by using a function fmod( ). The fmod( ) function divides the two float numbers passed to it as parameters and returns the remainder as a floating-point value. Following program shows fmod( ) function at work.#include
main( )
{
printf ( “%f”, fmod ( 5.15, 3.0 ) ) ;
}
The above code snippet would give the output as 2.150000.
What does the error “Null Pointer Assignment” mean and what causes this error?
The Null Pointer Assignment error is generated only in small and medium memory models. This error occurs in programs which attempt to change the bottom of the data segment. In Borland’s C or C++ compilers, Borland places four zero bytes at the bottom of the data segment, followed by the Borland copyright notice “Borland C++ - Copyright 1991 Borland Intl.”. In the small and medium memory models, a null pointer points to DS:0000. Thus assigning a value to the memory referenced by this pointer will overwrite the first zero byte in the data segment. At program termination, the four zeros and the copyright banner are checked. If either has been modified, then the Null Pointer Assignment error is generated. Note that the pointer may not truly be null, but may be a wild pointer that references these key areas in the data segment. What’s the difference between a null pointer, a NULL macro, the ASCII NUL character and a null string?
A null pointer is a pointer which doesn’t point anywhere. A NULL macro is used to represent the null pointer in source code. It has a value 0 associated with it. The ASCII NUL character has all its bits as 0 but doesn’t have any relationship with the null pointer. The null string is just another name for an empty string “”. What is the difference between const char *p, char const *p, and char* const p ?
‘const char *p’ and ‘char const *p’ are the same, i.e. p points to a constant character. On the other hand, ‘char* const p’ means p is a constant pointer pointing to a character which means we cannot change the pointer p but we can change the character which p is pointing to. How to get the memory size ?
Consider the following program#include
#include
main( )
{
int memsize;
memsize = biosmemory( ) ;
printf ( “RAM size = %dK\n”,memsize ) ;
return 0 ;
}
The function biosmemory uses BIOS interrupt 0×12 to return the size of memory.
How to use function strdup( ) in a program?
The string function strdup( ) copies the given string to a new location. The function uses malloc( ) function to allocate space required for the duplicated string. It takes one argument a pointer to the string to be duplicated. The total number of characters present in the given string plus one bytes get allocated for the new string. As this function uses malloc( ) to allocate memory, it is the programmer’s responsibility to deallocate the memory using free( ).#include
#include
#include
void main( )
{
char *str1, *str2 = “double”;
str1 = strdup ( str2 ) ;
printf ( “%s\n”, str1 ) ;
free ( str1 ) ;
}
Can we change the system date to some other date?
Yes, We can! The function stime( ) sets the system date to the specified date. It also sets the system time. The time and date is measured in seconds from the #include
#include
void main( )
{
time_t tm ;
int d ;
tm = time ( NULL ) ;
printf ( “The System Date : %s”, ctime ( &tm ) ) ;
printf ( “\nHow many days ahead you want to set the date : ” ) ;
scanf ( “%d”, &d ) ;
tm += ( 24L * d ) * 60L * 60L ;
stime ( &tm ) ;
printf ( “\nNow the new date is : %s”, ctime ( &tm ) ) ;
}
In this program we have used function ctime( ) in addition to function stime( ). The ctime( ) function converts time value to a 26-character long string that contains date and time
How do I write a function that takes variable number of arguments?
The following program demonstrates this.#include
#include
void main( )
{
int i = 10 ;
float f = 2.5 ;
char *str = “Hello!” ;
vfpf ( “%d %f %s\n”, i, f, str ) ;
vfpf ( “%s %s”, str, “Hi!” ) ;
}
void vfpf ( char *fmt, … )
{
va_list argptr ;
va_start ( argptr, fmt ) ;
vfprintf ( stdout, fmt, argptr ) ;
va_end ( argptr ) ;
}
Here, the function vfpf( ) has called vfprintf( ) that take variable argument lists. va_list is an array that holds information required for the macros va_start and va_end. The macros va_start and va_end provide a portable way to access the variable argument lists. va_start would set up a pointer argptr to point to the first of the variable arguments being passed to the function. The macro va_end helps the called function to perform a normal return.
Can we get the process identification number of the current program?
Yes! The macro getpid( ) gives us the process identification number of the program currently running. The process id. uniquely identifies a program. Under DOS, the getpid( ) returns the Program Segment Prefix as the process id. Following program illustrates the use of this macro.#include
#include
void main( )
{
printf ( “The process identification number of this program is %X\n”,
getpid( ) ) ;
}
No comments:
Post a Comment