Showing posts with label Theory. Show all posts
Showing posts with label Theory. Show all posts

Sunday, August 28, 2016

Microsoft Cloud Computing Services

Overall Azure Services:
https://azure.microsoft.com/en-in/get-started/

Microsoft Azure specific Services:
https://azure.microsoft.com/en-in/documentation/articles/active-directory-whatis/
https://azure.microsoft.com/en-us/documentation/articles/key-vault-whatis/

Onedrive vs Sharepoint
http://blog.apterainc.com/bid/392491/What-s-the-Difference-between-OneDrive-and-SharePoint

Microsoft Azure Vault:
http://www.cio.com/article/2986308/cloud-security/is-byok-the-key-to-secure-cloud-computing.html

Office LockBox
http://en.share-gate.com/blog/office365-security-customer-lockbox
https://blogs.office.com/2015/04/21/announcing-customer-lockbox-for-office-365/

Cloud Computing Security
https://en.wikipedia.org/wiki/Cloud_computing_security

Encryption Algorithms:
https://en.wikipedia.org/wiki/Symmetric-key_algorithm
https://en.wikipedia.org/wiki/RSA_(cryptosystem)
https://en.wikipedia.org/wiki/Public-key_cryptography

David Malan System Design Topics

Wednesday, July 27, 2016

C++ Interview Topics/Links

C++ specific Concepts

static:
http://www.cprogramming.com/tutorial/statickeyword.html
http://quiz.geeksforgeeks.org/c-static-keyword-question-1/
http://quiz.geeksforgeeks.org/c-plus-plus/static-keyword/

friend:
http://www.cprogramming.com/tutorial/friends.html
http://www.tutorialspoint.com/cplusplus/cpp_friend_functions.htm
http://quiz.geeksforgeeks.org/c-plus-plus/friend-function-and-class/

Const:
http://www.studytonight.com/cpp/const-keyword.php

namespace:
http://www.cplusplus.com/doc/tutorial/namespaces/

virtual function:
http://stackoverflow.com/questions/2391679/why-do-we-need-virtual-functions-in-c?rq=1
http://www.studytonight.com/cpp/virtual-functions.php
http://www.programcreek.com/2011/01/a-simple-example-of-c-virtual-keyword/
http://quiz.geeksforgeeks.org/c-plus-plus/virtual-functions/

Copy Constructor:
http://www.studytonight.com/cpp/copy-constructor-in-cpp.php

Reference types in C++ vs Pointers in C:
http://www.tutorialspoint.com/cplusplus/cpp_references.htm
http://www.cprogramming.com/tutorial/references.html

Interface vs Abstract Class:
http://www.brushupmyskill.com/2016/01/differences-between-interface-and.html

Advanced C++ Topics

Smart pointers:
http://www.geeksforgeeks.org/smart-pointers-cpp/
https://dsalgointerview.wordpress.com/2014/03/11/smart-pointers/

Unique Pointers:
https://dsalgointerview.wordpress.com/2014/03/11/unique_ptr/

Move semantics and rvalue references in C++11:
http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html
http://blog.smartbear.com/c-plus-plus/c11-tutorial-introducing-the-move-constructor-and-the-move-assignment-operator/

Use of Lambdas:
http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11

C++/STL Containers:
http://www.cplusplus.com/reference/stl/

C++ 11 Features:
http://www.codeproject.com/Articles/570638/Ten-Cplusplus-Features-Every-Cplusplus-Developer
http://blog.smartbear.com/c-plus-plus/the-biggest-changes-in-c11-and-why-you-should-care/

Tuesday, June 21, 2016

Structure Concepts

Structure Declaration:
A structure declaration that is not allowed by a list of variables reserves no storage;it merely describes a template or the shape of a structure.
Structure Initialization:
A structure can be initialisedas follows
struct point maxpt={320, 200};
An automatic structure may also be initialised by assignement or by calling a function that returns a structure of the right type
Structure Nesting:
Structures can be nested as follows
struct rect{
struct point pt1;
struct point pt2;}
rect strcuture contains two point structures.
Size of a structure:
Concept:We can use the concept of Pointer Difference
struct MyStruct
{
int i;
int j;
};
int main()
{
struct MyStruct *p=0;
int size = ((char*)(p+1))-((char*)p);
printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
return 0;
}
Structures and functions:
The only legaloperations on a structure are
1.copying it or assigning to it as a unit[Passing arguments to functions and returning values from functions]
2.Taking its address with &
3.Accessing its members
structures can be passed in functions in the follwing 3 ways
1.Pass Components separately
2.Pass an entire structure
3.Pass a pointer to it

Saturday, July 14, 2012

Structure & Bit Fields

Both C and C++ allow integer members to be stored into memory spaces smaller than the compiler would ordinarily allow. These space-saving structure members are called bit fields, and their width in bits can be explicitly declared. Bit fields are used in programs that must force a data structure to correspond to a fixed hardware representation and are unlikely to be portable.
The syntax for declaring a bit field is as follows:
>>-type_specifier--+------------+--:--constant_expression--;---><
                   '-declarator-'
 
 
A bit field declaration contains a type specifier followed by an optional declarator, a colon, a constant integer expression that indicates the field width in bits, and a semicolon. A bit field declaration may not use either of the type qualifiers, const or volatile.
C The C99 standard requires the allowable data types for a bit field to include qualified and unqualified _Bool, signed int, and unsigned int. In addition, this implementation supports the following types.
  • int
  • short, signed short, unsigned short
  • char, signed char, unsigned char
  • long, signed long, unsigned long
  • long long, signed long long, unsigned long long
In all implementations, the default integer type for a bit field is unsigned.
C++ C++ extends the list of allowable types for bit fields to include any integral type or enumeration type.
In either language, when you assign a value that is out of range to a bit field, the low-order bit pattern is preserved and the appropriate bits are assigned.
Bit fields with a length of 0 must be unnamed. Unnamed bit fields cannot be referenced or initialized. A zero-width bit field can cause the next field to be aligned on the next container boundary where the container is the same size as the underlying type of the bit field.
Mac OS X Bit fields are also subject to the align compiler option. Each of the align suboptions gives a different set of alignment properties to the bit fields. For a full discussion of the align compiler option and the #pragmas affecting alignment, see XL C/C++ Compiler Reference.
The following restrictions apply to bit fields. You cannot:
  • Define an array of bit fields
  • Take the address of a bit field
  • Have a pointer to a bit field
  • Have a reference to a bit field
The following structure has three bit-field members kingdom, phylum, and genus, occupying 12, 6, and 2 bits respectively:
struct taxonomy {
     int kingdom : 12;
     int phylum : 6;
     int genus : 2;
     };
Alignment of Bit Fields
If a series of bit fields does not add up to the size of an int, padding can take place. The amount of padding is determined by the alignment characteristics of the members of the structure.
The following example demonstrates padding, and is valid for all implementations. Suppose that an int occupies 4 bytes. The example declares the identifier kitchen to be of type struct on_off:
struct on_off {
                  unsigned light : 1;
                  unsigned toaster : 1;
                  int count;            /* 4 bytes */
                  unsigned ac : 4;
                  unsigned : 4;
                  unsigned clock : 1;
                  unsigned : 0;
                  unsigned flag : 1;
                 } kitchen ;
The structure kitchen contains eight members totalling 16 bytes. The following table describes the storage that each member occupies:

Member Name Storage Occupied
light 1 bit
toaster 1 bit
(padding -- 30 bits) To the next int boundary
count The size of an int (4 bytes)
ac 4 bits
(unnamed field) 4 bits
clock 1 bit
(padding -- 23 bits) To the next int boundary (unnamed field)
flag 1 bit
(padding -- 31 bits) To the next int boundary
All references to structure fields must be fully qualified. For instance, you cannot reference the second field by toaster. You must reference this field by kitchen.toaster.
The following expression sets the light field to 1:
  kitchen.light = 1;
When you assign to a bit field a value that is out of its range, the bit pattern is preserved and the appropriate bits are assigned. The following expression sets the toaster field of the kitchen structure to 0 because only the least significant bit is assigned to the toaster field:
  kitchen.toaster = 2;
 
Reference Links:
http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/
index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03defbitf.htm
 
http://c-faq.com/struct/bitfields.html

Friday, July 13, 2012

Memory Representation of int data type in C

int may be signed or unsigned both have different memory representation.

1. Memory representation of:
unsigned int a=7;

It is 16-bit data type and all 16 bit is data bit.
Binary equivalent of 7 is: 111
for 16 bit we will add 13 zero in the left side i.e. 00000000 00000111
Since Turbo C is based on 8085 microprocessor which follow little-endian.
Here A is 00000111 and B is 00000000

Memory representation: 
Note: same memory representation will be of:
unsigned short int a=7;
2. Memory representation of:
 
int a=7 or signed int a=7;
 
It is 16 bit data type.
15 bit: data bit
1 bit: signed bit
Binary equivalent of 7 is 111
for 16 bit we will add 13 zero in the left side i.e. 00000000 00000111
Here
A is 00000111
B is 00000000


Memory representation:


Note: same memory representation will be of:



3. Memory representation of:



int a= -7 or signed int a= -7;
It is 16 bit data type.Binary equivalent of 7 is 111 for 16 bit we will add 13 zero in the left side 

i.e. 00000000 00000111 since a is negative number so it will first convert in 
the 2’s complement format before stored in the memory. 1’s Complement of a: 11111111 11111000 + 1 ______________________ 2’s Complement of a: 11111111 11111001 Memory representation

Note: same memory representation will be of:
short int a=-7 or signed short int a=-7;

Note:
Above memory representation is for TURBO C compiler. Both linux gcc and tubro c follow little endianess architecture. But size of data type in linux gcc and turbo c is not same. So memory representation may vary in gcc.

Friday, March 30, 2012

size_t concepts

`size_t' is a type suitable for representing the amount
of memory a data object requires, expressed in units of `char'.
It is an integer type (C cannot keep track of fractions of a
`char'), and it is unsigned (negative sizes make no sense).
It is the type of the result of the `sizeof' operator. It is
the type you pass to malloc() and friends to say how much
memory you want. It is the type returned by strlen() to say
how many "significant" characters are in a string.

Each implementation chooses a "real" type like `unsigned
int' or `unsigned long' (or perhaps something else) to be its
`size_t', depending on what makes the most sense. You don't
usually need to worry about what `size_t' looks like "under the
covers;" all you care about is that it is the "right" type for
representing object sizes.

The implementation "publishes" its own choice of `size_t'
in several of the Standard headers: <stdio.h>, <stdlib.h>,
and some others. If you examine one of these headers (most
implementations have some way of doing this), you are likely
to find something like

#ifndef __SIZE_T
#define __SIZE_T
typedef unsigned int size_t;
#endif

This means that on this particular implementation `size_t' is
an `unsigned int'. Other implementations make other choices.
(The preprocessor stuff -- which needn't be in exactly the form
shown here -- ensures that your program will contain only one
`typedef' for `size_t' even if it includes several of the headers
that declare it.)

General guidance: If you want to express the size of something
or the number of characters in something, you should probably use
a `size_t' value to do so. Some people also hold that an array
index is a sort of "proxy" for a size, so `size_t' should be used
for array indices as well; I see merit in the argument but confess
that I usually disregard it.

Monday, March 26, 2012

#define vs costants in C

1st Logic:
In ANSI C constants can be defined two ways: through the #define statement and through use of the const modifier. For example, the following two statement, are equivalent:
#define LENGTH 10       /* Length of the square in inches */
const int length = 10;  /* Length of the square in inches */
The const declaration is better because it is in the main part of the C language and provides more protection against mistakes.
Consider the following example:
#define SIZE 10 + 20      /* Size of both tables combined */
const int size = 10 + 20; /* Size of both tables combined */
As you've already seen, the #define statement is a problem. SIZE is a macro and always expands to 10 + 20. The const int size is an integer. It has the value 30. So while the statement:
area = SIZE * SIZE: /* Mistake */
generates the wrong number, the statement:
area = size * size: /* Works */
generates the right number. So the const declaration is less error-prone. Also, if you make a mistake in defining a const , the compiler generates an error message that points at the correct line. With a #define , the error appears when the symbol is used, not when it is defined.
Then why do we have the #define ? Because early compilers did not recognize const declarations. There is still a lot of code out there that was written for these compilers and that should be modernized.
The use of const is preferred over #define for specifying constants.

2nd logic:
One of them informs the preprocessor to do a textual substitution. The other actually declares a (constant) C variable.

A #define is either an immediate value or a macro. A constant is a variable that doesn't change in value. You can delcare a pointer to a const, but not to a #define, although a define could be a pointer (for example "#define PI1234 ((int *)0x1234)".

In C, #defines are local only, so there's no way to make a #define externally available to the linker. Instead, the #define must be included in the source code for all modules that need to access the define. A const variable can be global and accessed via other linked modules, but requires a memory access and occupies space. In assembly, global equates are possible, and linkers typically generate global equates to indicate the bounds of key points within the code, like the start and end of data and code. Global equates don't require a memory access and don't occupy any space.

Within a module, a C compiler could optimize a const as if it were a #define, if there are no pointers declared to the constant. In CPU terms, the const would become an "immediate" value. Other alternatives is that a const variable could be placed in the code area as opposed to the data area since it doesn't change. On some machines, declaring a ponter to a constant could cause an exception if you tried to modify the constant via the pointer (if the constant were placed in a read-only code section).

typedef vs #define in C

typedef:
  • Handled by the compiler itself.
  • An actual definition of a new type (some people said adding new alias).
  • typedef obeys scoping rules just like variables.
  • The type defined with a typedef is exactly like its counterpart as far as its type declaring power is concerned BUT it cannot be modified like its counterpart. For example, let’s say you define a synonim for the int type with:
typedef int MYINT
//Now you can declare an int variable either with
int a;
//or
MYINT a;
//But you cannot declare an unsigned int (using the unsigned modifier) with
unsigned MYINT a;
//although
unsigned int a;
//would be perfectly acceptable.
  • typedefs can correctly encode pointer types.
  • Some things can be done with typedef that cannot be done with define. Examples:
typedef int* int_p1;
int_p1 a, b, c;  // a, b, and c are all int pointers.

#define int_p2 int*
int_p2 a, b, c;  // only the first is a pointer!
typedef int a10[10];
a10 a, b, c; // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp // func_p is a pointer to a function that
          // takes an int and returns an int
#define:
  • Handled by the preprocessor (a program run before actual compiler).
  • Works like replacing all in your editor.
  • #DEFINES are just replacements done by the preprocessor. For example:
  1. typedef char *String_t;
  2. #define String_d char *
  3. String_t s1, s2; String_d s3, s4;
s1, s2, and s3 are all declared as char *, but s4 is declared as a char, which is probably not the intention.
  • #define stays valid until the end of the file (or until a matching undef).
  • A #define is just a macro, i.e. it will be processed/expanded by the preprocessor.

To summarize the main differences:
The #define directive can be used to define types, such as:
#define INT32 long int /* 32 bit signed integer type */
The typedef clause can be used in a similar manner.
typedef long int int32; /* 32 bit signed integer */

The typedef is preferred over the #define because is better integrated into the C language, and it can create more kinds of variable types than a mere define.

Consider the following:
#define INT_PTR int    /* Define a pointer to integer */
typedef int *int_ptr;  /* Define a pointer to an integer */
INT_PTR ptr1, ptr2;    /* This contains a subtle problem */
int_ptr ptr3, ptr4;    /* This does not */
What's the problem with the line INT_PTR ptr1, ptr2 ? The problem is that ptr2 of type integer, not a pointer to integer. If you expand this line, the problem, comes apparent:
INT_PTR ptr1, ptr2;    /* This contains a subtle problem */
int *  ptr1, ptr2;     /* This contains a subtle problem */
Problems like this can be avoided by using typedef .
When possible, use typedef instead of #define .

#define in C

Simple Define Statements
One of the uses of the #define statement is to define simple constant format is this:
#define SYMBOL value /* comment */
The SYMBOL is any valid C symbol name (by convention, #define names are all uppercase). The value can be a simple number or an expression.
Like variable declarations, a constant declaration needs a comment explains it. This comment helps create a dictionary of constants.
Some examples:
/* Max number of symbols in a procedure */
#define SYMBOL_MAX 500
/* The longest name handled by this system */
#define NAME_LENGTH 50
#define constants are declared like variables. Always put a comment describes the constant after each declaration.
Constant names are all upper-case.

Constant expressions

If the value of a #define statement is a compound expression, you can run problems. The following code looks correct, but it hides a fatal flaw.
/* Length of the object (inches) (partl=10, part2=20) */
#define LENGTH 10 + 20     /* Bad practice */
#define WIDTH 30           /* Width of table (in inches) */
/*..... */
/* Prints out an incorrect width */
printf( "The area i s %d\n" , LENGTH * WIDTH);
Expanding the printf line, you get:
printf( "The area i s %d\n" , LENGTH * WIDTH);
printf( "The area i s %d\n" , 10 + 20 * WIDTH);
printf( "The area i s %d\n" , 10 + 20 * 30);
This another example of how the C preprocessor can hide problems. Clearly LENGTH is 10 + 20, which is 30. So LENGTH is 30, right? Wrong. LENGTH literally 10 + 20 , and:
10 + 20 * 30
is vastly different from:
30 * 30
To avoid problems like this, always surround all #define expressions with parenthesis ()  ). Thus, the statement:
/* Length of the object (inches) (partl=10, part2=20) */
#define LENGTH 10 + 20       /* Bad Practice */
Becomes:
/* Length of the object (inches) (partl=10, part2=20) */
#define LENGTH (10 + 20)       /* Good Practice */
If the value of a constant is anything other than a single number, enclose it in parentheses.

Useful Links:
http://www.oualline.com/style/c06.html 

Paratmetrized and Multiline Macros in C

Paratmetrised Macros:
The #define may have arguments. For example, the following macro doubles a number:
/* Double a number */
#define DOUBLE_IT(number) (2 * (number))
Enclosing the entire macro in parenthesis avoids a lot of trouble similar to the problems with simple #define s.
Enclose parameterized macros in parentheses.
In the next example, the macro SQUARE is supposed to square a number:
/* Square a number */
#define SQUARE(X) (x * x)
/* Bad practice, no () around parameter */
The invocation of the macro:
a = SQUARE(1 + 3);
expands to:
a = (1 + 3 * 1 + 3);
which is not what was expected. If the macro is defined as:
/* Square a number */
#define SQUARE(X) ((x) * (x))
Then the expansion will be:
a = ((l + 3) * (1 + 3));
Enclose each argument to a parameterized macro in parenthesis.

Multiline Macros:
The #define statement can be used to define code as well as constants. For example:
/* Print current values of registers (for debugging) */
#define PRINT_REGS printf("Registers AX=%x BX=%x\n", AX,BX);
This is fine as long as the target of the #define is a single C statement. Problems occur when multiple statements are defined. The following example defines a macro ABORT that will print a message and exit the system. But it doesn't work when put inside an if statement.
/* Fatal error found, get out of here */
#define ABORT print("Abort\n"); exit(8);
/*.... */
if (value > LIM)
    ABORT;
problem can easily be seen when we expand the macro:
if (value > LIM)
    printf("Abort\n"); exit(8);
Properly indented, this is:
if (value > LIM)
    printf("Abort\n");
exit(8);
This is obviously not what the programmer intended. A solution is to enclose multiple statements in braces.
/* Fatal error found, get out of here */
#define ABORT { printf ( "Abort\n" ); exit(8) ; )
    /* Better, but not good */
This allows you to use the ABORT macro in an if, like this:
if (value > LIMIT)
    ABORT;
Unfortunately, it causes a syntax error when used with an else:
if (value > LIMIT)
    ABORT;
else
    do_it();
The do/while statement comes to the rescue. The statement:
do {
    printf( "Abort\n" );
    exit(8);
} while (0);
executes the body of the loop once and exits. C treats the entire do/while as a single statement, so it's legal inside a if/else set.
Therefore, properly defined, the macro is:
/* Print an error message and get out */
#define ABORT                             \
    do {                                  \
        printf( "Abort\n" );                \
        exit(8);                          \
} while (0)                      /* Note: No semicolon */
Always enclose macros that define multiple C statements in braces.
If a macro contains more than one statement, use a do/while structure to enclose the macro. (Don't forget to leave out the semicolon of the statement).
When macros grow too long, they can be split up into many lines. The preprocessor uses the backslash ( \ ) to indicate "continue on next line." The latest ABORT macro also uses this feature.
Always stack the backslashes in a column. Try and spot the missing backslash in the following two examples:
/* A broken macro */
#define ABORT                             \
    do {                                  
        printf( "Abort\n" );                \
        exit(8);                          \
} while (0)
/* Another broken macro */
#define ABORT \
    do { \
        printf( "Abort\n" ); \
        exit(8); 
} while (0)
The mistake in the first example is obvious. In the second example, the problem is hidden.
When creating multi-line macros, align the backslash continuation characters ( \ ) in a column.

Conditional Compilation in C

The preprocessor allows you conditionally to compile sections o through the use of #ifdef , #else , and #endif directives.
For example:
#ifdef DOS
#define NAME "C:\ETC\DATA"
#else /* DOS */
#define NAME "/etc/data"
#endif /* DOS */
Actually, the #else and #endif directives take no arguments. The following them is entirely a comment, but a necessary one. It serves to match #else and #endif directive with the initial #ifdef .
Note: Some strict ANSI compilers don't allow symbols after #else or #endif directives. In these cases, the comment DOS must be formally written as /* DOS */ .
Comment #else and #endif directives with the symbol used in the initial #ifdef or #endif directive.
Use conditional compilation sparingly. It easily confuse the code.
#ifdef SPECIAL
float sum(float a[])
#else /* SPECIAL */
int sum(int bits)
#endif SPECIAL
{
#ifdef SPECIAL
    float total;    /* Total so far */
#else /* SPECIAL */
    int total;      /* Total number of bits */
#endif /* SPECIAL */
    int i;          /* General index */
#ifdef SPECIAL
    total = 0.0;
#else /* SPECIAL */
     total = 0;
#endif /* SPECIAL */
#ifdef SPECIAL
    for (i = 0; a[i] ! = 0.0; ++i)
        total += ( ( b its & i ) ! = 0);
#else /* SPECIAL */
    for (i = Ox8O; i ! = 0: i >> 1)
        total += a[i];
#endif /* SPECIAL */
    return (total);
}
/*
 * A comment explaining that this
 * is bad code would be redundant
 */
The structure of this function is nearly impossible to pick out. Actually, it consists of two completely different functions merged together. There are a few lines of common code, but not many.
float sum(float a[])
{
    float total;    /* Total so far */
    int i;          /* General index */
    total = 0.0;
    for (i = 0; a[i ] ! = 0.0; ++i)
        total += ( ( b its & i ) ! = 0);
    return (total);
}
int sum(int bits)
{
    int total;      /* Total number of bits */
    int i;          /* General index */
     total = 0;
    for (i = Ox8O; i ! = 0: i >> 1)
        total += a[i];
    return (total);
}
Avoid complex conditional sections. C is difficult enough to understand without confusing the issue. Usually it is better to write two entirely separate but clearer functions.
Use conditional compilation sparingly. Don't let the conditionals obscure the code.

Where to define the control symbols

The control symbols for conditional compilation can be defined through #define statements in the code or the -D compiler option.
If the compiler option is used, the programmer must know how the program was compiled in order to understand its function. If the control symbol is defined in the code, the programmer needs no outside help. Therefore, avoid the compiler option as much as possible.
Define (or undefine) conditional compilation control symbols in the code rather than using the -D option to the compiler.
Put the #define statements for control symbols at the very front of the file. After all, they control how the rest of the program is produced.
Use the #undef statement for symbols that are not defined. This serves several functions. It tells the program that this symbol is used for conditional compilation. Also, #undef contains a comment that describes the symbol Finally, to put the symbol in, all the programmer needs to do is change the #undef to #define.
#define CHECK /* Internal data checking enabled */
#undef DEBUG /* Not the debug version of the program */
Put #define and #undef statements for compilation control symbols at the beginning of the program.

Commenting out code

Sometimes a programmer wants to get rid of a section of code. This may be because of an unimplemented feature, or some other reason. One trick is to comment it out, but this can lead to problems:
/*-------Begin commented out section ------
open_database();
update_symbol_table(); /* Add our new symbols */
close_database();
/*-------End commented out section------*/
Unless your compiler has been extended for nested comments, this code will not compile. The commented-out section ends at the line /* Add our new symbols */, not at the bottom of the example.
Conditional compilation can accomplish the same thing, with much less hassle.
#ifdef UNDEF
open_database();
update_symbol_table(); /* Add our new symbols */
close_database();
#endif /* UNDEF */
Note: This will not work if the programmer defines the symbol (However, any programmer who defines this symbol should be shot.)
Do not comment out code. Use conditional compilation ( #ifdef UNDEF ) to get rid of unwanted code.
Sometimes the programmer wants to take out a section of code for a minutes for debugging. This can be done in a similar way:
#ifdef QQQ
    erase_backups();
#endif QQQ
The symbol QQQ was chosen because it is probably not defined and is easy spot with an editor. This allows all QQQ lines to be quickly removed when the is found.
Use #ifdef QQQ to temporarily eliminate code during debugging.

#include directive in C

Include files are used to define data structures, constants, and function prototypes for items used by multiple modules. it is possible to put code in an include file, but this is rarely done.

Style for #Includes

,Most programs put the #include directives in a group just after the heading comments. That way they are all together in a known place. System includes are enclosed in <>) come first, followed by any local includes (enclosed in "" ).
Example:
/********************************************************
 *   ... heading comments ....                          *
 ********************************************************/
/* System includes */
#include <stdio.h>
#include <alloc.h>
#include <string.h>
/* Local includes */
#include "key.h"
#include "table.h"
#include "blank.h"
#include directives come just after the heading comments. Put system includes first, followed by local includes.
#include directives that use absolute file names, that is specify path and name, such as /user/sam/program/data.h and Y:\DEVELOP\PROGRAM\DEFS.H make your program non-portable. If the program is moved to another machine, even one using the same operating system, the source will have to be changed.
The solution is to never use absolute paths. The compiler can be pointed to the correct directory by using the -I option. That way you need to change only one Makefile instead of a bunch of source files.
/* Non portable */
#include "/user/sam/program/data.h"
/* Portable, compile with "-I/user/sam/program" */
#include "data.h"
Do not use absolute paths in #include directives. Let the -I compile opt

Protecting against double #Includes

Include files can contain #include directives. This means that you can easily include the same file twice. For example, suppose database.h and symbol.h both need the file defs.h . Then, putting these lines:
#include "database.h"
#include "symbol.h"
in your program brings in two copies of defs.h . Defining a structure or type twice can cause errors. So how do you avoid this problem? The solution is t conditional compilation to prevent the double include from causing trouble.
#ifndef _DEFS_H_INCLUDED_
#define _DEFS_H_INCLUDED_
And at the end, insert this line:
#endif /* _DEFS_H_INCLUDED_ */
The first time through, _DEFS_H_INCLUDED_ is not defined.
The #ifndef causes the entire body of the file to be included and _DEFS_H_INCLUDED_ to be defined. Therefore, when the file is include the #ifndef kicks in, and the entire body of the file is now #ifdef 'ed out.

Sunday, March 25, 2012

break and continue in C

The break keyword is used to terminate a loop or exit from a block. After exiting, the program control jumps to the statement after the loop or block.

The continue keyword is used to skip a current iteration and move to the next iteration.