Search

Sponsored Links

Meta

Categories

Archives

Recent Posts

RSS Feeds

28
Feb

Circular Doubly Linked List With Out Using Special Head or Tail Node

Circular double linked list can be traversed clockwise or anticlockwise. In this list all nodes are linked as shown in the below figure. The only difference between double linked list and circular double linked list is last node points to first node in the list, first node points to last node instead of pointing to NULLs.

 

circular double linked list

here is the c structure for a node in a circular double linked list and it is same as double linked list.

struct Node
{
  void* info; //data
  Node* next; //used to point to next node
  Node* prev; //used to point to previous node 
};

and in this implementation as well (earlier post double linked list also doen’t maintain special nodes), we are not using any special nodes(head or tail), so while operating on the list one must be careful to maintain logical head or tail according to the need.

here is the code for inserting, deleting nodes

//insert before a known node and return the inserted node
Node *insertbefore(Node *before, void *data)
{
  Node* n;
  n = (Node *) malloc (sizeof(Node));
  n->info = data;
 
  //incase header node is not created
  if (!before)
  {
    n->prev = n;
    n->next = n;
    return n;
  }
 
  n->prev = before->prev;
  n->next = before;
  before->prev->next = n;
  before->prev = n;
 
  return n;
}
 
//insert after a known node and return the inserted node
Node *insertafter(Node *after, void *data)
{
  Node* n;
  n = (Node *) malloc (sizeof(Node));
  n->info = data;
 
  //incase header node is not created
  if (!after)
  {
    n->prev = n;
    n->next = n;
    return n;
  }
 
  n->prev = after;
  n->next = after->next;
  if (after->prev) /*just to take care when list is broken*/
  {
    after->next->prev = n;
  }
  after->next = n;
 
  return n;
}
 
//delete before a known node and return the node before deleted node
Node *deletebefore(Node *before)
{
  Node* tmp;
 
  tmp = before->prev;
  before->prev = tmp->prev;
  if (tmp->prev) /*just to take care when list is broken*/
  {
    tmp->prev->next = before;
  }
  free(tmp);
 
  return before->prev;
}
 
//delete after a known node and return the node after deleted node
Node *deleteafter(Node *after)
{
  Node* tmp;
 
  tmp = after->next;
 
  after->next = tmp->next;
  tmp->next->prev = after;
  free(tmp);
 
  return after->next;
 
}
 
//given any node in list, deletes entire double linked list
int deletelist(Node *n)
{
  void *taddr = n;
  Node *tmp;
  Node* after = n;
  Node* before = n->prev;
 
  //delete all nodes after n (if any)
  do
  {
    tmp = after->next;
    free(after);
    after = tmp;
  }while (after && (taddr != after));
 
  return 0;
}

the below routine prints circular linked list, we can give any node in the list as a starting point

//given any node in list, prints entire list
int printlist(Node *h)
{
  Node* t = h;
 
  do
  {
    printf(" %d <->", t->info);
    t = t->next;
  }while(t && (t != h));
 
  printf(" NULL\n");
  return 0;
}

searching a circular double linked list not different from double linked list just the difference is sentinels (nodes whose addresses are NULL) are not present in circular double linked list unless it is broken.

//given any node in list, search entire list
Node *searchlist(Node *h, void *info)
{
  Node* after = h;
 
  //search all nodes after n (if any)
  do
  {
    if (after->info == info)
    {
      return after;
    }
    after = after->next;
  }while(after && (after != h));
 
 
  return NULL;
}

detecting a broken link in circular double linked list…

int detectlist(Node *n)
{
  int brokenlinks = 0;
  Node *tmp = n;
  Node* after = n->next;
  Node* before = n->prev;
 
  //detect abnormalities in the list (broken links) after n (if any)
  do
  {
    if ((after->prev != tmp) || (tmp->next != after))
    {
      brokenlinks++;
    }
 
    after = after->next;
    tmp = tmp->next;
  }while(after && tmp && (after != n->next) && (tmp != n));
 
  return brokenlinks;
}

download the above program [circular double linked list.c

let me know your comments and suggestions…

Popularity: 73%

27
Feb

Composition Over Inheritance

Several Patterns books will always say that composition is preferred over inheritance, because it makes your code more reusable, and more flexible. Let’s see a usual example of this in C++, using pointers or references:

class my_object {
private:
  other_object * _p;
public:
  explicit my_object (other_object * p) : _p(p) { };
 
  void do_something() { _p->do_something() };
};

This allows the user to define the functionality of my_object’s do_something method during runtime by passing in a pointer to an object that’s of type other_object or an object that derives from (or inherits from) other_object.

Sounds like a disaster because in C and C++, you can cast a pointer to anything into a pointer of another type. Let’s see how someone might be able to try doing this:

int b;
my_object a((other_object *)&b);

Disaster! And not to mention, bad coding style… We can go about it by using a reference instead of a pointer to avoid this abuse:

 
class my_object {
private:
  other_object & _r;
public:
  explicit my_object (other_object & r) : _r(r) { };
  void do_something () { _r.do_something() };
};

This is still dangerous because someone can actually do something like this:

 
int b;
other_object * p = (other_object *) &b;
my_object ( *p );

Which will compile. What we want really, is to enforce that the implementation of do_something is passed on to a concrete implementation that actually *does something* (pardon the pun). How do we achieve that to prevent mis-use? We use templates:

 
template <typename>
class my_object {
private:
  do_trait _r;
public:
  explicit my_object ( ) : _r() { };
  void do_something () { _r.do_something() };
};

NOW, with this, the code will only compile if and only if the type defined for do_trait has a default constructor, and a method that implements do_something(). We then restrict the use of the object during compile time, such that we don’t need to pass the implementation during runtime — which is usually where the problems occur.

The only way we can use the object then, is to provide a conforming type for do_trait when we want an instance of my_object that has a do_something that behaves accordingly.

A sample of the use of the class above, is the following:

my_object<other_object> a;
my_object<my_other_object> b;

We can even make it a bit funkier this way:

 
struct my_object {
};
 
template <typename>
class my_object_templ : my_object {
 private:
   do_trait _r;
 public:
   explicit my_object_templ ( ) : _r() { };
   void do_something () { _r.do_something() };
};
 
//... somewhere in the code...
std::auto_ptr<my_object> a(new my_object_templ<other_type>() );
a.reset(new my_object_templ<my_other_type>() );

But then this still leads us to the same problems as before — though now, we have a re-usable composite implementation, which has a common interface to do_something(). That way, we can re-use this implementation wherever we might need a place where an object implements a do_something() method.

Makes sense? Questions and comments welcome. :)
by Dean Michael

creative commonsThis work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.

Popularity: 6%

26
Feb

A Simple Timer…

I got inspired by an officemate’s suggestion (thanks sir Chie) to make a tool which allowed you to invoke a command and have it timed to the second. This is because we needed a tool which would run a script in a predetermined number of seconds, and cron was too clumsy to use. So with his idea, I came up with a piece of software (under the GPL) which allowed you to invoke any application (or command) every N number of seconds.

The application was pretty simple, but I am posting the code here for the general public to look at and use for their own purpose. (This application is under the GPL, and if you’re interested in using the application or getting the actual sources, email me to get the package.

I am still applying for space on sourceforge (or some other hosting maybe here in the Philippines for it). Enjoy!

/* timer — a timed command invocation tool. Copyright (C) 2005 Dean Michael C. Berris, et al This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
 
#define VERSION 0.1
 
void gnu_info() 
{        
  std::cerr << "timer version " << VERSION << ", Copyright (C) 2005 Dean Michael C. Berris et al\n";
  std::cerr << "timer comes with ABSOLUTELY NO WARRANTY; for details readthe file `COPYING'.\n";
  std::cerr << "This is free software, and you are welcome to redistribute it\nunder certain conditions; refer to `COPYING' for details.\n\n";
}
 
void usage(char * argv[]) 
{        
  std::cerr << "usage: " << argv[0] << " (time in seconds) (app to run)\n";
}
 
int main(int argc, char * argv[]) {        
  // run the argv[2] command every arv[1] seconds        
  gnu_info();        
  if (argc < 3) 
  {                
    usage(argv);                
    return (-1);        
  }        
  long time = strtol(argv[1], NULL, 10);        
  pid_t pid;        
  int status;        
  std::string command = argv[2];        
  for (register int i = 3; i < argc; i++) 
  {                
    command.push_back(' ');                
    command.append(argv[i]);        
  }        
  while (1) 
  {                
    pid = fork();                
    if (pid == 0) 
    { 
      // child                        
      int ret = system(command.c_str());                        
      exit(ret);                
    } 
    else 
    {                       
      sleep(time);                        
      wait(&status); 
      //wait for the child to die                
    }        
  }        
  return (0);
}

Comments and optimizations welcome.

by Dean Michael

download the above source code

creative commonsThis work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.

Popularity: 3%

22
Feb

Can we use printf() in an ISR?

No we cannot use printf() in ISR because ISRs’ are a part of kernel and kernel is not linked with libaray provided by C,so when we use printf() in ISR it should generate a linkage error.

Popularity: 4%

20
Feb

Palindrome Checker

Palindrome checker takes input from a file or keyboard, and lists out all palindrome words. This checker identifies even multiple words which are palindrome. This is a console based program, without arguments to the program, will act as a console shell, which takes input from keyboard and processes the words.

Recursive string reversal function is used to reverse the strings while checking for palindrome. Here is the function which identify whether a string is palindrome or not.

 

boolean checking_str_palindrome(const char *str)
{
  int pal_flag = FALSE;
  char *dest_str = (char *) malloc(sizeof(char) * (strlen(str) + 1));
 
  if (dest_str == NULL)
  {
    /*we are out of memory*/
    return FALSE;
  }
 
  memset(dest_str, 0x00, strlen(str));
  string_reverse(str, dest_str);
  dest_str[strlen(str)] ='\0';
  if(!strcmp(str, dest_str))
  {
    pal_flag = TRUE;
  }
 
  free(dest_str);
 
  return pal_flag;
}

Here is the entire [program]….

Popularity: 12%

17
Feb

String Reversal

/*!
 * string_reverse.c: Reverse a string  Feb 17, 2006
 */
#include <stdio.h>
#include <string.h>

void reverse_str(char *str, int start, int end)
    {
    char c = str[start];
    str[start] = str[end];
    str[end] = c;

    start++;
    end–;
    if (start < end)
        reverse_str(str, start, end);
    }

int main ()
    {
    char str[] = "vijoeyz";
    int len = strlen(str);
    reverse_str(str, 0, len-1);
    puts(str);
    return 0;
    }

Popularity: 23%

16
Feb

Printing array spirally - c program

Printing array in spiral order is not that tough as we think, if we properly maintain directions and positions of indexes
we are done, here is such simple program…

/*Printing array spirally for ex.

1    2    3    4

5    6    7    8

9    10   11  12

13   14   15   16

need to print the above matrix in 1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 order (i.e. spirally) */

 
#include <stdio.h>
 
#define MAX_COLS 20
 
enum
{
  ARR_RIGHT,
  ARR_DOWN,
  ARR_LEFT,
  ARR_UP
};
 
int array_spiral_print(int arr[][MAX_COLS], int num_rows, int num_cols)
{
  int m = num_rows-1;  //num_rows
  int n = num_cols-1;  //num cols
  int m_begin = 0, n_begin = 0, m_end = m, n_end = n;
  int direction = ARR_RIGHT;
  int i,j;
 
  while((m_begin<m) && (m_end>0) && (n_begin<n) && (n_end>0))
  {
    switch(direction)
    {
    case ARR_RIGHT:
      for (j=n_begin; j<=n_end; j++)
      {
        printf("%d ", arr[m_begin][j]);
      }
      m_begin++;
      direction = ARR_DOWN;
      break;
    case ARR_DOWN:
      for (i=m_begin; i<=m_end; i++)
      {
        printf("%d ", arr[i][n_end]);
      }
      n_end- -;
      direction = ARR_LEFT;
      break;
    case ARR_LEFT:
      for (j=n_end; j>=n_begin; j- -)
      {
        printf("%d ", arr[m_end][j]);
      }
      m_end- -;
      direction = ARR_UP;
      break;
    case ARR_UP:
      for (i=m_end; i>=m_begin; i- -)
      {
        printf("%d ", arr[i][n_begin]);
      }
      n_begin++;
      direction = ARR_RIGHT;
 
      break;
    }
  }
 
  return 0;
}
 
#ifdef TEST
int main()
{
  int arr[][MAX_COLS] = {{1, 2, 3, 10}, {4, 5, 6, 11}, {7, 8, 9, 12}, {13, 14, 15, 16}};
  array_spiral_print(arr, 4, 4);
}
#endif

download [source code] for the above program which is a c file.

please let me know your comments….

Popularity: 25%

16
Feb

IEEE 754 Binary Floating Point Representation

How the floating point values are stored?

Note:  Please note that this discussion is not related to the C Language.

To be able to represent floating point numbers in the bit pattern, one needs
to know about IEEE 754, the floating point specification.  So, read patiently.

IEEE Floating Point Format:
---------------------------

    3 3          2         1         0
    1 09876543 21098765432109876543210
    +-+--------+-----------------------+
    |s| be     |       fraction        |
    +-+--------+-----------------------+

    be - biased exponent.  It is a constant, 127, for 32-bit
         floating point number.  This is also know as
         Mantisa(M).

    The general form of a floating point number is:
    x = s * M * B^p

        where,  s is sign bit
                M is normalized mantissa (1.fffff for IEEE 754)
                B is base ( 2 for IEEE 754 )
                p is integer power (explained below)

                ^ stands for exponentiation

    (Note: The 1 of 1.fffff is not explicitly stored in the memory)

    The general form would be: x = s * 1.ffff .. fff (binary) * 2^p

    This would not solve the problem unless an example or two are given.

    Example 1:  Convert 5.75 to binary floating point.

    The integer part is 101.
    The fractional part is found by

        0.75 * 2    =   1.5     (1)
        0.5  * 2    =   1.0     (1)
        0.0  * 2    =   0.0     (0)   so it terminates

    So, the number is 101.110
    This is the mere binary floating point representation of 5.75
    To make it IEEE 754 compliant, we have to have the normalized
    mantissa.

    So,
        101.110 = 1.01110 * 2^2
        therefore, M = 1.01110  and
                   p = 2

        be = p + 127 = 2 + 127 = 129 i.e., 1000 0001 (binary)
        The fractional part is 0.01110...

    So, the IEEE 754 representation of 5.75 becomes:

        0 1000 0001 01110 0000 0000 0000 0000 000

    Example 2:  Convert -0.1 to binary floating point

    The fractional part is found by

        0.1  * 2    =   0.2     (0)
        0.2  * 2    =   0.4     (0)
        0.4  * 2    =   0.8     (0)
        0.8  * 2    =   1.6     (1)
        0.6  * 2    =   1.2     (1)
        0.2  * 2    =   0.4     (0)     which repeats 0.2 above
        0.4  * 2    =   0.8     (0)
        0.8  * 2    =   1.6     (1)

    So, the fractional part is 0.000110011...

    0.000110011  =  1.1001100 * 2^(-4)
    therefore,  M = 1.1001100
                p = -4

    be = 127 + p = 127 - 4 = 123 i.e., 0111 1011 (binary)
    The fractional part is 1001 1000 ....

    So, the IEEE 754 representation of 5.75 becomes:

        1 01111011 1001 1000 0000 0000 0000 000

Popularity: 33%

16
Feb

ASCII Case Conversion

/*
 * case_conv.c  -   Program to change case without using arithmetic
 *                  operators or library functions.  This program
 *                  works ONLY if the charcter set is ASCII, and hence
 *                  is not portable.  It is here, only as an example,
 *                  to convey a logic as how it can be done.
 */

/*
 * Refer the ASCII table while tracing the following program:
 *
 * Letter           Upper(binary)       Lower(binary)
 * ——           ————-       ————-
 *
 *  A               0100 0001           0110 0001
 *  B               0100 0010           0110 0010
 *  …             …                 …
 *  O               0100 1111           0110 1111
 *  P               0101 0000           0111 0000
 *  …             …                 …
 *  Z               0101 1010           0111 1010
 */

#include <stdio.h>
#include <stdlib.h>

int
to_lower ( int ch )
{
    unsigned char _ch = (unsigned char)ch >> 4;

    /* If CH is already in lower case, return it */
    if ( _ch == 0×6 || _ch == 0×7 )
        return ch;

    /* convert it to lower case */
    if ( _ch == 0×4 )
        return (int)( ( (unsigned char)ch & 0×0f ) | 0×60 );
    else
    if ( _ch == 0×5 )
        return (int)( ( (unsigned char)ch & 0×0f ) | 0×70 );
    else
        return ch;
}

int
to_upper ( int ch )
{
    unsigned char _ch = (unsigned char)ch >> 4;

    /* If CH is already in upper case, return it */
    if ( _ch == 0×4 || _ch == 0×5 )
        return ch;

    /* convert it to upper case */
    if ( _ch == 0×6 )
        return (int)( ( (unsigned char)ch & 0×0f ) | 0×40 );
    else
    if ( _ch == 0×7 )
        return (int)( ( (unsigned char)ch & 0×0f ) | 0×50 );
    else
        return ch;
}

int
main ( void )
{
    printf ( "%c\n", to_upper ( ‘+’ ) );
    printf ( "%c\n", to_upper ( ‘r’ ) );
    printf ( "%c\n", to_upper ( ‘l’ ) );
    printf ( "%c\n", to_upper ( ‘P’ ) );

    printf ( "%c\n", to_lower ( ‘$’ ) );
    printf ( "%c\n", to_lower ( ‘R’ ) );
    printf ( "%c\n", to_lower ( ‘O’ ) );
    printf ( "%c\n", to_lower ( ‘9′ ) );
    return EXIT_SUCCESS;
}

Popularity: 11%

14
Feb

Bus Error

Bus error occurs when hardware tells the OS about a problematic memory reference.  In practice, a bus error is almost always caused by a misaligned read or write.  It’s called a bus error, because the address bus is the component that chokes if a misaligned load or store is requested.

union {
    char a[10];
    int i;
}u;

A bus error can also be generated by referencing memory that does not physically exist.

Alignment means that data items can only be stored at an address that is multiple of their size.

A program to cause a bus error is:

int *p = (int*) &(u.a[1]);
*p = 17;        /* the misaligned addr is p causes a bus error */

Simply, a bus error means that the CPU disliked something about that memory reference, while segv means that the MMU disliked something about it.

Popularity: 8%

Next Page »