Showing posts with label C. Show all posts
Showing posts with label C. Show all posts

Which is the best sorting method?

There is no sorting method that is universally superior to all others. The programmer must carefully examine the problem and the desired results before deciding the particular sorting method. Some of the sorting methods are given below:

Bubble sort : When a file containing records is to be sorted then Bubble sort is the best sorting method when sorting by address is used.
Bsort : It can be recommended if the input to the file is known to be nearly sorted.
Meansort : It can be recommended only for input known to be very nearly sorted.
Quick Sort : In the virtual memory environment, where pages of data are constantly being swapped back and forth between external and internal storage. In practical situations, quick sort is often the fastest available because of its low overhead and its average behavior.
Heap sort : Generally used for sorting of complete binary tree. Simple insertion sort and straight selection sort : Both are more efficient than bubble sort. Selection sort is recommended for small files when records are large and for reverse situation insertion sort is recommended. The heap sort and quick sort are both more efficient than insertion or selection for large number of data.
Shell sort :  It is recommended for moderately sized files of several hundred elements.
Radix sort : It is reasonably efficient if the number of digits in the keys is not too large.

How can we copy the contents of one file to another in one shot?

#include <fstream.h>
void main( )
{
     char source [ 67 ], target [ 67 ];
     char ch;
     cout << endl << "Enter source filename";
     cin >> source;
     cout << endl << "Enter target filename";
     cin >> target;
     ifstream infile ( source );
     ofstream outfile ( target );
     outfile << infile.rdbuf( );
}
Here all the copying is done through the single statement
outfile << infile.rdbuf( );

The function rdbuf( ) returns the address of the strstreambuf where the values are stored. 

How to allocate memory for a multidimensional array dynamically?

Many times we need to allocate memory for a multidimensional array dynamically. Because of complexity of pointers many find this difficult.

Following program allocates memory for a 3 x 3 array dynamically, copies contents of a 3 x 3 array in it and prints the contents using the pointer.

#include <iostream.h>
#include <new.h>
int a[ ][3] = {
                      1, 2, 3,
                      4, 5, 6,
                      7, 8, 9
                  };
void main( )
{
     int **p;
     p = new int *[3] ;
     for ( int i = 0 ; i < 3 ; i++ )
            p[i] = new int[3];
     for ( i = 0 ; i < 3 ; i++ )
       for ( int j = 0 ; j < 3 ; j++ )
            p[i][j] = a[i][j] ; 
     for ( i = 0 ; i < 3 ; i++ )
     {
       for ( j = 0 ; j < 3 ; j++ )
            cout << p[i][j] ;
      cout << "\n" ;
     }
}

How do I write code that allows to create only one instance of a class?

#include <iostream.h>
class sample  
{
         static sample *ptr ;
    private:
         sample( ){}
    public:
         static sample* create( )
         {
                   if ( ptr == NULL )
                       ptr = new sample ;
                   return ptr; 
         } 
 } ;
 sample *sample::ptr = NULL ;
 void main( )
{
      sample *a = sample::create( ) ;
      sample *b = sample::create( ) ;
}

Here, the class sample contains a static data member ptr which is a pointer to the object of same class. The constructor is private which avoids us from creating objects outside the class. A static member function called create( ) is used to create an object of the class. In this function the condition is checked whether or not ptr is NULL, if it is then an object is created dynamically and its address collected in ptr is returned. If ptr is not NULL, then the same address is returned. Thus, in main( ) on execution of the first statement one object of sample gets created whereas on execution of second statement, b holds the address of the first object. Thus, whatever number of times you call create( ) function, only one object of sample class will be available. 

C Program to Print a pyramid string triangle

#include <stdio.h>
#include <string.h>
int main()
{
         int i,j,length;
         char arr[] = "Programming";
         length = strlen(arr);
         for (i = length; i >= 0; i--)
        {
            printf("\n");
           for (j = 0; j< i; j++)
          {
                  printf("%c",arr[j]);
          }
       }
     return 0;
}
Output:
Programming
Programmin
Programmi
Programm
Program
Progra
Progr
Prog
Pro
Pr
P

C Program to count Number of Words in a Line

#include<stdio.h>
#include<string.h>
void main()
{
        char str[20];
        char *p;
        int count=0;
        clrscr();
        printf("Enter the Line:");
        gets(str);
        p=str;

        while(*p!='\0')
        {
              if(*p=='')
              {
                       count++;
              }
              p++;
        }
        printf("The number of Word is: %d",count+1);
        getch();
}
Output:
Enter the Line: C Programming Language
The number of Word is: 3

Find The Output Of Following Code?

#include<stdio.h>
#include<conio.h>
void main()
{
           clrscr();
           int i=5,j=5,k=5;
           i= i++ * ++i;
           j= ++j * ++j;
           k= k++ * k++;

           printf("%d\n",i);
           printf("%d\n",j);
           printf("%d\n",k);
           getch();
}

Output:

37
49
27

Explanation:
i=i++ * ++i; 
it reads from right to left
so first i increments so i=++i * 6;
Now i value is 6 so multiply 6 * 6=36
then perform post increment in i so Value becomes 37

j & K output is also same as above explanation.

Write a C program whether the given number is Armstrong number or not.

Armstrong number:

Those Numbers which sum of its digits to power of number of its digits is equal to that numbers are known as Armstrong Numbers.

Example 1: 153 Total Digits in 153 is 3 
               1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153 

Example 2: 1634 Total digits in 1634 is 4 
                1^4 + 6^4 + 3^4 +4^4 = 1 + 1296 + 81 + 64 =1634 

Examples of Armstrong numbers: 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725
int main(){
    int num,r,sum=0,temp;

    printf("Enter a number: ");
    scanf("%d",&num);

    temp=num;
    while(num!=0)
    {
         r=num%10;
         num=num/10;
         sum=sum+(r*r*r);
    }
    if(sum==temp)
         printf("%d is an Armstrong number",temp);
    else
         printf("%d is not an Armstrong number",temp);

    return 0;
}

Out Put:
Enter a number: 153
153 is an Armstrong number

Write a C program to demonstrate call by value and call by reference.

Call By Value & Call By Reference:
void callByValue(int, int);
void callByReference(int *, int *);
 
int main()
{
    int x=30, y=40;
    clrscr();
    printf("Value of x = %d and y = %d.\n", x,y);
 
    callByValue(x, y);
    printf("\nCall By Value function call...\n");
    printf("Value of x = %d and y = %d.\n", x,y);
 
    callByReference(&x, &y);
    printf("\nCall By Reference function call...\n");
    printf("Value of x = %d and y = %d.\n", x,y);
 
    getch();
    return 0;
}
 
void callByValue(int x, int y)
{
    int temp;
    temp = x;
    x = y;
    y = temp;
}
 
void callByReference(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

OUTPUT:
      Values of x = 30 and and y=40.
      Call By Value function call... 
      Values of x = 30 and and y=40.
      Call By Reference function call...
      Values of x = 40 and and y=30.

Write a C program to calculate the total and average of marks

void main( )
{
      int avg, sum = 0;
      int marks[10];
      for (int i = 0; i<=9; i++ )
      {
            printf ( “\n Please enter marks for 10 students: ” );
            scanf ( “%d”, &marks[i] );
      }
     for (i = 0; i<=9; i++)
          sum = sum + marks[i];
     avg = sum / 20;
     printf ( “\n Total marks secured by 10 students in a test are %d”, sum);
     printf ( “\n Average marks secured by 10 students in a test are %d”, avg);

}

Dynamic Memory Allocation in C

In dynamic memory management memory will be allocate at run time via a group of functions in the C standard library, namely malloc, realloc, calloc and free. This is also known as heap memory.

malloc:

The malloc() function dynamically allocates memory when required. This function allocates ‘size’ byte of memory and returns a pointer to the first byte or NULL if there is some kind of error.


void * malloc (size_t size);

malloc allocates memory in bytes.malloc() does not initialize the memory allocated.

int *ptr = malloc(sizeof(int) * 10); // allocates 10 ints!

calloc:

void *calloc(size_t nvar,size_t size)

calloc allocates memory in blocks. calloc initializes the allocated memory to zero. calloc takes two arguments, number of variables to be allocated and size of each variable.

int num;
int *ptr = (int*)calloc(num, sizeof(int));

realloc:

The realloc() function changes the size of a block of memory that was previously allocated with malloc() or calloc(). The function prototype is

void *realloc(void *ptr, size_t size);

The ptr argument is a pointer to the original block of memory. The new size, in bytes, is specified bysize.
There are several possible outcomes with realloc():

  • If sufficient space exists to expand the memory block pointed to by ptr, the additional memory is allocated and the function returns ptr.
  • If sufficient space does not exist to expand the current block in its current location, a new block of the size for size is allocated, and existing data is copied from the old block to the beginning of the new block. The old block is freed, and the function returns a pointer to the new block.
  • If the ptr argument is NULL, the function acts like malloc(), allocating a block of size bytes and returning a pointer to it.
  • If the argument size is 0, the memory that ptr points to is freed, and the function returns NULL.
  • If memory is insufficient for the reallocation (either expanding the old block or allocating a new one), the function returns NULL, and the original block is unchanged.
free:

When you allocate memory with either malloc() or calloc(), it is taken from the dynamic memory pool that is available to your program. This pool is sometimes called the heap, and it is finite. When your program finishes using a particular block of dynamically allocated memory, you should deallocate, or free, the memory to make it available for future use. To free memory that was allocated dynamically, use free(). 


void free(void *ptr); 

The free() function releases the memory pointed to by ptr. This memory must have been allocated with malloc(), calloc(), or realloc(). If ptr is NULL, free() does nothing.

For loop syntax in C

for(<loop variable initialization>;<loop condition>;<loop variable increment/decrement>)
{
           loop statement 1;
           loop statement 2;
           loop statement 3;
              ………………….
           loop statement N;
}


Example:
#include<stdio.h>
#include<conio.h>
 
void main()
{
 
     int i;
     clrscr();
 
     for(i=1;i<=10;i++)
     {
            printf("%d for loop.\n",i);
     }
      getch();
}
When above “for loop” block (line no. 10 - 13) gets executed let me tell you what happens.

For loop execution steps:

  • At first value of “i” is set to 1, this happens only once in loop execution.
  • Next loop condition (i<=10) is tested. Since value of “i” is 1, it satisfies loop condition and loop statement is executed.
  • When we reach at closing brace of “for loop” then control moves back to beginning of “for loop” and where value of “i” is incremented by 1 (i++).
  • Again it starts from step no. 2. This looping will continue till loop condition (i<=10) is tested to false (means condition is no longer true because value of “i” would be greater than 10, i.e. 11).
  • When value of “i” reaches to 11 then control exits from loop and next statement, after loop block, is executed (in above program line no. 14).

If memory is allocated dynamically using new then can we expand the allocated memory using realloc( )?

Yes, we can! This can be explained with the help of following example:

#include <iostream.h>
#include <malloc.h> 
void main( )

       int *p = new int[5] ; 
       p[1] = 3 ; 
       p = ( int * ) realloc ( p, sizeof ( int ) * 5 ) ; 
       cout << p[1] ; 


The realloc( ) function expands the existing allocated memory if it finds enough contiguous memory locations that are required. If enough contiguous memory blocks are not available then the new memory block is allocated. The existing data is copied and the original memory block is freed.

Stack Overflow Situation

func_call() {
           funct_call();
}

Every time the above function is called the return address is stored onto the stack. Calling in this infinite loop will cause a stack overflow.

Examples for an infinite loop

a. while (1)
   {
   }

b. for (;;)

   {
   }

c. do

   {
   }while(1);

d. label:
    goto label;

Standard prototypes for main() function

a. int main (void)
b. int main (int argc, char **argv)
c. int main (int argc, char *argv[])

C++ Features Not in C

Listed below are some features that are found in C++, not found in C, but still have nothing to do with Object Oriented Programming.

Casts:
In C, if you want to cast an int to a long int, for example, you'd use 
int i=0; 
long l = (long) i; 

In C++, you can use a function-like call to make the cast. 
long l = long(i);

It's easier to read. Since it's possible to create functions to perform casts involving user-defined types, this makes all the casts look consistent. For example, you may have a user-defined type -- complex numbers. 

You have a function that accepts an integer and casts it to a complex number: 1 --> 1 + 0i (real part is 1 and imaginary part is 0) 

Suppose your function call is named 'complex', then it may look like: 

Complex x;
int i=1; 
 x = complex(i);

Flexible Declarations:
In C, all var declarations within a scope occur at the beginning of that scope. Thus, all global declartions must appear before any functions, and any local declarations must be made before any executable statements.

C++, on the other hand, allows you to mix data declarations with functions and executable statements. 

E.g. In C,
void makeit(void) 
{
      float i; 
      char *cp;
      /* imagine 2000 lines of code here */ 
      /* allocate 100 bytes for cp */ 
      cp = malloc(100); /* 1st use of cp */ 
      for (i=0; i<100; ++i) /* 1st use of i */ 
      { 
              /* do something */ 
      } /* more code */ 
 } 

In C++, 
void makeit(void) 
      // 2000 lines of code 
      char *cp = new char[100]; 
      for (int i=1; i<10; i++) { } 
}

'struct' and 'union' Tags:

In C, we would have this segment: 
struct foo 
{
      int a; 
      float b;
struct foo f; 

This declares a struct with the tag name 'foo' and then creates an instance of foo named f. Notice when you declare var of that struct, you have to say 'struct foo'. 
In C++, struct and union tags are considered to be type name, just as if they had been declared by the 'typedef' statement. 

struct foo {int a; float b;}
foo f; 

which is equivalent to the following in C: 
typedef struct 
      int a; 
      float b; 
} foo;

foo f;


'const':

In ANSI C, it also supports 'const', but C++'s 'const' is more flexible than C's. In both C and C++, a value declared as 'const' is inviolate; it may not be modified by any part of the program in any way. 
The most common use of 'const' values in C is to replace '#define' literal constants. 

#define MAX_CUSTOMERS 10 
 const int MAX_CUSTOMERS = 10; 

Thus, 
MAX_CUSTOMERS = 10; 
MAX_CUSTOMERS ++; 

are both not acceptable. Note: since you cannot make changes to a 'const', each constant must be initialized when declared. The following is wrong: 
const int invalid; 

In C++, you can do something like 
const int ArraySize = 100;
int Array[ArraySize];
while in ANSI C, this would be flagged as an error.

'new' and 'delete':

In C, all dynamic mem allocation is handled via library calls, such as 'malloc' and 'free'. Here's how a traditional C programs might allocate memory: 

void func(void) 
{
     int *i; 
     i = (int *)malloc(sizeof(int)); 
    *i = 10; 
     printf("%d", *i); 
     free(i); 

In C++, there are new ways of dynamically allocating mem using operators called 'new' and 'delete', where 'new' replaces 'malloc' and 'delete' replaces 'free' in C. We could rewrite the above function as the following: 

void func() 
     int *i = new int; 
     *i = 10; 
     cout << *i; 
     delete i; 
}
You'd probably agree this is a much clearer syntax and it's much easier to use as well. 

A couple more examples: 
     int *i = new int[10]; // an array of 10 integers 
     int *i = new int(*)[10]; // an array of 10 pointers to integers 

You can also intialize all the variables allocated by 'new': 

float *f = new float[50] (0.0); 

Error Code: if 'new' fails to allocate any memory requested, it will return NULL;
Tip: Usually, right after a call to allocate memory, 'new' or 'malloc' check to see if any memory has been allocated. This can prevent your program from accessing a NULL pointer which is a disaster and which will cause a bus error.

Note: Don't mix the use of 'new' and 'delete' with that of 'malloc' and 'free'. i.e, always use either all the C lib calls 'malloc' and 'free' in your program to manage dynamic mem. OR use all 'new' and 'delete'. All the mem allocated by 'malloc' should be returned to the available mem pool by 'free' and the same holds for 'new' and 'delete'. I'd just use 'new' and 'delete'.

References:

C can by clumsy sometimes. When you write a function to swap two integers, you have to pass the two integers into the function by reference: 

void swapint(int *a, int *b) 
      int temp;
      temp = *a; 
      *a = *b; 
      *b = temp; 
}
Here's the function call: 
    swapint(&i1, &i2); 

C++ supports a special type of identifier known as 'reference' &. It makes changing the parameter values in a function reletively painless. The above function can be rewritten in C++ as follows: 

void swapint(int &a, int &b) 
     int temp = a; 
     a = b; 
     b = temp; 
Function call: 
     swapint(i1, i2); 

When i1 and i2 are passed into the function, a POINTS to i1 and b POINTS to i2 instead of making local copies of i1 and i2. Now, whenever you refer to a or b in the function, you actually refer to i1 and i2. So, whatever changes you make to a or b, they will be reflected on i1 and i2.


Function Overloading:

In C, as in most other programming languages, every function must have a unique name. At times, it can be annoying. Imagine you want to have a function that returns the abs value of an integer. 
int abs(int i); 

If you need to figure out the abs value of every possible available data type, you then have to write a function for each of the possible types: 

long labs(long l);
double dabs(double d); 

All those functions do the same thing -- return the abs value of the argument. Thus it seems silly to have a different name for each of those functions. 

C++ solves this by allowing you to create those functions with the same name. This is called overloading. 

For example, you can do the above in C++: 
int abs(int i); 
long abs(long l); 
double abs(double d); 

And depending on the type of parameter you pass into the 'abs' func. C++ will select the right one. 

Note: What if the type of the parameter passed in is not identical to any of the available parameter types in the existing functions? 

abs('a'); 
abs(3.1415F); 

C++ will try to make the easiest conversion to match those parameter types in the funcion prototypes. 

abs('a'); // call int abs(int i) 
abs(3.1415F); // call double abs(double d);
If no such conversion exists, then an error will occur.

Can I mix C-style and C++ style allocation and deallocation?

Yes, in the sense that you can use malloc() and new in the same program.

No, in the sense that you cannot allocate an object with malloc() and free it using delete. Nor can you allocate with new and delete with free() or use realloc() on an array allocated by new.

The C++ operators new and delete guarantee proper construction and destruction; where constructors or destructors need to be invoked, they are. The C-style functions malloc(), calloc(), free(), and realloc() doesn't ensure that. Furthermore, there is no guarantee that the mechanism used by new and delete to acquire and release raw memory is compatible with malloc() and free(). If mixing styles works on your system, you were simply "lucky" - for now.

If you feel the need for realloc() - and many do - then consider using a standard library vector. 

For example // read words from input into a vector of strings:

vector<string> words;
string s;
while (cin>>s && s!=".") words.push_back(s);


The vector expands as needed.

Purpose of main() function in C?

In C, program execution starts from the main() function. Every C program must contain a main() function. The main function may contain any number of statements. These statements are executed sequentially in the order which they are written.

The main function can in-turn call other functions. When main calls a function, it passes the execution control to that function. The function returns control to main when a return statement is executed or when end of function is reached.

In C, the function prototype of the 'main' is one of the following:
int main(); //main with no arguments
int main(int argc, char *argv[]); //main with arguments

The parameters argc and argv respectively give the number and value of the program's command-line arguments.

Example:

#include <stdio.h>
/* program section begins here */
int main()
{
          // opening brace - program execution starts here
          printf("Welcome to the world of C");
          return 0;
}
// closing brace - program terminates here

Output:
Welcome to the world of C

Which bitwise operator is suitable for checking whether a particular bit is ON or OFF?

Bitwise AND operator.

Example: Suppose in byte that has a value 10101101 . We wish to check whether bit number 3 is ON (1) or OFF(0) . Since we want to check the bit number 3, the second operand for AND operation we choose is binary 00001000, which is equal to 8 in decimal.

Explanation:

ANDing operation :

10101101 original bit pattern
00001000 AND mask
--------------
00001000 resulting bit pattern
--------------

The resulting value we get in this case is 8, i.e. the value of the second operand. The result turned out to be a 8 since the third bit of operand was ON. Had it been OFF, the bit number 3 in the resulting bit pattern would have evaluated to 0 and complete bit pattern would have been 00000000. Thus depending upon the bit number to be checked in the first operand we decide the second operand, and on ANDing these two operands the result decides whether the bit was ON or OFF.