There are times when it is convenient to allocate memory at run time using malloc(), calloc(), or other allocation functions. Using this approach permits postponing the decision on the size of the memory block need to store an array, for example, until run time. Or it permits using a section of memory for the storage of an array of integers at one point in time, and then when that memory is no longer needed it can be freed up for other uses, such as the storage of an array of structures.

When memory is allocated, the allocating function (such as malloc(), calloc(), etc.) returns a pointer. The type of this pointer depends on whether you are using an older K&R compiler or the newer ANSI type compiler. With the older compiler the type of the returned pointer is char, with the ANSI compiler it is void.

If you are using an older compiler, and you want to allocate memory for an array of integers you will have to cast the char pointer returned to an integer pointer. For example, to allocate space for 10 integers we might write:

    int *iptr;
iptr = (int *)malloc(10 * sizeof(int));
if (iptr == NULL)

{ .. ERROR ROUTINE GOES HERE .. }
If you are using an ANSI compliant compiler, malloc() returns a void pointer and since a void pointer can be assigned to a pointer variable of any object type, the (int *) cast shown above is not needed. The array dimension can be determined at run time and is not needed at compile time. That is, the 10 above could be a variable read in from a data file or keyboard, or calculated based on some need, at run time.
Because of the equivalence between array and pointer notation, once iptr has been assigned as above, one can use the array notation. For example, one could write:

    int k;
for (k = 0; k < 10; k++)
iptr[k] = 2;
to set the values of all elements to 2.

Even with a reasonably good understanding of pointers and arrays, one place the newcomer to C is likely to stumble at first is in the dynamic allocation of multi-dimensional arrays. In general, we would like to be able to access elements of such arrays using array notation, not pointer notation, wherever possible. Depending on the application we may or may not know both dimensions at compile time. This leads to a variety of ways to go about our task.

As we have seen, when dynamically allocating a one dimensional array its dimension can be determined at run time. Now, when using dynamic allocation of higher order arrays, we never need to know the first dimension at compile time. Whether we need to know the higher dimensions depends on how we go about writing the code. Here I will discuss various methods of dynamically allocating room for 2 dimensional arrays of integers.

First we will consider cases where the 2nd dimension is known at compile time.

METHOD 1:

One way of dealing with the problem is through the use of the typedef keyword. To allocate a 2 dimensional array of integers recall that the following two notations result in the same object code being generated:
    multi[row][col] = 1;     *(*(multi + row) + col) = 1;

It is also true that the following two notations generate the same code:
    multi[row]            *(multi + row)

Since the one on the right must evaluate to a pointer, the array notation on the left must also evaluate to a pointer. In fact multi[0] will return a pointer to the first integer in the first row, multi[1] a pointer to the first integer of the second row, etc. Actually, multi[n] evaluates to a pointer to that array of integers that make up the n-th row of our 2 dimensional array. That is, multi can be thought of as an array of arrays and multi[n] as a pointer to the n-th array of this array of arrays. Here the word pointer is being used to represent an address value. While such usage is common in the literature, when reading such statements one must be careful to distinguish between the constant address of an array and a variable pointer which is a data object in itself.

Consider now:

--------------- Program  --------------------------------


#include
#include

#define COLS 5

typedef int RowArray[COLS];
RowArray *rptr;

int main(void)
{
int nrows = 10;
int row, col;
rptr = malloc(nrows * COLS * sizeof(int));
for (row = 0; row < nrows; row++)
{
for (col = 0; col < COLS; col++)
{
rptr[row][col] = 17;
}
}

return 0;
}
------------- End of Prog. --------------------------------

Here I have assumed an ANSI compiler so a cast on the void pointer returned by malloc() is not required. If you are using an older K&R compiler you will have to cast using:
    rptr = (RowArray *)malloc(.... etc.
Using this approach, rptr has all the characteristics of an array name name, (except that rptr is modifiable), and array notation may be used throughout the rest of the program. That also means that if you intend to write a function to modify the array contents, you must use COLS as a part of the formal parameter in that function, just as we did when discussing the passing of two dimensional arrays to a function.

METHOD 2:

In the METHOD 1 above, rptr turned out to be a pointer to type "one dimensional array of COLS integers". It turns out that there is syntax which can be used for this type without the need of typedef. If we write:
    int (*xptr)[COLS];

the variable xptr will have all the same characteristics as the variable rptr in METHOD 1 above, and we need not use the typedef keyword. Here xptr is a pointer to an array of integers and the size of that array is given by the #defined COLS. The parenthesis placement makes the pointer notation predominate, even though the array notation has higher precedence. i.e. had we written
    int *xptr[COLS];
we would have defined xptr as an array of pointers holding the number of pointers equal to that #defined by COLS. That is not the same thing at all. However, arrays of pointers have their use in the dynamic allocation of two dimensional arrays, as will be seen in the next 2 methods.

METHOD 3:

Consider the case where we do not know the number of elements in each row at compile time, i.e. both the number of rows and number of columns must be determined at run time. One way of doing this would be to create an array of pointers to type int and then allocate space for each row and point these pointers at each row. Consider:
-------------- Program  ------------------------------------



#include
#include

int main(void)
{
int nrows = 5; /* Both nrows and ncols could be evaluated */
int ncols = 10; /* or read in at run time */
int row;
int **rowptr;
rowptr = malloc(nrows * sizeof(int *));
if (rowptr == NULL)
{
puts("\nFailure to allocate room for row pointers.\n");
exit(0);
}

printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");

for (row = 0; row < nrows; row++)
{
rowptr[row] = malloc(ncols * sizeof(int));
if (rowptr[row] == NULL)
{
printf("\nFailure to allocate for row[%d]\n",row);
exit(0);
}
printf("\n%d %p %d", row, rowptr[row], rowptr[row]);
if (row > 0)
printf(" %d",(int)(rowptr[row] - rowptr[row-1]));
}

return 0;
}

--------------- End ------------------------------------

In the above code rowptr is a pointer to pointer to type int. In this case it points to the first element of an array of pointers to type int. Consider the number of calls to malloc():
    To get the array of pointers             1     call
To get space for the rows 5 calls
-----
Total 6 calls
If you choose to use this approach note that while you can use the array notation to access individual elements of the array, e.g. rowptr[row][col] = 17;, it does not mean that the data in the "two dimensional array" is contiguous in memory.

You can, however, use the array notation just as if it were a continuous block of memory. For example, you can write:

    rowptr[row][col] = 176;
just as if rowptr were the name of a two dimensional array created at compile time. Of course row and col must be within the bounds of the array you have created, just as with an array created at compile time.

If you want to have a contiguous block of memory dedicated to the storage of the elements in the array you can do it as follows:

METHOD 4:

In this method we allocate a block of memory to hold the whole array first. We then create an array of pointers to point to each row. Thus even though the array of pointers is being used, the actual array in memory is contiguous. The code looks like this:
----------------- Program -----------------------------------


#include
#include

int main(void)
{
int **rptr;
int *aptr;
int *testptr;
int k;
int nrows = 5; /* Both nrows and ncols could be evaluated */
int ncols = 8; /* or read in at run time */
int row, col;

/* we now allocate the memory for the array */

aptr = malloc(nrows * ncols * sizeof(int));
if (aptr == NULL)
{
puts("\nFailure to allocate room for the array");
exit(0);
}

/* next we allocate room for the pointers to the rows */

rptr = malloc(nrows * sizeof(int *));
if (rptr == NULL)
{
puts("\nFailure to allocate room for pointers");
exit(0);
}

/* and now we 'point' the pointers */

for (k = 0; k < nrows; k++)
{
rptr[k] = aptr + (k * ncols);
}

/* Now we illustrate how the row pointers are incremented */
printf("\n\nIllustrating how row pointers are incremented");
printf("\n\nIndex Pointer(hex) Diff.(dec)");

for (row = 0; row < nrows; row++)
{
printf("\n%d %p", row, rptr[row]);
if (row > 0)
printf(" %d",(rptr[row] - rptr[row-1]));
}
printf("\n\nAnd now we print out the array\n");
for (row = 0; row < nrows; row++)
{
for (col = 0; col < ncols; col++)
{
rptr[row][col] = row + col;
printf("%d ", rptr[row][col]);
}
putchar('\n');
}

puts("\n");

/* and here we illustrate that we are, in fact, dealing with
a 2 dimensional array in a contiguous block of memory. */
printf("And now we demonstrate that they are contiguous in memory\n");

testptr = aptr;
for (row = 0; row < nrows; row++)
{
for (col = 0; col < ncols; col++)
{
printf("%d ", *(testptr++));
}
putchar('\n');
}

return 0;
}




------------- End Program -----------------

Consider again, the number of calls to malloc()
    To get room for the array itself      1      call
To get room for the array of ptrs 1 call
----
Total 2 calls

Now, each call to malloc() creates additional space overhead since malloc() is generally implemented by the operating system forming a linked list which contains data concerning the size of the block. But, more importantly, with large arrays (several hundred rows) keeping track of what needs to be freed when the time comes can be more cumbersome. This, combined with the contiguousness of the data block that permits initialization to all zeroes using memset() would seem to make the second alternative the preferred one.

As a final example on multidimensional arrays we will illustrate the dynamic allocation of a three dimensional array. This example will illustrate one more thing to watch when doing this kind of allocation. For reasons cited above we will use the approach outlined in alternative two. Consider the following code:

------------------- Program -------------------------------------

/* Program */

#include
#include
#include

int X_DIM=16;
int Y_DIM=5;
int Z_DIM=3;

int main(void)
{
char *space;
char ***Arr3D;
int y, z;
ptrdiff_t diff;

/* first we set aside space for the array itself */

space = malloc(X_DIM * Y_DIM * Z_DIM * sizeof(char));

/* next we allocate space of an array of pointers, each
to eventually point to the first element of a
2 dimensional array of pointers to pointers */

Arr3D = malloc(Z_DIM * sizeof(char **));

/* and for each of these we assign a pointer to a newly
allocated array of pointers to a row */

for (z = 0; z < Z_DIM; z++)
{
Arr3D[z] = malloc(Y_DIM * sizeof(char *));

/* and for each space in this array we put a pointer to
the first element of each row in the array space
originally allocated */

for (y = 0; y < Y_DIM; y++)
{
Arr3D[z][y] = space + (z*(X_DIM * Y_DIM) + y*X_DIM);
}
}

/* And, now we check each address in our 3D array to see if
the indexing of the Arr3d pointer leads through in a
continuous manner */

for (z = 0; z < Z_DIM; z++)
{
printf("Location of array %d is %p\n", z, *Arr3D[z]);
for ( y = 0; y < Y_DIM; y++)
{
printf(" Array %d and Row %d starts at %p", z, y, Arr3D[z][y]);
diff = Arr3D[z][y] - space;
printf(" diff = %d ",diff);
printf(" z = %d y = %d\n", z, y);
}
}
return 0;
}

------------------- End of Prog.----------------------------

If you have followed this tutorial up to this point you should have no problem deciphering the above on the basis of the comments alone. There are a couple of points that should be made however. Let's start with the line which reads:
    Arr3D[z][y] = space + (z*(X_DIM * Y_DIM) + y*X_DIM);
Note that here space is a character pointer, which is the same type as Arr3D[z][y]. It is important that when adding an integer, such as that obtained by evaluation of the expression (z*(X_DIM * Y_DIM) + y*X_DIM), to a pointer, the result is a new pointer value. And when assigning pointer values to pointer variables the data types of the value and variable must match.

Related Links :

Multi-Dimensional Arrays

    #define ROWS 5
#define COLS 10

int multi[ROWS][COLS];
we can access individual elements of the array multi using either:
    multi[row][col]
or
    *(*(multi + row) + col)
To understand more fully what is going on, let us replace
    *(multi + row)
with X as in:
    *(X + col)
Now, from this we see that X is like a pointer since the expression is de-referenced and we know that col is an integer. Here the arithmetic being used is of a special kind called "pointer arithmetic" is being used. That means that, since we are talking about an integer array, the address pointed to by (i.e. value of) X + col + 1 must be greater than the address X + col by and amount equal to sizeof(int).

Since we know the memory layout for 2 dimensional arrays, we can determine that in the expression multi + row as used above, multi + row + 1 must increase by value an amount equal to that needed to "point to" the next row, which in this case would be an amount equal to COLS * sizeof(int).

That says that if the expression *(*(multi + row) + col) is to be evaluated correctly at run time, the compiler must generate code which takes into consideration the value of COLS, i.e. the 2nd dimension. Because of the equivalence of the two forms of expression, this is true whether we are using the pointer expression as here or the array expression multi[row][col].

Thus, to evaluate either expression, a total of 5 values must be known:

  1. The address of the first element of the array, which is returned by the expression multi, i.e., the name of the array.
  2. The size of the type of the elements of the array, in this case sizeof(int).
  3. The 2nd dimension of the array
  4. The specific index value for the first dimension, row in this case.
  5. The specific index value for the second dimension, col in this case.
Given all of that, consider the problem of designing a function to manipulate the element values of a previously declared array. For example, one which would set all the elements of the array multi to the value 1.
    void set_value(int m_array[][COLS])
{
int row, col;
for (row = 0; row < ROWS; row++)
{
for (col = 0; col < COLS; col++)
{
m_array[row][col] = 1;
}
}
}

And to call this function we would then use:
    set_value(multi);
Now, within the function we have used the values #defined by ROWS and COLS that set the limits on the for loops. But, these #defines are just constants as far as the compiler is concerned, i.e. there is nothing to connect them to the array size within the function. row and col are local variables, of course. The formal parameter definition permits the compiler to determine the characteristics associated with the pointer value that will be passed at run time. We really don’t need the first dimension and, as will be seen later, there are occasions where we would prefer not to define it within the parameter definition, out of habit or consistency, I have not used it here. But, the second dimension must be used as has been shown in the expression for the parameter. The reason is that we need this in the evaluation of m_array[row][col] as has been described. While the parameter defines the data type (int in this case) and the automatic variables for row and column are defined in the for loops, only one value can be passed using a single parameter. In this case, that is the value of multi as noted in the call statement, i.e. the address of the first element, often referred to as a pointer to the array. Thus, the only way we have of informing the compiler of the 2nd dimension is by explicitly including it in the parameter definition.

Related Links :

Pointers and Strings

The study of strings is useful to further tie in the relationship between pointers and arrays. It also makes it easy to illustrate how some of the standard C string functions can be implemented. Finally it illustrates how and when pointers can and should be passed to functions.

In C, strings are arrays of characters. This is not necessarily true in other languages. In BASIC, Pascal, Fortran and various other languages, a string has its own data type. But in C it does not. In C a string is an array of characters terminated with a binary zero character (written as '\0'). To start off our discussion we will write some code which, while preferred for illustrative purposes, you would probably never write in an actual program. Consider, for example:

    char my_string[40];

my_string[0] = 'T';
my_string[1] = 'e';
my_string[2] = 'd':
my_string[3] = '\0';

While one would never build a string like this, the end result is a string in that it is an array of characters terminated with a nul character. By definition, in C, a string is an array of characters terminated with the nul character. Be aware that "nul" is not the same as "NULL". The nul refers to a zero as defined by the escape sequence '\0'. That is it occupies one byte of memory. NULL, on the other hand, is the name of the macro used to initialize null pointers. NULL is #defined in a header file in your C compiler, nul may not be #defined at all.

Since writing the above code would be very time consuming, C permits two alternate ways of achieving the same thing. First, one might write:

    char my_string[40] = {'T', 'e', 'd', '\0',};   

But this also takes more typing than is convenient. So, C permits:

    char my_string[40] = "Ted";

When the double quotes are used, instead of the single quotes as was done in the previous examples, the nul character ( '\0' ) is automatically appended to the end of the string.

In all of the above cases, the same thing happens. The compiler sets aside an contiguous block of memory 40 bytes long to hold characters and initialized it such that the first 4 characters are Ted\0.

Now, consider the following program:

------------------program 3.1-------------------------------------

/* Program 3.1 from PTRTUT10.HTM 6/13/97 */

#include

char strA[80] = "A string to be used for demonstration purposes";
char strB[80];

int main(void)
{

char *pA; /* a pointer to type character */
char *pB; /* another pointer to type character */
puts(strA); /* show string A */
pA = strA; /* point pA at string A */
puts(pA); /* show what pA is pointing to */
pB = strB; /* point pB at string B */
putchar('\n'); /* move down one line on the screen */
while(*pA != '\0') /* line A (see text) */
{
*pB++ = *pA++; /* line B (see text) */
}
*pB = '\0'; /* line C (see text) */
puts(strB); /* show strB on screen */
return 0;
}

--------- end program 3.1 -------------------------------------


In the above we start out by defining two character arrays of 80 characters each. Since these are globally defined, they are initialized to all '\0's first. Then, strA has the first 42 characters initialized to the string in quotes.

Now, moving into the code, we declare two character pointers and show the string on the screen. We then "point" the pointer pA at strA. That is, by means of the assignment statement we copy the address of strA[0] into our variable pA. We now use puts() to show that which is pointed to by pA on the screen. Consider here that the function prototype for puts() is:

    int puts(const char *s);

For the moment, ignore the const. The parameter passed to puts() is a pointer, that is the value of a pointer (since all parameters in C are passed by value), and the value of a pointer is the address to which it points, or, simply, an address. Thus when we write puts(strA); as we have seen, we are passing the address of strA[0].

Similarly, when we write puts(pA); we are passing the same address, since we have set pA = strA;

Given that, follow the code down to the while() statement on line A. Line A states:

While the character pointed to by pA (i.e. *pA) is not a nul character (i.e. the terminating '\0'), do the following:

Line B states: copy the character pointed to by pA to the space pointed to by pB, then increment pA so it points to the next character and pB so it points to the next space.

When we have copied the last character, pA now points to the terminating nul character and the loop ends. However, we have not copied the nul character. And, by definition a string in C must be nul terminated. So, we add the nul character with line C.

It is very educational to run this program with your debugger while watching strA, strB, pA and pB and single stepping through the program. It is even more educational if instead of simply defining strB[] as has been done above, initialize it also with something like:

    strB[80] = "12345678901234567890123456789012345678901234567890"

where the number of digits used is greater than the length of strA and then repeat the single stepping procedure while watching the above variables. Give these things a try!

Getting back to the prototype for puts() for a moment, the "const" used as a parameter modifier informs the user that the function will not modify the string pointed to by s, i.e. it will treat that string as a constant.

Of course, what the above program illustrates is a simple way of copying a string. After playing with the above until you have a good understanding of what is happening, we can proceed to creating our own replacement for the standard strcpy() that comes with C. It might look like:

   char *my_strcpy(char *destination, char *source)
{
char *p = destination;
while (*source != '\0')
{
*p++ = *source++;
}
*p = '\0';
return destination;
}

In this case, I have followed the practice used in the standard routine of returning a pointer to the destination.

Again, the function is designed to accept the values of two character pointers, i.e. addresses, and thus in the previous program we could write:

    int main(void)
{
my_strcpy(strB, strA);
puts(strB);
}

I have deviated slightly from the form used in standard C which would have the prototype:

    char *my_strcpy(char *destination, const char *source); 

Here the "const" modifier is used to assure the user that the function will not modify the contents pointed to by the source pointer. You can prove this by modifying the function above, and its prototype, to include the "const" modifier as shown. Then, within the function you can add a statement which attempts to change the contents of that which is pointed to by source, such as:

    *source = 'X';

which would normally change the first character of the string to an X. The const modifier should cause your compiler to catch this as an error. Try it and see.

Now, let's consider some of the things the above examples have shown us. First off, consider the fact that *ptr++ is to be interpreted as returning the value pointed to by ptr and then incrementing the pointer value. This has to do with the precedence of the operators. Were we to write (*ptr)++ we would increment, not the pointer, but that which the pointer points to! i.e. if used on the first character of the above example string the 'T' would be incremented to a 'U'. You can write some simple example code to illustrate this.

Recall again that a string is nothing more than an array of characters, with the last character being a '\0'. What we have done above is deal with copying an array. It happens to be an array of characters but the technique could be applied to an array of integers, doubles, etc. In those cases, however, we would not be dealing with strings and hence the end of the array would not be marked with a special value like the nul character. We could implement a version that relied on a special value to identify the end. For example, we could copy an array of positive integers by marking the end with a negative integer. On the other hand, it is more usual that when we write a function to copy an array of items other than strings we pass the function the number of items to be copied as well as the address of the array, e.g. something like the following prototype might indicate:

    void int_copy(int *ptrA, int *ptrB, int nbr);

where nbr is the number of integers to be copied. You might want to play with this idea and create an array of integers and see if you can write the function int_copy() and make it work.

This permits using functions to manipulate large arrays. For example, if we have an array of 5000 integers that we want to manipulate with a function, we need only pass to that function the address of the array (and any auxiliary information such as nbr above, depending on what we are doing). The array itself does not get passed, i.e. the whole array is not copied and put on the stack before calling the function, only its address is sent.

This is different from passing, say an integer, to a function. When we pass an integer we make a copy of the integer, i.e. get its value and put it on the stack. Within the function any manipulation of the value passed can in no way effect the original integer. But, with arrays and pointers we can pass the address of the variable and hence manipulate the values of the original variables.

Related Links :

Bubble sort [linked list]

#define MAX 10

struct lnode
{
int data;
struct lnode *next;
} *head, *visit;

/* add a new entry to the linked list */
void llist_add(struct lnode **q, int num);
/* preform a bubble sort on the linked list */
void llist_bubble_sort(void);
/* print the entire linked list */
void llist_print(void);

int main(void)
{
/* linked list */
struct lnode *newnode = NULL;
int i = 0; /* a general counter */

/* load some random values into the linked list */
for(i = 0; i < MAX; i++) {
llist_add(&newnode, (rand() % 100));
}

head = newnode;
printf("Before bubble sort:\n");
llist_print();
printf("After bubble sort:\n");
llist_bubble_sort();
llist_print();

return 0;
}

/* adds a node at the end of a linked list */
void llist_add(struct lnode **q, int num)
{
struct lnode *tmp;

tmp = *q;

/* if the list is empty, create first node */
if(*q == NULL)
{
*q = malloc(sizeof(struct lnode));
tmp = *q;
} else
{
/* go to last node */
while(tmp->next != NULL)
tmp = tmp->next;

/* add node at the end */
tmp->next = malloc(sizeof(struct lnode));
tmp = tmp->next;
}

/* assign data to the last node */
tmp->data = num;
tmp->next = NULL;
}

/* print the entire linked list */
void llist_print(void) {
visit = head;

while(visit != NULL) {
printf("%d ", visit->data);
visit = visit->next;
}
printf("\n");
}

/* preform a bubble sort on the linked list */
void llist_bubble_sort(void) {
struct lnode *a = NULL;
struct lnode *b = NULL;
struct lnode *c = NULL;
struct lnode *e = NULL;
struct lnode *tmp = NULL;

/*
// the `c' node precedes the `a' and `e' node
// pointing up the node to which the comparisons
// are being made.
*/
while(e != head->next)
{
c = a = head;
b = a->next;
while(a != e)
{
if(a->data > b->data)
{
if(a == head) {
tmp = b -> next;
b->next = a;
a->next = tmp;
head = b;
c = b;
} else {
tmp = b->next;
b->next = a;
a->next = tmp;
c->next = b;
c = b;
}
} else {
c = a;
a = a->next;
}
b = a->next;
if(b == e)
e = a;
}
}
}

Related Links :

convert upper case to lower case or lower case

void main(void)
{
clrscr();
int i,j,k,l,b,n;
printf("Enter the value of N:");
scanf("%d",&n);
for(i=0;i{
printf("
");
for(l=0;l printf(" ");
for(j=i+1;j<=n;j++)
printf("%d",j);
for(k=n-1;k>i;k--)
printf("%d",k);
}
b=n-1;
for(i=0;i{
printf("
");
for(l=n-2;l>i;l--)
printf(" ");
for(j=b;j<=n;j++)
printf("%d",j);
for(k=n-1;k>=b;k--)
printf("%d",k);
b--;
}
getch();
}

Related Links :

Finding LCM and GCD In C

#include

void main()
{
int a[20],n,i,j,c,max,min;
unsigned long prod;
clrscr();
printf("Enter the no. of entries: ");
scanf("%d",&n);
printf("Enter the entries:");
for(i=0;i
{
scanf("%d",&c);
if(c>0)
a[i]=c;
else
{
printf("Invalid Entry");
return;
}
}

max=a[0];
for(i=0;i
if(a[i]>=max)
max=a[i];
min=a[0];
for(i=0;i
if(a[i]
min=a[i];

for(i=0,prod=1;i
prod=prod*a[i];

for(i=max;i<=prod;i+=max)
{

c=0;
for(j=0;j
if(i%a[j]==0)
c+=1;
if(c==n)
{
printf("The LCM of the nos: %d",i);
break;
}
}

for(i=min;i>0;i--)
{
if (min%i==0)
{
c=0;
for(j=0;j
if(a[j]%i==0)
c+=1;
}
if(c==n)
{
printf("The GCD of the nos: %d",i);
break;
}
}
getch();
}

Related Links :

INTERVIEW QUESTIONS C

Predict the output or error(s) for the following:

1.
void main()
{
int const * p=5;
printf("%d",++(*p));
}

Answer:
Compiler error: Cannot modify a constant value.
Explanation:
p is a pointer to a "constant integer". But we tried to change the
value
of the "constant integer".

2.
main()
{
char s[ ]="man";
int i;
for(i=0;s[ i ];i++)
printf("
%c%c%c%c",s[ i ],*(s+i),*(i+s),i[s]);
}
Answer:
mmmm
aaaa
nnnn

Explanation:
s[i], *(i+s), *(s+i), i[s] are all different ways of expressing the
same
idea. Generally array name is the base address for that array. Here s
is
the base address. i is the index number/displacement from the base
address. So, indirecting it with * is same as s[i]. i[s] may be
surprising. But in the case of C it is same as s[i].

3.
main()
{
float me = 1.1;
double you = 1.1;
if(me==you)
printf("I love U");
else
printf("I hate U");
}

Answer:
I hate U

Explanation:
For floating point numbers (float, double, long double) the values
cannot
be predicted exactly. Depending on the number of bytes, the precession
with of the value represented varies. Float takes 4 bytes and long
double
takes 10 bytes. So float stores 0.9 with less precision than long
double.
Rule of Thumb:
Never compare or at-least be cautious when using floating point numbers
with relational operators (== , >, <, <=, >=,!= ) .

4.
main()
{
static int var = 5;
printf("%d ",var--);
if(var)
main();
}
Answer:
5 4 3 2 1

Explanation:
When static storage class is given, it is initialized once. The change
in
the value of a static variable is retained even between the function
calls. Main is also treated like any other ordinary function, which can
be
called recursively.

5.
main()
{
int c[ ]={2.8,3.4,4,6.7,5};
int j,*p=c,*q=c;
for(j=0;j<5;j++) {
printf(" %d ",*c);
++q; }
for(j=0;j<5;j++){
printf(" %d ",*p);
++p; }
}

Answer:
2 2 2 2 2 2 3 4 6 5
Explanation:
Initially pointer c is assigned to both p and q. In the first loop,
since
only q is incremented and not c , the value 2 will be printed 5 times.
In
second loop p itself is incremented. So the values 2 3 4 6 5 will be
printed.

6.
main()
{
extern int i;
i=20;
printf("%d",i);
}

Answer:
Linker Error : Undefined symbol '_i'
Explanation:
extern storage class in the following declaration,
extern int i;
specifies to the compiler that the memory for i is allocated in some
other
program and that address will be given to the current program at the
time
of linking. But linker finds that no other variable of name i is
available
in any other program with memory space allocated for it. Hence a linker
error has occurred .

7.
main()
{
int i=-1,j=-1,k=0,l=2,m;
m=i++&&j++&&k++||l++;
printf("%d %d %d %d %d",i,j,k,l,m);
}

Answer:
0 0 1 3 1


Explanation :
Logical operations always give a result of 1 or 0 . And also the
logical
AND (&&) operator has higher priority over the logical OR (||)
operator.
So the expression ‘i++ && j++ && k++’ is executed first. The result of
this expression is 0 (-1 && -1 && 0 = 0). Now the expression is 0 ||
2
which evaluates to 1 (because OR operator always gives 1 except for ‘0
||
0’ combination- for which it gives 0). So the value of m is 1. The
values
of other variables are also incremented by 1.

8.
main()
{
char *p;
printf("%d %d ",sizeof(*p),sizeof(p));
}

Answer:
1 2

Explanation:

The sizeof() operator gives the number of bytes taken by its operand. P
is
a character pointer, which needs one byte for storing its value (a
character). Hence sizeof(*p) gives a value of 1. Since it needs two
bytes
to store the address of the character pointer sizeof(p) gives 2.

9.
main()
{
int i=3;
switch(i)
{
default:printf("zero");
case 1: printf("one");
break;
case 2:printf("two");
break;
case 3: printf("three");
break;
}
}

Answer :
three

Explanation :
The default case can be placed anywhere inside the loop. It is executed
only when all other cases doesn't match.

10.
main()
{
printf("%x",-1<<4);
}
Answer:

fff0

Explanation :
-1 is internally represented as all 1's. When left shifted four times
the
least significant 4 bits are filled with 0's.The %x format specifier
specifies that the integer value be printed as a hexadecimal value.

11.
main()
{
char string[]="Hello World";
display(string);
}
void display(char *string)
{
printf("%s",string);
}
Answer:
Compiler Error : Type mismatch in redeclaration of function display
Explanation :
In third line, when the function display is encountered, the compiler
doesn't know anything about the function display. It assumes the
arguments
and return types to be integers, (which is the default type). When it
sees
the actual function display, the arguments and type contradicts with
what
it has assumed previously. Hence a compile time error occurs.

12.
main()
{
int c=- -2;
printf("c=%d",c);
}

Answer:
c=2;

Explanation:
Here unary minus (or negation) operator is used twice. Same maths
rules
applies, ie. minus * minus= plus.
Note:
However you cannot give like --2. Because -- operator can only be
applied
to variables as a decrement operator (eg., i--). 2 is a constant and
not a
variable.

13.
#define int char
main()
{
int i=65;
printf("sizeof(i)=%d",sizeof(i));
}

Answer:
sizeof(i)=1

Explanation:
Since the #define replaces the string int by the macro char

14.
main()
{
int i=10;
i=!i>14;
printf("i=%d",i);
}
Answer:
i=0


Explanation:
In the expression !i>14 , NOT (!) operator has more precedence than ‘
>’
symbol. ! is a unary logical operator. !i (!10) is 0 (not of true is
false). 0>14 is false (zero).

Related Links :

Bubble Sorting Algorithm

#include
#include

void bubblesort(int *, const int, char);
void swap(int *, int *);


int main()
{
const int i = 10;
int a[11];
char b;
printf("Enter a number: ");
int c;
for (c=0;c<10;c++)
{
printf("%d: ",c+1);
scanf("%d",&a[c]);
}

printf("Data Items in Original Order: ");

for (c=0;c {
printf("%d",a[c]);
}

printf("Which order would you like?: ");
scanf("%s",&b);
if (b=='a')
{
bubblesort(a,i,'a');
printf("Data Items in Ascending Order: ");
for (c=0;c {
printf("%d",a[c]);
}
}
else if(b=='d')
{
bubblesort(a,i,'d');
printf("Data Items in Decending Order: ");
for (c=0;c {
printf("%d",a[c]);
}
}
printf("Thank you for using BubbleSort");
return 0;
}

void bubblesort(int * array, const int size, char order)
{

order=tolower(order);
for (int pass=1;pass {
for (int j=0;j {
if (order=='a')
{
if (array[j]>array[j+1])
{
printf("%d : ",array[j]);
printf("%d",array[j+1]);
swap(&array[j],&array[j+1]);
}
}
if (order=='d')
{
if (array[j] {
printf("%d : ",array[j]);
printf("%d",array[j+1]);
swap(&array[j],&array[j+1]);
}
}
}
}
}



void swap(int *e1, int *e2)
{
int swap=*e1;
*e1=*e2;
*e2=swap;
}

Related Links :

All types of Linked List Operations

#include
#include
#include
#include
#include
void disp(struct node*);
struct node *addbeg(struct node *,int);
void addend(struct node *,int);
void sortlist(struct node*,int);
struct node *addbef(struct node *,int);
void addaft(struct node *,int);
void addbet(struct node *,int,int);
struct node *del(struct node *,int);
struct node *befdel(struct node *,int);
void aftdel(struct node *,int);
void betdel(struct node *,int,int);
void update(struct node *,int);
void search(struct node *,int);
struct node *reverse(struct node *);
struct node{
int n;


struct node *next;

} ;
void main()
{
char ch,boolc1,boolc2,boolc3,boolc4,boolc5,boolc6,boolc7;


int
i,num,no,addb,adde,befadd,aftadd,fnode,snode,cut,befcut,aftcut,prnode,succ
node,change,find;
struct node *head,*tail,*ptr;
clrscr();
printf("THIS IS A PROGRAM ABOUT LINKED LIST");
printf("supply no. of elements in the linked list");
scanf("%d",&num);
head=tail=ptr=NULL;
for(i=0;i
{
printf("supply new node
");
scanf("%d",&no);
ptr=(struct node*)malloc(sizeof(struct node));
if(tail==NULL)
{ head=tail=ptr;
ptr->n=no;
ptr->next=NULL;
}
else
{ tail->next=ptr;
ptr->n=no;
ptr->next=NULL;
tail=ptr;
}
}
disp(head);
printf("node you want to add before");
scanf("%d",&addb);
if(addb>=0)
{
head=addbeg(head,addb);

printf("Now");
disp(head);
}
else printf("ayou don't! OK");
printf("node you want to add end");
scanf("%d",&adde);
if(adde>=0)
{
addend(head,adde);

printf("Now");
disp(head);
}
else
printf("ayou don't! OK
");
printf("before which node you want to add?");
scanf("%d",&befadd);
head=addbef(head,befadd);
printf("Now");
disp(head);
printf("after which node you want to add?");
scanf("%d",&aftadd);
addaft(head,aftadd);
printf("Now");
disp(head);
printf("between which two nodes you want to add?");
fflush(stdin);
scanf("%d %d",&fnode,&snode);
addbet(head,fnode,snode);
printf("Now");
disp(head);
printf("want to delete any node? (y/n)");
fflush(stdin);
scanf("%c",&boolc1);
if(boolc1=='y')
{
printf("supply node to be deleted
");
scanf("%d",&cut);
head=del(head,cut);
printf("Now");
disp(head);
}
else
printf("OK. list remains same
");
printf("want to delete before any node? (y/n)");
fflush(stdin);
scanf("%c",&boolc2);
if(boolc2=='y')
{
printf("supply that node
");
scanf("%d",&befcut);
head=befdel(head,befcut);
printf("Now");
disp(head);
}
else
printf("OK. list remains same
");
printf("want to delete after any node? (y/n)");
fflush(stdin);
scanf("%c",&boolc3);
if(boolc3=='y')
{ printf("supply that node
");
scanf("%d",&aftcut);
aftdel(head,aftcut);
printf("Now");
disp(head);
}
else printf("OK. list remains same");
printf("want to delete node between any two node? (y/n)");
fflush(stdin);
scanf("%c",&boolc4);
if(boolc4=='y') {
printf("supply those nodes
");
scanf("%d %d",&prnode,&succnode);
betdel(head,prnode,succnode);
printf("Now");
disp(head);
}
else
printf("OK. list remains same
");
printf("want to update any node? (y/n)");
fflush(stdin);
scanf("%c",&boolc5);
if(boolc5=='y') {
printf("supply node to be updated

");
scanf("%d",&change);
update(head,change);
printf("Now");
disp(head);
}
else
printf("OK. list remains same
");
printf("want to search any node? (y/n)");
fflush(stdin);
scanf("%c",&boolc6);
if(boolc6=='y')
{ printf("node to be searched
");
scanf("%d",&find);
search(head,find);
}
else
printf("OK. list remains same
");
printf("want to display the list in reverse order? (y/n)");
fflush(stdin);
scanf("%c",&boolc7);
if(boolc7=='y') {
printf("In reverse order");

head=reverse(head);
disp(head);
}
else
printf("OK. list remains same
");
printf("wish to sort the list? (y/n)");
fflush(stdin);
scanf("%c",&ch);
if(ch=='y')
{
sortlist(head,num);

printf("after sorting");
disp(head);
}

else
{
printf("Finally");

disp(head); }
getch();
}
void disp(struct node *head)
{ struct node *p;
p=head;
printf(" entire linked list is");
while(p->next!=NULL)
{ printf("%d->",p->n);
p=p->next;
if (p->next==NULL)
printf("%d
",p->n);
}
return;
}
void sortlist(struct node *head,int num)
{ struct node *temp,*q;
int i,j;
q=head;
temp=(struct node *)malloc(sizeof(struct node));
for(i=0;i
for(j=0;j
{ while(q->next!=NULL)
{ if((q->n)>(q->next->n))
{ temp->n=q->n;
q->n=q->next->n;
q->next->n=temp->n;
}
q=q->next;
}
if(q->next==NULL && i
q=head;
}
q=head;
return;
}
struct node *addbeg(struct node *head,int addn)
{ struct node *p;
p=(struct node *)malloc(sizeof(struct node));
p->n=addn;
p->next=head;
head=p;
return head;
}
void addend(struct node *head,int addn)
{ struct node *p,*q;
p=(struct node *)malloc(sizeof(struct node));
q=head;
while(q->next!=NULL)
q=q->next;
q->next=p;
p->n=addn;
p->next=NULL;
return;
}
struct node *addbef(struct node *head,int befadd)
{ struct node *p,*q,*r;
int addp;
printf("new node");
scanf("%d",&addp);
p=(struct node *)malloc(sizeof(struct node));
p->n=addp;
q=r=head;
while(q->n!=befadd)
{ r=q;
q=q->next;
if(q==NULL) break;
}
if(q==NULL) {
printf("anode %d not found
",befadd);
delay(1000);
return head;
}
if(q==head) { p->next=q;
head=p;
return head;
}
r->next=p;
p->next=q;
return head;
}
void addaft(struct node *head,int aftadd)
{ struct node *p,*q;
int addp;
printf("new node");
scanf("%d",&addp);
p=(struct node *)malloc(sizeof(struct node));
p->n=addp;
q=head;
while(q->n!=aftadd)
{ q=q->next;
if(q==NULL) break;
}
if(q==NULL) {
printf("anode %d not found
",aftadd);
delay(1000);
return;
}
p->next=q->next;
q->next=p;
return;
}
void addbet(struct node *head,int no1,int no2)
{ struct node *p,*q,*r,*s;
int addp;
// printf("%d %d
",*no1,*no2);
printf("new node
");
scanf("%d",&addp);
p=(struct node *)malloc(sizeof(struct node));
p->n=addp;
r=head;
q=r;
if(q->n!=no1)
{ r=q;
q=q->next;
}
else
{ if (q->next->n!=no2)
{ s=q->next;
while(s!=NULL) { s=s->next;
if(s->n==no2)
{
printf("anodes are not successive
");
delay(1000);
return;
}
}
printf("aillegal node selection");
delay(1000);
return;
}
else { q=q->next;
r->next=p;
p->next=q;
return;
}
}
while(r->n!=no1 || q->n!=no2)
{ r=q;
q=q->next;
if(q==NULL)
{
printf("aillegal node selection
");
delay(1000);
return;
}
}
r->next=p;
p->next=q;
return;
}
struct node *del(struct node *head,int cut)
{ struct node *p,*q;
p=head;
q=p;
while(p->n!=cut)
{ q=p;
p=p->next;
if(p==NULL)
{
printf("anode %d not found
",cut);
delay(1000);
return head;
}
}
if(p==head) { head=q->next;
q=head;
free(p);
return head;
}
q->next=p->next;
free(p);
return head;
}
struct node *befdel(struct node *head,int befcut)
{ struct node *p,*q;
p=head;
q=p;
while(p->next->n!=befcut)
{ q=p;
p=p->next;
if(p==NULL)
{
printf("anode %d not found
",befcut);
delay(1000);
return head;
}
}
if(p==head) { head=q->next;
q=head;
free(p);
return head;
}
q->next=p->next;
free(p);
return head;
}
void aftdel(struct node *head,int aftcut)
{ struct node *p,*q;
p=head;
q=p;
while(q->n!=aftcut)
{ q=p;
p=p->next;
if(p==NULL) { if(q->next==NULL) printf("ano node after node
%d
",aftcut);
else printf("anode %d not found
",aftcut);
delay(1000);
return;
}
}
if(q==head) p=q->next;
q->next=p->next;
free(p);
return;
}
void betdel(struct node *head,int prnode,int succnode)
{ struct node *p,*q,*r,*s;
p=head;
q=p;
if(p->n!=prnode)
{ q=p;
p=p->next;
}
else { r=p->next;
if(r->next->n!=succnode)
{ s=r->next;
while(s!=NULL) { s=s->next;
if(s->n==succnode)
{ printf("amore nodes between those nodes
");
delay(1000);
return;
}
}
printf("aillegal node selection");
delay(1000);
return;
}
else { q->next=r->next;
free(r);
return;
}
}
while(q->n!=prnode || p->next->n!=succnode)
{ q=p;
p=p->next;
if(p->next==NULL) {
printf("aillegal node selection
");
delay(1000);
return;
}
}
q->next=p->next;
free(p);
return;
}
void update(struct node *head,int change)
{ struct node *p;
int upd;
p=head;
printf("updated node");
scanf("%d",&upd);
while(p->n!=change)
{ p=p->next;
if(p==NULL) {
printf("anode %d not found
",change);
delay(1000);
return;
}
}
p->n=upd;
return;
}
void search(struct node *head,int find)
{ struct node *p;
int j=1;
p=head;
while(p->n!=find)
{ p=p->next;
j++;
if(p==NULL) {
printf("

SORRY. node %d is not present",find);
delay(1000);
return;
}
}
printf("aYES! the node %d is present in the %dth position",find,j);
delay(1000);
return;
}
struct node *reverse(struct node *head)
{ struct node *t1,*t2;
t1=head->next;
t2=t1->next;
head->next=NULL;
while(t1!=NULL)
{ t1->next=head;
head=t1;
t1=t2;
t2=t2->next;
}
return head;
}

Related Links :


If you face any Problem in viewing code such as Incomplete "For Loops" or "Incorrect greater than or smaller" than equal to signs then please collect from My Web Site CLICK HERE


More Useful Topics...

 

History Of C..

In the beginning was Charles Babbage and his Analytical Engine, a machine
he built in 1822 that could be programmed to carry out different computations.
Move forward more than 100 years, where the U.S. government in
1942 used concepts from Babbage’s engine to create the ENIAC, the first
modern computer.
Meanwhile, over at the AT&T Bell Labs, in 1972 Dennis Ritchie was working
with two languages: B (for Bell) and BCPL (Basic Combined Programming
Language). Inspired by Pascal, Mr. Ritchie developed the C programming
language.

My 1st Program...


#include
#include
void main ()
{
clrscr ();
printf ("\n\n\n\n");
printf ("\t\t\t*******Pankaj *******\n");
printf ("\t\t\t********************************\n");
printf ("\t\t\t\"Life is Good...\"\n");
printf ("\t\t\t********************************");
getch ();
}

Next Step...


#include
#include

void main ()
{
clrscr ();
printf ("\n\n\n\n\n\n\n\n");
printf ("\t\t\t --------------------------- \n\n");

printf ("\t\t\t | IGCT, Info Computers, INDIA | \n\n");
printf ("\t\t\t --------------------------- ");

getch ();

}

Hits!!!