Sunday, June 29, 2008

Functions In C

C family of languages are procedure oriented languages. You split your work into functions and these functions call other functions and get the work done. A function is like a miniprogram, with its own set of variables, statements (instructions). In addition, a function will take some parameters and returns a values.

Another feature of C functions are, they are a self contained blocks. All variables defined inside the functions are local to the function. Even the parameters sent by caller are sent as copies without affecting the original values.

C does not distinguish between procedures and functions like Pascal. If a function is meant to execute statements and not return an answer, it is supposed to return void. Note here that void is also a data type. But you can have only void functions and pointers but not have void variables.

A C function can return only one value. This return value can be any built in or extended data type except for an array. A FUNCTION CAN NOT RETURN AN ARRAY. NOR CAN IT RETURN ANOTHER FUNCTION. If there is a need to return an array, then the function can be made to return a pointer because of similarities between array and pointer.

C functions are isolated from each other. A function can not use variables defined in other functions. It can only use local variables or so called global variables which are variable defined outside of all functions.

In order to use a function, three steps are needed. 1> Declare a function 2> Define a function 3> Invoke a function. Declaration is like a variable declaration. It tells the type of function (ie type of its return value) and type and number of its parameters. Function declaration is function header with a semicolon.

If a function is not declared, it is assumed to be a function which can take any number of parameters and which returns an int. Note int not void. Hence many students have the practice of writing main() instead of int main(). But that is OK when compared to the blunder of writing void main(). Never write void main(). main function returns an integer which is the exit status of the program.

A function can call itself. Then it becomes a recursive function. These recursive functions are useful for solving some algorithms. But if a recursive call is the last statement of a function, then it is tail end recursion which should be avoided. As a rule of thumb, you should use recursion only when iterative solution is too compicated.

A function creates a stack frame when it is invoked. This frame will store all local variables, parameters etc. When the function is returned, the stack frame is removed. This is an advantage, as the variable take up memory only when they are in use. But it will not be possible to remember the previous value of local variable. For that you must use a static variable.

Every C program has a special function called main(). This function is the starting point of the program for hosted environments. Other functions do get executed when they are called by main directly or indirectly.

main() can accept parameters in the form of command line arguemnts. These are a series of strings supplied with the exec file name. They will be stored in array of strings normally called argv (argument vector) and their count will be stored in argc.

An array gets passed to the function as call by address method unlike other types of parameters which are passed as copies (ie call by value). If the function modifies array parameter in the function, the actual parameter array also gets modified (For any other type of parameter, this does not happen). The reason for this is, the function treats array parameter as a pointer to first element of the array and manipulates the array using this pointer.

Note that in any expression (except for sizeof operator) which uses an array, the array gets converted into pointer.

Tuesday, June 3, 2008

Deep copy and shallow copy

If an object contains dynamically allocated data members then Shallow copy just copies the pointers of these. So the copied object and original object point to the same value.
Deep copy will allocate memory for these members then copy the contents not the pointers.
Point to note here is Compiler provided assignment operator as well as copy constructor will perform shallow copy.
This article clearly explains the difference between deep and shallow copying of objects.

http://www.fredosaurus.com/notes-cpp/oop-condestructors/shallowdeepcopy.html



Now for an example

#include

using std::cin;

using std::cout;

using std::endl;
//class definition

class deep

{

public:

int *m;//this has to be dynamically allocated

void print();

};


void deep::print()

{

cout<<"The number is "<<*m<< endl;<>
}


int main()

{
//create two objects of deep class

deep d1,d2;

d1.m = new int;

*(d1.m)=15;
//copy to d2

d2=d1;
//print d1 and d2;

cout<<"D1 is ";

d1.print();
cout lt<"D2 is ";

d2.print();
//Now change d2

*(d2.m)=75;
//again print d1 and d2

cout <<"After modifying d2 ======\n";

cout<<"D1 is \n";

d1.print();
cout<<"D2 is \n";

d2.print();
return 0; //successful termination of the program

}



And here is the output of the program

D1 is

The number is 15

D2 is

The number is 15

After modifying d2 ======

D1 is

The number is 75

D2 is

The number is 75

Press any key to continue



As you can see, modifying d2 modifies d1 as well because d1.m and d2.m are pointing at the same integer. This is shallow copy

Here you should not the point that compiler provided assignment operator does shallow copying.


Now let us provide deep copying.
class deep
{
public:
int *m;//this has to be dynamically allocated
void print();
deep& operator =(deep& d1);
~deep();
deep();
};
deep::deep()
{
m = new int;
}
deep::~deep()//destructor
{
delete m;
}
void deep::print()
{
cout<<"The number is "<<*m<<endl;
}
//assignment operator for deep copy
deep& deep::operator =(deep& d1)
{
if (&d1== this)//check for self assignment
return *this;
else
{
delete m;
m = new int;
*m = *(d1.m);
}
return *this;
}
int main()
{
//create two objects of deep class
deep d1,d2;
*(d1.m)=15;
//copy to d2
d2=d1;
//print d1 and d2;
cout<<"D1 is ";
d1.print();
cout<<"D2 is ";
d2.print();
//Now change d2
*(d2.m)=75;
//again print d1 and d2
cout<<"After modifying d2 ======\n";
cout<<"D1 is \n";
d1.print();
cout<<"D2 is \n";
d2.print();
return 0;//successful termination of the program
}
Look at the overloaded assignment operator. This will newly allocate memory for m after releasing the previous allocation and then copy the content of d1.m . if statement is meant for checking self assignment which could be hazardous.
The output of the program is
D1 is
The number is 15
D2 is
The number is 15
After modifying d2 ======
D1 isThe number is 15
D2 is
The number is 75
Press any key to continue

Where are C++ objects stored?

Question : In which memory a class gets stored?


Answer : A class is nothing but data type description. Which is present in the code. So I don't think the class will have any memory allocated to it.
As far as object is concerned, the object will be stored in stack if it is a local object, in heap if it is dynamic object and in data segment if it is a static object.
How are the methods i.e. function members of the object stored. They are NOT stored as objects have pointers to actual function. In fact there is a single function per class in the code segment. In that situation how does the function access the data members of the object. This is achieved with a special pointer this which gets passed to the function.
A static member function is special because it does not get this pointer. So it CAN NOT access the non-static data of the object.
And a virtual function is handled in another way. Here every object which has atleast one virtual function will have a special pointer vptr which points to vtbl a per class table which holds the address of all virtual functions.
Read a better description of all this in
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=195

Monday, June 2, 2008

Sequence point

The question was
What will be the output of the following program in UNIX OS with CC compiler and TC compiler?
int main()
{int i=5;
printf("\n%d",++i + ++i + ++i + ++i + ++i );
}
If any difference then Why it is difference?

The answer is the program is wrong. Unfortunately the program will compile and run and show some result.

According to C standard you can not modify the variable more than once in between two sequence points. Here you are modifying the variable i 5 times. Please note that + addition operation is not a sequence point. Only logical operator && and and the complete expression and function call are sequence points.

At a sequence point, all variable updates and side-effects since the previous sequence point are guaranteed to have taken place.

Read more about sequence points here.

http://c-faq.com/expr/seqpoints.html

and here http://en.wikipedia.org/wiki/Sequence_point . There is one more link to "THe C book" But currently i am unable to open it.