Saturday, December 5, 2009

Complicated Declaration


int *p[10];

This is an array of pointers

int (*p)[10];

This is a pointer to a 10 element array



C code to dynamically allocate one, two and three dimensional arrays (using malloc())

One Dimensional Array
int *myarray = malloc(no_of_elements * sizeof(int));

//Access elements as myarray[i]

2 Dimensional Array
Method1
int **myarray = (int **)malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
{
 myarray[i] = malloc(ncolumns * sizeof(int));
//allocating 1 D array = number of elements in column
}

// Access elements as myarray[i][j]

Method 2 (Contagious Allocation)
int **myarray = (int **)malloc(nrows * sizeof(int *));
myarray[0] = malloc(nrows * ncolumns * sizeof(int));

for(i = 1; i < no_of_rows; i++)
  myarray[i] = myarray[0] + (i * ncolumns);

// Access elements as myarray[i][j]

In either case, the elements of the dynamic array can be accessed with normal-looking array subscripts: array[i][j]. 

Method 3
int *myarray = malloc(nrows * ncolumns * sizeof(int));

// Access elements using myarray[i * ncolumns + j].
i.e. you must now perform subscript calculations manually, accessing the i,jth element with array3[i * ncolumns + j].  (A macro can hide the explicit calculation, but invoking it then requires parentheses and commas which don't look exactly like multidimensional array subscripts.) 

Method4
Finally, you can use pointers-to-arrays:
 int (*array4)[NCOLUMNS] =
(int (*)[NCOLUMNS])malloc(nrows * sizeof(*array4));
, but the syntax gets horrific and all but one dimension must be known at compile time.
Three Dimensional Array

#define MAXX 3
#define MAXY 4
#define MAXZ 5

main()
{
    int ***p,i,j;
    
p=(int ***) malloc(MAXX * sizeof(int ***));

    for(i=0;i
    {
        p[i]=(int **)malloc(MAXY * sizeof(int *));
        for(j=0;j
            p[i][j]=(int *)malloc(MAXZ * sizeof(int));
//allocating 1D array of size = size of last dimensional...So we have to allocate
//n1*n2 such arrays...where n1 and n2 are 2 such dimensional.
    }
     
    for(k=0;k
        for(i=0;i
            for(j=0;j
                p[i][j][k]=;

}

GCD of 2 integers

#include 

int gcd(int a, int b);
int gcd_recurse(int a, int b);



int main()
{
  printf("\nGCD(%2d,%2d) = [%d]", 6,4,  gcd(6,4));



 printf("\nGCD(%2d,%2d) = [%d]", 6,4,  gcd_recurse(6,4));
  return(0);
}

// Iterative algorithm
int gcd(int a, int b)
{
   int temp;
  
   while(b)
   {
      temp = a % b;
      a = b;
      b = temp;
   }

   return(a);
}


// Recursive algorithm
int gcd_recurse(int a, int b)
{
   int temp;

   temp = a % b;

   if (temp == 0)
   {
      return(b);
   }
   else
   {
      return(gcd_recurse(b, temp));
   }
}

Given an array of n integers from 1 to n with one integer repeated

#include
#include
#include

int i,j=0,k,a1[10];

main()
{
     printf("Enter the array of numbers between 1 and 100(you can repeat the numbers):");
     for(i=0;i<=9;i++)
     {
         scanf("%d",&a1[i]);
     }
    
     while(j<10)
     {
        for(k=0;k<10;k++)
        {
            if(a1[j]==a1[k] && j!=k)
            {
                printf("Duplicate found!");
                printf("The duplicate is %d\n",a1[j]);
                getch();
            }
        }
        j=j+1;
    }
   
    getch();
    return(0);
}

What are the common causes of pointer bugs?

What is a dangling pointer? What are reference counters with respect to pointers?

A pointer which points to an object that no longer exists. Its a pointer referring to an area of memory that has been deallocated. Dereferencing such a pointer usually produces garbage.

Using reference counters which keep track of how many pointers are pointing to this memory location can prevent such issues. The reference counts are incremented when a new pointer starts to point to the memory location and decremented when they no longer need to point to that memory. When the reference count reaches zero, the memory can be safely freed. Also, once freed, the corresponding pointer must be set to NULL. 

Friday, December 4, 2009

To add two long positive numbers (each represented by linked lists in C)

node *long_add(mynode *h1, mynode *h2, mynode *h3)    //h3 = h2+h1
{
  node *c, *c1, *c2;
  int sum, carry, digit;

  carry = 0;
  c1 = h1->next;
  c2 = h2->next;

  while(c1 != h1 && c2 != h2)
  {
     sum   = c1->value + c2->value + carry;
     digit = sum % 10;
     carry = sum / 10;

     h3 = insertNode(digit, h3);

     c1 = c1->next;
     c2 = c2->next;
  }

  if(c1 != h1)
  {
     c = c1;
     h = h1;
  }
  else
  {
     c = c2;
     h = h2;
  }

  while(c != h)
  {
    sum   = c->value + carry;
    digit = sum % 10;
    carry = sum / 10;
    h3 = insertNode(digit, h3);
    c = c->next;
  }

  if(carry==1)
  {
     h3 = insertNode(carry, h3);
  }

  return(h3);
}