Sunday, July 13, 2008
Read these C statements
1> int *a
2> int **a
3> int *a()
4> int (*a)()
5> int *a[5]
6> int (*a)[5]
7> int (*a())[5]
First one is obvious. All of us know a is a pointer to an integer.
<2> is again simple. a is a pointer to pointer to an integer
<3> Here a is a function whose return type is int pointer
<4> a is pointer to function which has no parameters and which returns an integer. Now you know how to write function pointers. Remeber to enclose the * along with function name in paranthesis.
<5> a is an array of 5 integer pointers
<6> a is pointer to an array of 5 integers. This is equivalent to a 2 dimensional array. Now do some home work. Compile a program with a function which takes a 2d array as a parameter (say
void print(int a[3][3])
with debugging enabled (as gcc prg.c -g). Start gdb and enter the function. Now ask the gdb whatis 2d array
gdb> whatis a
type int (*a)[3]
So gdb is telling you your parameter is a pointer to an array. This is one concept many of us misunderstand. Since 1d array gets converted into pointer when passed as a parameter, we think 2d array gets converted into pointer to pointer. NO, IT DOES NOT. It gets converted into a pointer to an 1d array, this pointer pointing to the first row. By incrementing the pointer, we get the second row.
<7> Here is a function which returns a 2d array. Now you will think how can a function return an array? No, the function is returning a pointer to an array, which is nothing but address of first row of the 2d array.
Let us write a function to return a matrix after doubling it and without modifying the original matrix
int (*doubleElements(int c[3][3])[3]
{
int d[3][3];
int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
d[i][j]=c[i][j]*2;
return b;
}
Please note that int d[3][3] can also be written as int (*d)[3].
Now the more difficult part is how to accept the matrix returned by this function.
int a[3][3],b[3][3];
-------
-------
b=doubleElements(a);
-------
-------
Now tell me why this wont work. b is the base address of the array and hence can not be used on LHS. So let us rewrite it as
int a[3][3], (*b)[3];
Fine we are ready to test the program.Do we get the output. NO. We get some garbage values. Why?
Look at the life span of d. This array is valid as long as the function exists. And is popped out the moment you return from function. It is destroyed and we are returning this destroyed array.
Only way to overcome this problem is declare d as a static array.
static int (*d)[3];
Now static elements are not stored in data segment and hence are not destroyed when function returns.And now our prgram works!!!
Thursday, July 3, 2008
Functions (2)
Exercise 1: Search for the file stdio.h and see the contents of the file
A function declaration as well as the header of the function must specify the name of the function, parameter list and also return type. If you do not mention the return type, c compiler assumes that the function returns an int.
float findHalf(int n)
{
return (n/2.0);
}
Now define this function after defintion of main(). Now call this function say
What do answer do you obtain? 7.5? 7? No. Answer will be zero.
findHalf(int );
You don't see change in the output. Again since you haven't mentioned return type, compiler thinks it is an int function.
float findHalf(int );
This declaration gives you the correct answer.
Ex 2: Write a program to print how many days are left for you on this earth making an assumption that you live upto 80 years. OK, ok, if you think it is too morbid, write a program to print how many days old are you.
Let us write some bit manipulation programs which Ritchie is so fond of. First write a function to find the number of 1 bits in the given int.
int numBits(unsigned int n )

Now look at this image fro http://www.oaklib.org/ which shows the ways stack frames are organised when 3 functions are being called.
Sunday, June 29, 2008
Functions In C
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
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
//copy to d2
//print d1 and d2;
cout lt<"D2 is ";
//Now change d2
//again print d1 and d2
cout<<"D2 is \n";
return 0; //successful termination of the program
deep::~deep()//destructor
//assignment operator for deep copy
int main()
//create two objects of deep class
//copy to d2
//print d1 and d2;
cout<<"D2 is ";
//Now change d2
//again print d1 and d2
cout<<"D2 is \n";
return 0;//successful termination of the program
Where are C++ objects 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
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.
Sunday, May 4, 2008
Some light moments
http://mukthabalaga.wordpress.com/category/it-junk/
THis is a piece of a joke site.
You Might Be a Programmer if...
you lust for O'Reilly books.
you know that "goto considered harmful".
you are looking for the "else" at the end of this joke.
you believe that making a wrong program worse is no sin.
every combination of three letters is a meaningful acronym for you.
when you are counting objects, you go "0,1,2,3,4,5,6,7,8,9,A,B,C,D...".
you can remember seventeen computer passwords but not your anniversary.
you are sure that the year 2000 is a leap year, and know why it is dangerous.
you start laughing hysterically when the topic of computer reliability is brought up.
you go to balance your checkbook and discover that you're doing the math in hexadecimal.
the language you are best speaking is English, but the language you are best writing is Java.
on vacation, you are reading a computer manual and turning the pages faster than everyone else who is reading John Grisham novels.