Sunday, 26 July 2009

C programming mind blowing Questions and answers

1.What will be the output of the following code?

void main ()
{ int i = 0 , a[3] ;
a[i] = i++;
printf ("%d",a[i]) ;
}
Ans: The output for the above code would be a garbage value. In the statement a[i] = i++; the value of the variable i would get assigned first to a[i] i.e. a[0] and then the value of i would get incremented by 1. Since a[i] i.e. a[1] has not been initialized, a[i] will have a garbage value.

-------------------------------------------------------------------------------------------------
2.
Why doesn't the following code give the desired result?

int x = 3000, y = 2000 ;
long int z = x * y ;
Ans: Here the multiplication is carried out between two ints x and y, and the result that would overflow would be truncated before being assigned to the variable z of type long int. However, to get the correct output, we should use an explicit cast to force long arithmetic as shown below:

long int z = ( long int ) x * y ;
Note that ( long int )( x * y ) would not give the desired effect.

-------------------------------------------------------------------------------------------------
3.
Why doesn't the following statement work?

char str[ ] = "Hello" ;
strcat ( str, '!' ) ;

Ans: The string function strcat( ) concatenates strings and not a character. The basic difference between a string and a character is that a string is a collection of characters, represented by an array of characters whereas a character is a single character. To make the above statement work writes the statement as shown below:
strcat ( str, "!" ) ;

-------------------------------------------------------------------------------------------------
4.
How do I know how many elements an array can hold?

Ans: The amount of memory an array can consume depends on the data type of an array. In DOS environment, the amount of memory an array can consume depends on the current memory model (i.e. Tiny, Small, Large, Huge, etc.). In general an array cannot consume more than 64 kb. Consider following program, which shows the maximum number of elements an array of type int, float and char can have in case of Small memory model.
main( )
{
int i[32767] ;
float f[16383] ;
char s[65535] ;
}
-------------------------------------------------------------------------------------------------

5. How do I write code that reads data at memory location specified by segment and offset?

Ans: Use peekb( ) function. This function returns byte(s) read from specific segment and offset locations in memory. The following program illustrates use of this function. In this program from VDU memory we have read characters and its attributes of the first row. The information stored in file is then further read and displayed using peek( ) function.

#include
#include

main( )
{

char far *scr = 0xB8000000 ;
FILE *fp ;
int offset ;
char ch ;

if ( ( fp = fopen ( "scr.dat", "wb" ) ) == NULL )
{

printf ( "\nUnable to open file" ) ;
exit( ) ;

}

// reads and writes to file
for ( offset = 0 ; offset < 160 ; offset++ )
fprintf ( fp, "%c", peekb ( scr, offset ) ) ;
fclose ( fp ) ;

if ( ( fp = fopen ( "scr.dat", "rb" ) ) == NULL )
{

printf ( "\nUnable to open file" ) ;
exit( ) ;

}

// reads and writes to file
for ( offset = 0 ; offset < 160 ; offset++ )
{

fscanf ( fp, "%c", &ch ) ;
printf ( "%c", ch ) ;

}

fclose ( fp ) ;

}





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("\n%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) Printf can be implemented by using __________ list.

Answer:
Variable length argument lists

4) char *someFun()
{
char *temp = "string constant";
return temp;
}
int main()
{
puts(someFun());
}

Answer:
string constant

Explanation:
The program suffers no problem and gives the output correctly because the character
constants are stored in code/data area and not allocated in stack, so this doesn't lead to
dangling pointers.

5) char *someFun1()
{
char temp[ ] = "string";
return temp;
}
char *someFun2()
{
char temp[ ] = {'s', 't','r','i','n','g'};
return temp;
}
int main()
{
puts(someFun1());
puts(someFun2());
}

Answer:
Garbage values.

Explanation:
Both the functions suffer from the problem of dangling pointers. In someFun1() temp
is a character array and so the space for it is allocated in heap and is initialized with character
string "string". This is created dynamically as the function is called, so is also deleted
dynamically on exiting the function so the string data is not available in the calling function
main() leading to print some garbage values. The function someFun2() also suffers from the
same problem but the problem can be easily identified in this case.

6) main()
{
char a[4]="HELL";
printf("%s",a);
}

Answer:
HELL%@!~@!@???@~~!

Explanation:
The character array has the memory just enough to hold the string "HELL"
and doesnt have enough space to store the terminating null character. So it
prints the HELL correctly and continues to print garbage values till it
accidentally comes across a NULL character.

7) main()
{
int a=10,*j;
void *k;
j=k=&a;
j++;
k++;
printf("\n %u %u ",j,k);
}

Answer:
Compiler error: Cannot increment a void pointer

Explanation:
Void pointers are generic pointers and they can be used only when the type
is not known and as an intermediate address storage type. No pointer
arithmetic can be done on it and you cannot apply indirection operator (*) on
void pointers.

8) void main()
{
char ch;
for(ch=0;ch<=127;ch++)
printf("%c %d \n", ch, ch);
}

Answer:
Implementaion dependent

Explanation:
The char type may be signed or unsigned by default. If it is signed then ch++
is executed after ch reaches 127 and rotates back to -128. Thus ch is always
smaller than 127.

9) Is this code legal?
int *ptr;
ptr = (int *) 0x400;

Answer:
Yes

Explanation:
The pointer ptr will point at the integer in the memory location 0x400.

10) Is the following code legal?
typedef struct a aType;
struct a
{
int x;
aType *b;
};

Answer:
Yes

Explanation:
The typename aType is known at the point of declaring the structure,
because it is already typedefined.

11) Is the following code legal?
void main()
{
typedef struct a aType;
aType someVariable;
struct a
{
int x;
aType *b;
};
}

Answer:
No

Explanation:
When the declaration,
typedef struct a aType;
is encountered body of struct a is not known. This is known as 'incomplete
types'.

12) Is the following code legal?
struct a
{
int x;
struct a b;
}

Answer:
No

Explanation:
Is it not legal for a structure to contain a member that is of the same
type as in this case. Because this will cause the structure declaration to be
recursive without end.

13) Is the following code legal?
struct a
{
int x;
struct a *b;
}

Answer:
Yes.

Explanation:
*b is a pointer to type struct a and so is legal. The compiler knows, the size of
the pointer to a structure even before the size of the structure
is determined(as you know the pointer to any type is of same size). This type
of structures is known as 'self-referencing' structure

14) What is wrong with the following code?
int *foo()
{
int *s = malloc(sizeof(int)100);
assert(s != NULL);
return s;
}

Answer & Explanation:
assert macro should be used for debugging and finding out bugs. The check
s != NULL is for error/exception handling and for that assert shouldn't be
used. A plain if and the corresponding remedy statement has to be given.

15) There were 10 records stored in "somefile.dat" but the following program printed 11
names. What went wrong?
void main()
{
struct student
{
char name[30], rollno[6];
}stud;
FILE *fp = fopen("somefile.dat","r");
while(!feof(fp))
{
fread(&stud, sizeof(stud), 1 , fp);
puts(stud.name);
}
}

Explanation:
fread reads 10 records and prints the names successfully. It will
return EOF only when fread tries to read another record and fails
reading EOF (and returning EOF). So it prints the last record again.
After this only the condition feof(fp) becomes false, hence comes out
of the while loop.


11. How do I write code to retrieve current date and time from the system and display it as a string?

Ans: Use time( ) function to get current date and time and then ctime( ) function to display it as a string. This is shown in following code snippet.

#include

void main( )
{
time_t curtime ;
char ctm[50] ;

time ( &curtime ) ; //retrieves current time &
stores in curtime
printf ( "\nCurrent Date & Time: %s", ctime (
&curtime ) ) ;
}

-------------------------------------------------------------------------------------------------
12.
How do I change the type of cursor and hide a cursor?

Ans: We can change the cursor type by using function _setcursortype( ). This function can change the cursor type to solid cursor and can even hide a cursor. Following code shows how to change the cursor type and hide cursor.

#include
main( )
{
/* Hide cursor */
_setcursortype ( _NOCURSOR ) ;

/* Change cursor to a solid cursor */
_setcursortype ( _SOLIDCURSOR ) ;

/* Change back to the normal cursor */
_setcursortype ( _NORMALCURSOR ) ;
}
-------------------------------------------------------------------------------------------------
13.
How do I write code that would get error number and display error message if any standard error occurs?

Ans: Following code demonstrates this.

#include
#include
#include

main( )
{
char *errmsg ;
FILE *fp ;
fp = fopen ( "C:\file.txt", "r" ) ;
if ( fp == NULL )
{
errmsg = strerror ( errno ) ;
printf ( "\n%s", errmsg ) ;
}
}
Here, we are trying to open 'file.txt' file. However, if the file does not exist, then it would cause an error. As a result, a value (in this case 2) related to the error generated would get set in errno. errno is an external int variable declared in 'stdlib.h' and also in 'errno.h'. Next, we have called sterror( ) function which takes an error number and returns a pointer to standard error message related to the given error number.
-------------------------------------------------------------------------------------------------
14.
How do I write code to get the current drive as well as set the current drive?

Ans: The function getdisk( ) returns the drive number of current drive. The drive number 0 indicates 'A' as the current drive, 1 as 'B' and so on. The Setdisk( ) function sets the current drive. This function takes one argument which is an integer indicating the drive to be set. Following program demonstrates use of both the functions.

#include

main( )
{
int dno, maxdr ;

dno = getdisk( ) ;
printf ( "\nThe current drive is: %c\n", 65 + dno
) ;

maxdr = setdisk ( 3 ) ;
dno = getdisk( ) ;
printf ( "\nNow the current drive is: %c\n", 65 +
dno ) ;
}
-------------------------------------------------------------------------------------------------
15.
The functions memcmp( ) and memicmp( )

The functions memcmp( ) and memicmp( ) compares first n bytes of given two blocks of memory or strings. However, memcmp( ) performs comparison as unsigned chars whereas memicmp( ) performs comparison as chars but ignores case (i.e. upper or lower case). Both the functions return an integer value where 0 indicates that two memory buffers compared are identical. If the value returned is greater than 0 then it indicates that the first buffer is bigger than the second one. The value less than 0 indicate that the first buffer is less than the second buffer. The following code snippet demonstrates use of both

#include
#include

main( )
{
char str1[] = "This string contains some
characters" ;
char str2[] = "this string contains" ;
int result ;

result = memcmp ( str1, str2, strlen ( str2 ) ) ;
printf ( "\nResult after comapring buffer using
memcmp( )" ) ;
show ( result ) ;

result = memicmp ( str1, str2, strlen ( str2 ) ) ;
printf ( "\nResult after comapring buffer using
memicmp( )" ) ;
show ( result ) ;
}

show ( int r )
{
if ( r == 0 )
printf ( "\nThe buffer str1 and str2 hold
identical data" ) ;
if ( r > 0 )
printf ( "\nThe buffer str1 is bigger than buffer
str2" ) ;
if ( r < 0 )
printf ( "\nThe buffer str1 is less than buffer
str2" ) ;
}

0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More