What is a pragma?
The #pragma preprocessor directive allows each compiler to implement compiler-specific features that can be turned on and off with the #pragma statement. For instance, your compiler might support a feature called loop optimization. This feature can be invoked as a command-line option or as a #pragma directive.
To implement this option using the #pragma directive, you would put the following line into your code:
Conversely, you can turn off loop optimization by inserting the following line into your code:
What is #line used for?
The #line preprocessor directive is used to reset the values of the _ _LINE_ _ and _ _FILE_ _ symbols, respectively. This directive is commonly used in fourth-generation languages that generate C language source files.
What is the difference between text and binary modes?
Streams can be classified into two types: text streams and binary streams. Text streams are interpreted, with a maximum length of 255 characters. With text streams, carriage return/line feed combinations are translated to the newline n character and vice versa. Binary streams are uninterpreted and are treated one byte at a time with no translation of characters. Typically, a text stream would be used for reading and writing standard text files, printing output to the screen or printer, or receiving input from the keyboard.
A binary text stream would typically be used for reading and writing binary files such as graphics or word processing documents, reading mouse input, or reading and writing to the modem.
How do you determine whether to use a stream function or a low-level function?
Stream functions such as fread() and fwrite() are buffered and are more efficient when reading and writing text or binary data to files. You generally gain better performance by using stream functions rather than their unbuffered low-level counterparts such as read() and write().
In multi-user environments, however, when files are typically shared and portions of files are continuously being locked, read from, written to, and unlocked, the stream functions do not perform as well as the low-level functions. This is because it is hard to buffer a shared file whose contents are constantly changing. Generally, you should always use buffered stream functions when accessing nonshared files, and you should always use the low-level functions when accessing shared files
What is static memory allocation and dynamic memory allocation?
Static memory allocation: The compiler allocates the required memory space for a declared variable.By using the address of operator,the reserved address is obtained and this address may be assigned to a pointer variable.Since most of the declared variable have static memory,this way of assigning pointer value to a pointer variable is known as static memory allocation. memory is assigned during compilation time.
Dynamic memory allocation: It uses functions such as malloc( ) or calloc( ) to get memory dynamically.If these functions are used to get memory dynamically and the values returned by these functions are assingned to pointer variables, such assignments are known as dynamic memory allocation.memory is assined during run time.
When should a far pointer be used?
Sometimes you can get away with using a small memory model in most of a given program. There might be just a few things that don’t fit in your small data and code segments. When that happens, you can use explicit far pointers and function declarations to get at the rest of memory. A far function can be outside the 64KB segment most functions are shoehorned into for a small-code model. (Often, libraries are declared explicitly far, so they’ll work no matter what code model the program uses.) A far pointer can refer to information outside the 64KB data segment. Typically, such pointers are used with farmalloc() and such, to manage a heap separate from where all the rest of the data lives. If you use a small-data, large-code model, you should explicitly make your function pointers far.
What is the difference between far and near?
Some compilers for PC compatibles use two types of pointers. near pointers are 16 bits long and can address a 64KB range. far pointers are 32 bits long and can address a 1MB range.
Near pointers operate within a 64KB segment. There’s one segment for function addresses and one segment for data. far pointers have a 16-bit base (the segment address) and a 16-bit offset. The base is multiplied by 16, so a far pointer is effectively 20 bits long. Before you compile your code, you must tell the compiler which memory model to use. If you use a smallcode memory model, near pointers are used by default for function addresses.
That means that all the functions need to fit in one 64KB segment. With a large-code model, the default is to use far function addresses. You’ll get near pointers with a small data model, and far pointers with a large data model. These are just the defaults; you can declare variables and functions as explicitly near or far.
far pointers are a little slower. Whenever one is used, the code or data segment register needs to be swapped out. far pointers also have odd semantics for arithmetic and comparison. For example, the two far pointers in the preceding example point to the same address, but they would compare as different! If your program fits in a small-data, small-code memory model, your life will be easier.
When would you use a pointer to a function?
Pointers to functions are interesting when you pass them to other functions. A function that takes function pointers says, in effect, Part of what I do can be customized. Give me a pointer to a function, and I’ll call it when that part of the job needs to be done. That function can do its part for me. This is known as a callback. It’s used a lot in graphical user interface libraries, in which the style of a display is built into the library but the contents of the display are part of the application.
As a simpler example, say you have an array of character pointers (char*s), and you want to sort it by the value of the strings the character pointers point to. The standard qsort() function uses function pointers to perform that task. qsort() takes four arguments,
- a pointer to the beginning of the array,
- the number of elements in the array,
- the size of each array element, and
- a comparison function, and returns an int.
How are pointer variables initialized?
Pointer variable are initialized by one of the following two ways
- Static memory allocation
- Dynamic memory allocation
How can you avoid including a header more than once?
One easy technique to avoid multiple inclusions of the same header is to use the #ifndef and #define
preprocessor directives. When you create a header for your program, you can #define a symbolic name that is unique to that header. You can use the conditional preprocessor directive named #ifndef to check whether that symbolic name has already been assigned. If it is assigned, you should not include the header, because it has already been preprocessed. If it is not defined, you should define it to avoid any further inclusions of the header. The following header illustrates this technique:
#define VER_NUM 1.00.00
#define REL_DATE 08/01/94
#if _ _WINDOWS_ _
#define OS_VER WINDOWS
#define OS_VER DOS
When the preprocessor encounters this header, it first checks to see whether _FILENAME_H has been defined. If it hasn’t been defined, the header has not been included yet, and the _FILENAME_H symbolic name is defined. Then, the rest of the header is parsed until the last #endif is encountered, signaling the end of the conditional #ifndef _FILENAME_H statement. Substitute the actual name of the header file for FILENAME in the preceding example to make it applicable for your programs.
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.