Inline functions

Generally when a function is called, the control is transferred to that function, along with some values if necessary, and after execution, the control is transferred back to the calling function. Obviously it saves memory space but certainly increases execution time. To reduce this execution time, C++ language provides inline functions.

The syntax of declaring inline functions is:

              inline function_name(list_of_arguments)
              {
                     // Function body
              }

A function is made “inline” by using the keyword inline before the function’s return type of the function definition. Whenever we call inline function, the C++ compiler places the entire code of inline function directly inside the code of the calling function. In other words we can say that inline functions are just like preprocessor macros because the compiler substitutes the entire function body for each inline function call.

If the function code is small, straight-line or when there are relatively few calls to it then use inline function otherwise uses the normal function.
Remember that when we define the function inline, it is up to the C++ compiler whether to insert the code of inline function or not to insert. 

Introduction to C++

C++ (pronounced "see plus plus") is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features.Developed by Bjarne Stroustrup starting in 1979 at Bell Labs, it adds object oriented features, such as classes, and other enhancements to the C programming language. Originally named C with Classes, the language was renamed C++ in 1983.







In 1998, the C++ standards committee (the ISO/IEC JTC1/SC22/WG21 working group) standardized C++ and published the international standard ISO/IEC 14882:1998 (informally known as C++98). For some years after the official release of the standard, the committee processed defect reports, and published a corrected version of the C++ standard, ISO/IEC 14882:2003, in 2003. In 2005, a technical report, called the "Library Technical Report 1" (often known as TR1 for short), was released. While not an official part of the standard, it specified a number of extensions to the standard library, which were expected to be included in the next version of C++. Support for TR1 is growing in almost all currently maintained C++ compilers.

The latest major revision of the C++ standard, C++11, (formerly known as C++0x) was approved by ISO/IEC on 12 August 2011.It has been published as 14882:2011.

C++: kind of and has a relationship

If two classes are related with one another there can be two kinds of relationship between them.

  1. kind of relationship
  2. has a relationship
kind of relationship is supported by inheritance.
has a relationship is supported by composition or containership.

In Inheritance if a class Y is derived from Class X,we can say that "Class Y is a kind of  Class X". This is because class Y has all the characteristics of X, and in addition some of its own.
For this reason inheritance is often called a kind of relationship.

In has a relationship you simply create objects of your existing class inside the new class.
Example 1:
               class company
               {
               };
               class employee
               {
                        company c;
               };

Example 2:
                #include<iostream.h>
                #include<string.h>
                class carburettor
                {
                         private:
                                      char type;
                                      float cost;
                                      char mfr[20];
                         public:
                                      void setdata(char t,float c,char *m)
                                      {
                                               type=t;
                                               cost=c;
                                               strcpy(mfr,m);
                                      }
                                      void displaydata()
                                      {
                                               cout<<endl<<type<<endl<<cost<<endl<<mfr;
                                      }
                 
                }; 
                class car
                {
                       private: 
                                     char model[20];
                                     char drivetype[20];
                       public:
                                     void setdata(char *m,char *d)
                                     {
                                               strcpy(model,m);
                                               strcpy(drivetype,d);
                                     }
                                     void displaydata()
                                     {
                                              cout<<endl<<model<<endl<<drivetype;
                                     }
                                     carburettor c;   //embedded object
                };
               void main()
               {
                       car mycar;
                       mycar.c.setdata('A',6500.00,"Hund");
                       mycar.setdata("sports","4-wheel");

                       mycar.c.displaydata();
                       mycar.displaydata();
               }

C++ has much more sophisticated mechanisms for code reuse in the form of composition and inheritance.

Composition is useful when classes act like a data type.

Constructors and Destructors

Constructor:
Constructors in C++ are special member functions of a class. A Constructor is a function that initilizes the members of object.There can be any number of overloaded constructors inside a class.The Constructor is automatically called whenever an object is created or dynamically allocated using "new" operator.

If no constructor is supplied then a default one is created by the compiler without any parameters.If you supply a constructor with parameters then default will NOT be created.

Some Points about Constructor:
  • Constructors have the same name as the class.
  • Constructors do not return any values.
  • Constructors are invoked first when a class is initialized. Any initialization for the class members,memory allocations are done at the constructor.
  • Constructors are never virtual.
Ex:
       Class Sample
       {
              public:
                      Sample()
                      { 
                           ..
                      }
       };

Destructor:
Destructor s in C++ also have the same name,except that they are preceded by a '~' operator. The destructors are called when the object of a class goes out of scope.The main use of destructors is to release dynamic allocated memory.Destructors are used to free memory,release resources and to perform other cleanup.If the destructor is not declared inside a class,the compiler automatically create a default one.

If the constructor/destructor is declared as private,then the class cannot be instantiated.

Ex:
        ~Sample()

Dangling Pointer

A dangling pointer arises when you use the address of an object after its lifetime is over. This may occur in situations like returning addresses of the automatic variables from a function or using the address of the memory block after it is freed. 

The following code snippet shows this:
                     class Sample
                     {
                                public:
                                         int *ptr;
                                Sample(int i)
                                {
                                         ptr = new int(i);
                                }
                               ~Sample()
                                {
                                         delete ptr;
                                 }
                                void PrintVal()
                                 {
                                           cout << "The value is " << *ptr;
                                 }
                     };
                    void SomeFunc(Sample x)
                    {
                                cout << "Say i am in someFunc " << endl;
                    }
                    int main()
                    {
                                Sample s1 = 10;
                                SomeFunc(s1);
                                s1.PrintVal();
                     }
In the above example when PrintVal() function is called it is called by the pointer that has been freed by the destructor in SomeFunc.

Void Pointer

Void pointer or generic pointer is a special type of pointer that can be pointed to objects of any data type. A void pointer is declared like a normal pointer, using the void keyword.

Pointers defined using specific data type cannot hold the address of the some other type of variable.

You should use it when you do not know what data type the memory contains. The advantage is that once you know the data type, you may typecast the void pointer into the appropriate data type.

A good example is the "malloc" function. It returns a void* and you can typecast it to whatever type you need.
                  void *malloc(size_t size);
                  int *n = (int *) malloc(sizeof(int));
Example:  
                 void *v;
                 int *i;
                 int ivar;
                 char chvar;
                 float fvar;
                 v = &ivar; // valid
                 v = &chvar; //valid
                 v = &fvar; // valid
                 i = &ivar; //valid
                 i = &chvar; //invalid
                 i = &fvar; //invalid

OpenMax

OpenMAX (Open Media Acceleration) is a royalty-free, cross-platform set of C-language programming interfaces that provides abstractions for routines especially useful for audio, video, and still images. It's intended for devices that process large amounts of multimedia data in predictable ways.

OpenMAX provides three layers of interfaces: 

                 Application Layer (AL)
                 Integration Layer (IL) 
                 Development Layer (DL). 

OpenMAX is managed by the non-profit technology consortium Khronos Group.

1) OpenMax Al interface between Applications like Media Player and Media framework.
2) OpenMax IL interface between Media framework and Codec’s.
3) OpenMax DL interface between Codec’s and Hardware.

OpenMax IL:
The OpenMax IL (Integration Layer) API defines a standardized media component interface to enable developers and platform providers to integrate and communicate with multimedia codec’s implemented in hardware or software”.


The Open MAX IL API allows the user to load, control, connect, and unload the individual components.

OpenMax IL Features:

  • A flexible component-based API core 
  • Ability to easily plug in new codec’s 
  • Capable of being implemented as either static or dynamic libraries 
  • Ease of communication between the client and the codec’s and between codec’s themselves
OpenMax IL Use:
           Open MAX IL Components are used like any typical Multimedia features such as playing video, recording audio and capturing images. For example, two Open MAX IL Components, decoder and render, are loaded by Open MAX IL and communicate with each other for decoding and rendering.

In the OpenMax IL, components represent individual blocks of functionality. Components can be sources, sinks, codec’s, filters, splitters, mixers, or any other data operator.
  • An IL client always communicates with a component via the IL core.
  • The IL client uses the Open MAX core for loading and unloading components, setting up direct communication between two Open MAX components, and accessing the component’s method functions. 
  • IL Client: MDF (Multimedia Device Framework) plays the role of the Open MAX IL client within the Open MAX IL architecture. 
  • IL core: Open MAX IL Core is used to load and unload the Open MAX IL Components and to facilitate communication between them. Open MAX IL Core is a platform-specific entity which is used to load and unload Open MAX IL Components, and to facilitate communication between them.
OMX Components handle data communication through ports. A port is an interface that represents: the connection to other components, the type of streamed data and the buffers needed to maintain such connection. In Open MAX a buffer is an entity that holds the information and represents the minimum unit of data that can be exchanged between two OMX Components. One OMX Component sends/receives buffers to/from other OMX Components through output/input ports.

OpenMax IL Profiles:Base Profile: support non tunneled communication
Interop Profile: support non tunneled communication and tunneled communication.

Non tunneled communication: exchanging data buffers b/w IL client and component.
Tunneled communication: components to exchange data buffers directly with each other.
Proprietary Communication:Third party based

OpenMax IL Component States:
  • WAIT FOR RESOURCES 
  • IDLE 
  • EXECUTING 
  • PAUSED 
  • INVALID 
  • LOADED 
  • UNLOADED

Non Tunnel Call Sequences:
1) Non tunnel initialization:
  • IL client shall call OMX_getHandle function, which activates actual component creation by core. 
  • The core passes IL client callback functions to the component by means of the Set Callbacks. 
  • If successful, OMX will be in OMX_StateLoaded state. 
  • IL Client configures the component and its ports using OMX_SetParameters. 
  • After configuration, It can request the component to make the state transition to OMX_StateIdle. After that only client can set up the buffers to component to use all of its ports. 
  • IL Client use OMX_AllocateBuffer and OMX_UseBuffer to set up buffers. 
  • If OMX_UseBuffer is used, the IL client shall have allocated buffer and passed it to component. 
  • IL client may ask component to allocate buffer and buffer header using OMX_AllocateBuffer. 
2) Non tunnel Data Flow:
     IL Client entirely responsible for moving data buffers among components if data tunneling is not used.
  • IL Client delivers data buffers to component using OMX_EmptyThisBuffer call. 
  • As soon as one buffer is available from the component output port, component shall send OMX_FillBufferDone call back. 
3) Non tunneled De Initialization:
  • First switch the components to the OMX_StateIdle state so that all buffers are returned to their suppliers. 
  • The component to change its state to OMX_StateLoaded.                                                                    The IL client shall free all of the component’s buffers by calling OMX_FreeBuffer for each buffer.                                                                                                                            OMX_FreeBuffer : free port buffer headers 
  • When all of the buffers have been freed, the component shall complete the state transition. 
  • The IL client calls the OMX_FreeHandle function that disposes of the component.

Scope Resolution Operator in C++

In C,Suppose there are two variables with the same name 'c'.Assume that one is declared outside the function(global) and another is declared locally inside the function.
If we attempt to access variable 'c' inside the function we always access the local variable.Basic rule says that whenever there is conflict between local variable and global variable,the local variable gets the priority.

C++ allows you flexibility of accessing both the variables using scope resolution operator(::).

Example:
             #include<iostream.h>
             int x=10;
             void main()
             {
                       int x=20;
                       cout<<"First"<<x<<::x;
                       {
                             int x=30;
                             cout<<"Second"<<x<<::x;
                       }
                       cout<<"Third"<<x<<::x;
             }
             
             OutPut:
                         20  10
                         30  10
                         20  10

Structures and Unions in C++

struct sample
{
      int num;
      char str[10];
};

union data
{
      int id;
      float val;
};

Unlike C,C++ does not need the keywords struct,union while defining variables.See below
sample s1;
data d1;

Structures and unions of C++ can contain as their elements not only various data types but also functions.

C Program to count the number of vowels in a name?

#include<iostream.h> 
using namespace std;
int main() 
{
         int vow_cnt=0; 
         char name[15]; 
         cout<<"Enter a name"<<endl; 
         cin>>name; 
         for(int i=0;i<strlen(name);i++) 
         { 
                   if(name[i] == 'a' || name[i] == 'e'||name[i] == 'i'||name[i] == 'o'||name[i] == 'u') 
                   { 
                         vow_cnt++; 
                   } 
         } 
         cout<<"Total Vowels in the string are=>"<<vow_cnt<<endl; 

I/P   : jithendra 
O/P : 3

Shallow copy and Deep copy


A shallow copy of an object copies all of the member field values. This works well if the fields are values, but may not be what you want for fields that point to dynamically allocated memory. The pointer will be copied. but the memory it points to will not be copied -- the field in both the original object and the copy will then point to the same dynamically allocated memory, which is not usually what you want. The default copy constructor and assignment operator make shallow copies.

A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. To make a deep copy, you must write a copy constructor and overload the assignment operator, otherwise the copy will point to the original, with disastrous consequences.

Structures in C

Structure is user defined data type which is used to store heterogeneous data items under unique name. Keyword 'struct' is used to declare structure.

Each variable in structure is known as a structure member. A structure can contain any valid data types like int, char, float, array or even other structures.

Syntax:

        Struct <structure name>
        {
            <data type 1> <element 1>;
            <data type 2> <element 2);

             -     -           -           -
             -       -     -           -           -
            <data type n> <element n>;
        }<structure Variable>;

 Example:
        Struct sample
        {
            int num;
            float var;
            char ch;
        };

Instance of structures:
Instances of structure can be created in two ways

           1)  Struct sample
                 {
                          int num[10];
                          float var;
                 }obj;

           2)  Struct sample
                {
                         int num[10];
                        float var;
                };
               Struct sample obj;

Initializing and accessing a Structure:
Structure members can be initialized when you declare a variable of your structure:
              
               Struct sample
               {
                        char name[10];
                        float x;
                        int num;
               };
             Struct sample var={“Program”,1.4,20};

The above declaration will create a struct object called var with an name equal to “Program”, x equal to 1.4, and num equal to 20.
Structure members can be accessed using member operator '.' . It is also called as 'dot operator' or 'period operator'.


/*  Program to Explain about a structure.
Author : http://ccppcoding.blogspot.com   */
#include <stdio.h>
struct example
{
            char EmpName[10];
            int id;
};
void main()
{
            Struct sample obj;
            obj.EmpName=”King”;
            obj.id=2100;
            printf("\n\n Employee Name : %s",obj.EmpName);
            printf("\n\n ID : %d",obj.id);
}

Structures within structures(Nested Structures):
Structures can also be used inside another structure. It is also called as “nesting of structures”.

Example:
            Struct company
            {
                            char Name[10];
                            char address[20];
                            int count;
                            struct employee
                            {
                                        char EmpName[10];
                                        int EmpId;
                            }empobj;
           }compobj;

Inner structure member variables can be accessed as:
           compobj.empobj.EmpName;
           compobj.empobj.EmpId;

Static Data & Functions in C/C++

Static Data in C:

If you declare the variable as static inside the functions,that variable retain the information between calls to a function.This static data variable is stored in Data Segment of the Memory.
                   If the static variable is initialized,stored in Data Segment
                   If not,Stored in BSS(Block started by Symbol) segment.

Static variables are automatically initialized to zero upon memory allocation.Static storage class can be specified for automatic as well as external variables.

The scope of static automatic variables is identical to that of automatic variables, i.e. it is local to the block in which it is defined; however, the storage allocated becomes permanent for the duration of the program. Static variables may be initialized in their declarations; however, the initializers must be constant expressions, and initialization is done only once at compile time when memory is allocated for the static variable.

Static Arrays:
We can apply static to a local array declaration so the array is not created and initialized each time the function is called and the array is not destroyed each time the function is exited in the program.
This reduces program execution time particularly for programs with frequently called functions that contain large arrays.


    Example Program:
/* Program which sums integers, using static variables */ 
#include <stdio.h>
#define MAX 5 
void sumIt(void); 
int main() 
{
           int i =0;
           printf("Enter 5 numbers to be summed\n"); 
           for(i = 0; i<MAX; ++i) 
                   sumIt(); 
           printf("Program completed\n"); 
           getchar(); 
         return 0; 
}
void sumIt(void) 
           static int sum = 0;
           int num; 
           printf("\nEnter a number: ");  
           scanf("%d", &num); 
           sum+=num;
           printf("The current sum is: %d",sum); 
}

 
Static Arrays Example Program:  
Function staticArrayInit has a local static array and function automaticArrayInit has an automatic local array.

#include <stdio.h>
 /* Static arrays are initialized to zero */ 
void staticArrayInit( void );
void automaticArrayInit( void );
int main()
{
       printf( "First call to each function:\n" ); 
       staticArrayInit(); 
       automaticArrayInit();
       printf( "\n\nSecond call to each function:\n" );
       staticArrayInit(); 
       automaticArrayInit();
     return 0; \
/* function to demonstrate a static local array */ 
void staticArrayInit( void ) 
       static int a[ 3 ]; 
       int i; 
       printf( "\nValues on entering staticArrayInit:\n" ); 
       for ( i = 0; i <= 2; i++ )
             printf( "array1[%d] = %d ", i, a[ i ] );
             printf( "\nValues on exiting staticArrayInit:\n" );
       for ( i = 0; i <= 2; i++ ) 
             printf( "array1[%d] = %d ", i, a[ i ] += 5 ); 
/* function to demonstrate an automatic local array */ 
void automaticArrayInit( void ) 
{
       int a[ 3 ] = { 1, 2, 3 }, i; 
       printf( "\n\nValues on entering automaticArrayInit:\n" ); 
       for ( i = 0; i <= 2; i++ ) 
             printf("array1[ %d ] = %d ", i, a[ i ] ); 
             printf( "\nValues on exiting automaticArrayInit:\n" );
       for ( i = 0; i <= 2; i++ ) 
             printf( "array1[ %d ] = %d ", i, a[ i ] += 5 ); 
}

Static Data in C++:

We all knew that,each object contains its own copy of the data members,where as ,the member functions are shared amongst all objects.

If a data member of a class is declared as static,then only one copy is created for the entire class,irrespective of the number of objects created from that class.Static member is useful when all the objects of the same class must share a common item of information.Static data member is available only with in the class,but it continues to live till the time program execution doesn't come to end.

      Example Program:
#include<iostream> 
class sample 
{
        static int count; //declaration of static variable
        int index; 
        public: 
                  sample() 
                  { 
                         count++; 
                         index++;
                  } 
                  void showdata()
                  { 
                         cout<<endl<<"count="<<count;
                         cout<<endl<<"index="<<index; 
                  } 
 };
 int sample::count=0; //definition of static variable count 
void main() 
{
      sample s1,s2; 
      s1.showdata(); 
      s2.showdata(); 
}
       Output:
             count=2;
             index=-2345;
             count=2;
             index=654;

Here,static data declared inside the class and defined in outside the class.
why such an approach is used for static data members?
If static date members were defined inside the class declaration it would violate the idea that a class declaration is only a blueprint and does not set aside any memory.

Defining the static member data out side the class also emphasizes two facts.
1) The memory space for such data is allocated only once,before program starts executing.
2) There is only one static member variable for the entire class.

When would we be required to use static member data?
Imagine a situation where an object is required to know how many other objects of its class are in existence.

Static Functions in C:

Generally,normal member functions will be accessible to through out  the program.If we declare the member function as static,that function can not be accessed by out side the file,only within the file can be accessed.

Static Functions in C++:
The main usage of static function is when we want to have a function which is accessible even when the class is not instantiated.
Static member functions have a class scope,they don't have access to 'this' pointer of a class.

Static functions are accessed using only the class name and the scope resolution operator.
Static member functions can only access static data.
Static member functions can not be declared as virtual.

   Example Program:
#include<iostream> 
class sample
        static int count; 
        public: 
                  sample() 
                  { 
                         count++;
                  } 
                  static void showdata() 
                  { 
                         cout<<endl<<"count="<<count; 
                   } 
};
int sample::count=0;
void main() 
        sample s1; 
        sample::showdata(); 
        sample s2; 
        sample::showdata();
}

Interrupt Handling in Linux

What is Interrupt?

An interrupt (also known as an exception or trap) is an event that causes the CPU to stop executing the current program and start executing a special piece of code called an interrupt handler or interrupt service routine (ISR).

There are two different kinds of interrupts:

         •Synchronous interrupt (Exception) produced by the CPU while processing instructions
         •Asynchronous interrupt (Interrupt) issued by other hardware devices
Handling interrupts:
   •Interrupts can occur at any time, the kernel tries to get it out of the way as soon as possible
   •An interrupt can be interrupted by another interrupt
   •There are regions in the kernel which must not be interrupted at all

Two different interrupt levels are defined:
   •Maskable interrupts issued by I/O devices; can be in two states, masked or unmasked. Only   
     unmasked interrupts are getting processed.
   •Nonmaskable interrupts; critical malfunctions (f.e. hardware failure); always processed by the 
    CPU.

Every hardware device has it's own Interrupt Request (IRQ) line. The IRQs are numbered starting from 0. All IRQ lines are connected to a Programmable Interrupt Controller (PIC). The PIC listens on IRQs and assigns them to the CPU. It is also possible to disable a specific IRQ line.

Top Half and Bottom Half:

One of the main problems with interrupt handling is how to perform lengthy tasks within a handler. Often a substantial amount of workmust be done in response to a device interrupt, but interrupt handlers need to finish up quickly and not keep interrupts blocked for long. These two needs (work and speed) conflict with each other,leaving the driver writer in a bit of a bind.

Linux (along with many other systems) resolves this problem by splitting the interrupt handler into two halves. The so-called top half is the routine that actually responds to the interrupt—the one you register with request_irq. The bottom half is a routine that is scheduled by the top half to be executed later, at a safer time. The big difference between the top-half handler and the bottom half is that all interrupts are enabled during execution of the bottom half—that’s why it runs at a safer time.

To implement bottom halves,two methods:
1) task lets
2) work queues

Swapping in C/C++

Simple Swap Program:

#include <stdio.h>
int main() 
{
      int a = 23, b = 47;
      int t; 
      printf("Before. a: %d, b: %d\n", a, b);
      t = a;
      a = b;
      b = t;
      printf("After. a: %d, b: %d\n", a, b); return 0;

 }

Out Put:
% cc -o swap_simple0 swap_simple0.c
% swap_simple0 

Before. a: 23, b: 47 
After. a: 47, b: 23

Using Exclusive-OR

#include <stdio.h> 
int main() 
        int a = 23, b = 47;
        printf("Before. a: %d, b: %d\n", a, b); 
        a ^= b;
        b ^= a; 
        a ^= b;
        printf("After. a: %d, b: %d\n", a, b); return 0; 
}

Out Put:
% cc -o swap_simple1 swap_simple1.c 
% swap_simple1 
Before. a: 23, b: 47 
After. a: 47, b: 23

Using Preprocessor Directive:
#define swap(type, i, j) {type t = i; i = j; j = t;} 
int main() 
{
       int a = 23, b = 47; 
       printf("Before swap. a: %d, b: %d\n", a, b);
       swap(int, a, b)
       printf("After swap. a: %d, b: %d\n", a, b); return 0;
}

Out Put:
% cc -o swap_p swap_p.c 
% swap_p 
Before swap: a: 23, b: 47 
After swap: a: 47, b: 23


                                                Swap Program with Functions
#include <stdio.h>
void swap(int *i, int *j) 
{
      int t = *i; 
      *i = *j; 
      *j = t; 
}
void main() 
{
       int a = 23, b = 47; 
       printf("Before. a: %d, b: %d\n", a, b); 
       swap(&a, &b);
       printf("After . a: %d, b: %d\n", a, b); 
}

Out Put:
% cc -o swap1 swap1.c
% swap1 
Before. a: 23, b: 47 
After. a: 47, b: 23



C++: Swap Program Using References:
#include <iostream> 
using std::cout;
void swap(int& i, int& j) 
       int t = i;
       i = j;
       j = t; 
}
int main() 
       int a = 23, b = 47; 
       cout << "Before. a: " << a << ", b: " << b << "\n"; 
       swap(a, b); 
       cout << "After. a: " << a << ", b: " << b << "\n"; 
  return 0; 
}

Out Put:
% CC -o swap_CC swap.cpp 
% swap_CC
Before: a: 23, b: 47 
After: a: 47, b: 23

How do I call a C function from C++?

Just declare the C function ``extern "C"'' (in your C++ code) and call it (from your C or C++ code). For example: // C++ code

        extern "C" void f(int); // one way
        extern "C" { // another way
            int g(double);
           double h();
        };
        void code(int i, double d)
        {
              f(i);
              int ii = g(d);
             double dd = h();
             // ...
        }
The definitions of the functions may look like this: /* C code: */
        void f(int i)
        {
              /* ... */
        }
        int g(double d)
       {
             /* ... */
       }
       double h()
      {
            /* ... */
      }
Note that C++ type rules, not C rules, are used. So you can't call function declared ``extern "C"'' with the wrong number of argument. For example: // C++ code
        void more_code(int i, double d)
        {
               double dd = h(i,d); // error: unexpected arguments
               // ...
       }

Why does declaring double x[500000] cause my program to crash?

Because such a large piece of memory exceeds the stack size (a stack overflow). You need to allocate the memory on the heap instead:
code:
double *x = new double[500000];

Don't forget to delete the memory (with delete[]) after you are finished with it to avoid memory leaks.

C Objectives

1) Why does this code: char *p = "hello, world!";
      p[0] = 'H';
       crash?

Explanation:
String constants are in fact constant. The compiler may place them in nonwritable storage, and it is therefore not safe to modify them. When you need writable strings, you must allocate writable memory for them, either by declaring an array, or by calling malloc. Try
char a[] = "hello, world!";


2) Why is this loop always executing once? 
     for(i = start; i < end; i++);
    {
            printf("%d\n", i);
    }

Explanation:
The accidental extra semicolon hiding at the end of the line containing the for constitutes a null statement which is, as far as the compiler is concerned, the loop body. The following brace-enclosed block, which you thought (and the indentation suggests) was a loop body, is actually the next statement, and it is traversed exactly once, regardless of the number of loop iterations.


3) What is the output?
    main()
    {
            static int var = 5;
            printf("%d ",var--);
            if(var)
                        main();
    }
   Answer:
    5 4 3 2 1
   
    Explanation:  
    When static storage class is given, it is initialized once. The change in the value of a static   
    variable is retained even between the function calls. Main is also treated like any other 
    ordinary function, which can be called recursively. 

4) What is the out put?
    main()
   {
            char *p;
            printf("%d %d ",sizeof(*p),sizeof(p));
   }

  Answer:
  1 2

  Explanation:
  The sizeof() operator gives the number of bytes taken by its operand. P is a character pointer, 
  which needs one byte for storing its value (a character). Hence sizeof(*p) gives a value of 1. 
  Since it needs two bytes to store the address of the character pointer sizeof(p) gives 2.