Thursday, March 24, 2011

difference between far and huge pointers

as we know by default the pointers are near for example int *p is a near pointer... size of near pointer is 2 bytes in case of 16 bit compiler........ n we already know very well size varies compiler to compiler...... They only store the offset of the address the pointer is referencing. . An address consisting of only an offset has a range of 0 - 64K bytes.... i think there is no need to discuss near pointers anymore.... so come to the main point..... that is far and huge pointers......

far and huge pointers:
Far and huge pointers have a size of 4 bytes. They store both the segment and the offset of the address the pointer is referencing. thn what is the difference between them ...........

Limitation of far pointer:

We cannot change or modify the segment address of given far address by applying any arithmetic operation on it. That is by using arithmetic operator we cannot jump from one segment to other segment. If you will increment the far address beyond the maximum value of its offset address instead of incrementing segment address it will repeat its offset address in cyclic order. this is also called wrapping.....i.e. if offset is 0xffff and we add 1 then it is 0x0000 and similarly if we decrease 0x0000 by 1 then it is 0xffff and remember there is no change in the segment....

Now i am going to compare huge and far pointers..........

1.
When a far pointer is incremented or decremented ONLY the offset of the pointer is actually incremented or decremented but in case of huge pointer both segment and offset value will change.....
like if we have

int main()
{
char far* f=(char far*)0x0000ffff;
printf("%Fp",f+0x1);
return 0;
}

then the output is:
0000:0000

as we see there is no change in segment value.......

and in case of huge........

int main()
{
char huge* h=(char huge*)0x0000000f;
printf("%Fp",h+0x1);
return 0;
}

then the o/p is:
0001:0000

it shows bcoz of increment operation not only offset value but segment value also change.......... that means segment will not change in case of far pointers but in case of huge it can move from one segment to another ......

2.
When relational operators are used on far pointers only the offsets are compared.In other words relational operators will only work on far pointers if the segment values of the pointers being compared are the same. and in case of huge this will not happen, actually comparison of absolute addresses takes place...... lets understand with the help of an example...
in far...............................

int main()
{
char far * p=(char far*)0x12340001;
char far* p1=(char far*)0x12300041;
if(p==p1)
printf("same");
else
printf("different");
return 0;
}

Output:
different

in huge.......................

int main()
{
char huge * p=(char huge*)0x12340001;
char huge* p1=(char huge*)0x12300041;
if(p==p1)
printf("same");
else
printf("different");
return 0;
}

Output:
same

Explanation:
as we see the absolute address for both p and p1 is 12341 (1234*10+1 or 1230*10+41) but they are not considered equal in 1st case becoz in case of far pointers only offsets are compared i.e. it will check whether 0001==0041.... that we know is false.... and know see what will happen in case of huge.....the comparison operation is performed on absolute addresses that are equal as i already told......

3.
A far pointer is never noramlized but a huge pointer is normalized . A normalized pointer is one that has as much of the address as possible in the segment, meaning that the offset is never larger than 15.
suppose if we have 0x1234:1234 then the normalized form of it is 0x1357:0004(absolute address is 13574).......
A huge pointer is normalized only when some arithmetic operation is performed on it ... and not noramlized during assignment....

int main()
{
char huge* h=(char huge*)0x12341234;
char huge* h1=(char huge*)0x12341234;
printf("h=%Fp\nh1=%Fp",h,h1+0x1);
return 0;
}

Output:
h=1234:1234
h1=1357:0005

Explanation:
as i said above huge is not normalized in case of assignment......but if an arithmetic operation is performed on it ..... it will be normalized.... so h is 1234:1234 and h1 is 1357:0005..........that is normalized.......

4.
The offset of huge pointer is less than 16 because of normalization and not so in case of far pointers...................

lets take an example to understand what i want to say.....
int main()
{
char far* f=(char far*)0x0000000f;
printf("%Fp",f+0x1);
return 0;
}

Output:
0000:0010

in case of huge
int main()
{
char huge* h=(char huge*)0x0000000f;
printf("%Fp",h+0x1);
return 0;
}

Output:
0001:0000

Explanation:
as we increment far pointer by 1 it will be 0000:0010...... and as we increment huge pointer by 1 thn it will be 0001:0000 bcoz its offset cant be greater than 15 in other words it will be normalized............

i tried my best to explain this...... if any query and suggestion plz comment here.........

Friday, March 18, 2011

difference between typedef and #define

lets have a look at whats the difference between typedef and #define.....

A typedef is just a new name for an already existing type and defines are handled by the preprocessor while typedefs are handled by the C compiler itself.
#define can be used to rename anything not just a type like typedef.................for e.g.

#define AND && and we cant use typedef for that like typedef && AND; its not possible with typedef...... some more examples like #define PRINT printf("hello") or #define sum(a,b) (a+b)....all this is not possible with typedef...................

we all know this very well so i am not going to explain this but what will happen if we use #define to rename a type................

suppose if we have
typedef char * ptr;
#define PTR char *

both of them are looking similar......


lets understand the difference with the help of an example............

typedef char * ptr;
#define PTR char *
int main()
{
ptr a,b,c;
PTR x,y,z;
printf( "sizeof a:%u\n" ,sizeof(a) );
printf( "sizeof b:%u\n" ,sizeof(b) );
printf( "sizeof c:%u\n" ,sizeof(c) );
printf( "sizeof x:%u\n" ,sizeof(x) );
printf( "sizeof y:%u\n" ,sizeof(y) );
printf( "sizeof z:%u\n" ,sizeof(z) );
return 0;
}

Output:
sizeof a:2
sizeof b:2
sizeof c:2
sizeof x:2
sizeof y:1
sizeof z:1

Explanation:
in case of turbo C compiler the size of pointer is 2 and in other compilers it is different it may be 4 like in dev compiler .........thats not our point of discussion.....we have to discuss why is there such output.........

Note that y and z do not have the same size as the x whereas a,b and c are consistent. Why is this? Simple: we used a macro for x y and z.

Look at what the macro actually does:

#define PTR char *

PTR x,y, z;
This is in turn converted (by simple text substitution) to:
char *x ,y, z;
That line does not define three pointer variables. It defines three variables with a base type of "char" one of which x is a pointer. It is the same as writing:
char *x;
char y;
char z;
The typedef dont fail this way because when we defined the new type we defined it specifically as a pointer type meaning that any variable defined with the new type will in fact be a pointer variable.......

\xhh hexadecimal number

lets understand the use of \xhh escape sequence with the help of some interesting examples
here hh is one or more hexadecimal digits(0....9,a...f,A...F).......firstly understand the meaning of one or more characters...it means there can be any no. of hexadecimal digits after \x.....

1.
int main()
{
char *s="A\x3a";
printf("%s",s);
return 0;
}

Output:
A:

Explanation:
here '\x3a' is a hexadecimal number n it is a single char....... firstly it will get converted in to decimal notation i.e. 58 and it is the ASCII value of char ':' hence at the place of \x3a there is :........................ so the output is A:............

2.
int main()
{
char *s="A\x003a";
printf("%s",s);
return 0;
}

Output:
A:

Explanation:
decimal notation of 003a is 58.................here i m trying to show there can b any no. of hexadecimal digits after \x...............

3.
#define new '\xa'
int main()
{
printf("A%c",new);
return 0;
}

Explanation:
here the output is A n the cursor is in the next line bcoz as we know the ascii value of new line character is 10.................so very interesting there is one more escape sequence to do the work of new line character..................

\ooo octal number

lets understand the use of \ooo escape sequence with the help of some interesting examples
here ooo is one to three octal digits(0....7) means there must be atleast one octal digit after \ and maximum three..........
1.
int main()
{
char *s="A\0655";
printf("%s",s);
return 0;
}

Output:
A55

Explanation:
its very interesting to know the reason behind such output.......here 065 is the octal notation....... firstly it will get converted in to decimal notation i.e. 53 and it is the ASCII value of char '5' hence at the place of \065 there is 5........................ so the output is A55............

okay,lets understand it with 1 more example.....

2.
int main()
{
char *s="A\035B";
printf("%s",s);
return 0;
}

Output:
A<->B

Explanation:
decimal notation of 035 is 29.................n it is the ASCII value of '<->' char.......... hence the output is A<->B........................

2.
int main()
{
char *s="A\33A";
printf("%s",s);
return 0;
}

Output:
A<-A

Explanation:
decimal notation of 33 is 27.................n it is the ASCII value of '<-' char.......... hence the output is A<-A........................it shows octal number can have two octal digits also.............similarly there can be only 1 octal digit.................

try for different strings......its really amazing.................

Thursday, March 17, 2011

getche() vs getchar()........

let us try to u nderstand this by the help of an example.....just write a program to enter you name and print that on the screen.....everyone can write that program so easily.....

void main()
{
char c[15];
printf("enter your name:");
scanf("%s",c);
printf("\nyour name is:%s",c);
getche();
}

output:
enter yourname:milan
your name is :milan

this runs fine ,and wait for the character on the getche() function call as expected....

Now,chnage the getche() to getchar()

void main()
{
char c[15];
printf("enter your name:");
scanf("%s",c);
printf("\nyour name is:%s",c);
getchar();
}

after running with getchar() you willl find that it does not wait for the character and output screen goes away....
why it is so????
Explanation:
this happens because the mechanism of getche() and getchar() is different..
1.)getche() directly takes the input directly from the input stream and getchar() reads that from the input buffer....
2.)getche() does not wait for the enter key and getchar() wait for hte enter key....

Now we enter our name and press enter that enter goes as the input for the getchar() function....let us prove this.......
void main()
{
char c[15],d;
 printf("enter your name:");
scanf("%s",c);
printf("\nyour name is:%s",c);
d=getchar();
printf("the ASCII value of enter key is %d and it is true",d);
getch();
}

output:
enter your name:milan
your name is:milan
the ASCII value of enter key is 10 and it is true.....

so u can see the enter pressed after entering the name goes as the input to the getchar() function.....

solution to this problem:
use the fflush function withe the input stream from where you are reading the data that is generally stdin (standard input).....it will clear the input stream buffer and now getchar() will wait ......
check this:
void main()
{
char c[15];
printf("enter your name:");
scanf("%s",c);
printf("\nyour name is:%s",c);
fflush(stdin);
getchar();
}


another example which proves that getchar() waits for the enter key and takes the first character int the buffer after pressing the enter........

#include<stdio.h>
#include<conio.h>
void main()
{
char a,b,c;
clrscr();
printf("Enter a charater-->");
a=getche();
printf("\nThe character pressed is :%c",a);
printf("\nNow enter the another charater-->");
b=getchar();
printf("Now the character pressed is:%c",b);
getch();
}

output:
Enter a character-->m /*here you can enter only one character coz getch directly interact with input device*/
The character pressed is:m
Now enter the another character-->milan  /*here you can ebter any number of character ,all get stored int he buffer and after pressing enter the first character is taken as the input to the gatchar()*/
Now the character pressed is:m


Monday, March 14, 2011

successful input means...........

as i said in my what scanf() returns????? post................. scanf returns the number of successful inputs.................... here i am going to explain what is the meaning of successful inputs..........

It return the number of input items successfully matched (means read attempt is unsuccessful if the input characters cannot be converted according to the given format code) and assigned......................
the return value does not include fields that were read but not assigned.....
A return value of zero indicates that no fields were assigned.

lets understand with the help of some examples............

int main()
{
int i;
char *s;
printf("Enter the string:");
i=scanf("%[012356789]",s);
printf("i=%d",i);
return 0;
}

Output:
Enter the string:hello
i=0

Explanation:
in the above example the string s can take only numbers and not any other character...............so when we input hello ............ scanf reads the characters but nothing is assigned to string s, hence scanf returns 0 at the place of 1......................


int main()
{
int i,j;
printf("Enter the number:");
i=scanf("%d",&j);
printf("i=%d",i);
return 0;
}

Output:
Enter the number:h
i=0

Explanation:
scanf is trying to read an int, but it receives the letter 'h' at the place of some number, hence it will return 0 at the place of 1............... and it doesn't mean nothing is assigned to i..............

Saturday, March 12, 2011

Reading and discarding characters in scanf()

Reading and discarding characters from the input stream

1.
int main()
{
int month,day,year;

printf( "Enter a date in the form mm-dd-yyyy: " );
scanf( "%d%*c%d%*c%d", &month, &day, &year );

printf( "month = %d day = %d year = %d\n\n", month, day, year );
return 0;
}

Output:
Enter a date in the form mm-dd-yyyy:03-12-2011
month = 03 day = 12 year = 2011

Explanation:
as we write the input:03-12-2011
scanf discards the character - because we used %*c to discard that character...there can be any character at the place of -...............

2.
int main()
{
int i,j;

printf( "Enter the numbers: " );
scanf( "%d/*/%d", &i,&j );

printf( "%d %d", i,j);
return 0;

}

output:
Enter the numbers:4/*/5
4 5

Explanation:
now we enter the numbers in this format 4/*/5 because scanf( "%d/*/%d", &i,&j ) consist /*/, and it discards this................ so i = 4 and j = 5..............

*****************************************

lets take one more example with field width and *

int main()

{

int a,b;

scanf("%d%*4c%d",&a,&b);

printf("a=%d,b=%d",a,b);

return 0;

}

/*before discussing its output.....firstly understand wht %*4c will do.......it will discard the 4 characters from the input string........*/

OUTPUT:

12abcd34

a=12

b=34

Explanation:

as the input string is 12abcd34.....the scanf start reading the characters 1..2..a.. as 'a' comes it start discarding the characters......n discard 4 characters continuously and then remaining characters i.e. 34 are in b variable....n suppose if d input string is 12abcde thn b has some garbage value........bcoz 'e' will not match with %d................

%[] explored

%[] consists a set of characters
The left bracket is followed by a set of characters and a right square bracket. The characters between the brackets define a set of characters making up the string. If the first character is not a circumflex (^), the input field consists of all subsequent input characters until the function finds a character not in the character set within the brackets.

void main()
{
char *s;
printf("enter the string:");
scanf("%[0123456789]",s);
printf("%s",s);
}

output:
enter the string:345y678
345

Explanation:
the var s consists 345 because y is not in the character set hence dont take no more characters from y. the above program shows the string can contain only the numbers.....

**********************
If the first character inside the square brackets is a circumflex, the input field consists of all subsequent input characters until the function finds a character that is in the bracketed character set. Thus
lets understand it with the help of an example:
void main()
{
char *s;
printf("enter the string:");
scanf("%[^0123456789]",s);
printf("%s",s);
}

output:
enter the string:sheetal7garg
sheetal

Explanation:
in the above program, string s can't contain any number......... it takes the characters until a number comes.......as in the example input is sheetal7garg and in character set there is [^0123456789] hence take the characters until 7 comes........... hence s contains sheetal.................
**************************************
One more example to understand it......

void main()
{
char *s1,*s2;
printf("enter the string:");
scanf("%5[^abc]%s",s1,s2);
printf("s1=%s\ns2=%s",s1,s2);
}

lets see different outputs....
1.
enter the string:welcome
s1=welco
s2=me

2.
enter the string:india
s1=indi
s2=a

Explanation:
in
scanf("%5[^abc]%s",s1,s2);
%5[^abc] means string s1 can store max 5 characters and does not take a,b or c characters as shown in 1st output s1 consist welco and also the remaining characters i.e. 'm','e' go in s2 string.........................similarly,in 2nd output s1 take characters i,n,d,i and stop when 'a' comes, then 'a' character is in s2 and if there are more characters after 'a' , all these also in s2...........

what scanf returns?????

scanf() returns the number of variables that were successfully assigned values means the number of successful inputs.

lets try to understand more clearly with the help of an example:

void main()
{
int i,j,k;
printf("Enter the values:");
i=scanf("%d%d",&j,&k);
printf("value of i=%d",i);
}

output:
Enter the values:12 13
value of i=2

Saturday, March 5, 2011

Use of static variable

use of static variables:

as all of u are familiar with static variables, its a storage class. i am just explaining the use of static variable with the help of an example.

int *f()

{

int i=20;

return(&i);

}

void main()

{

int *ptr;

ptr=f();

printf(“%d”,*ptr);

getch();

}

Its output is 20. but if the program is this

int *f()

{

int i=20;

return(&i);

}

void main()

{

int *ptr;

ptr=f();

printf(“%u”,ptr);

printf(“%d”,*ptr);

getch();

}

I think the output will be some address and 20

But at the place of 20,it has some garbage value…………

Why so………….

But if the storage class of i is static like

int *f()

{

static int i=20;

return(&i);

}

void main()

{

int *ptr;

ptr=f();

printf(“%u”,ptr);

printf(“%d”,*ptr);

getch();

}

Then the output is some address and 20………

Explanation:

When we call any function immediately after calling f() function .then printf(“%d”,*ptr); prints garbage value except 20… in the first case, when control returned from f() though variable i went dead but it was still left on the stack. We then access this value using its address that was in ptr… but when we precede the call to printf by a call to any other function as I did in 2nd printf(“%u”,ptr); printf(“%d”,*ptr); the stack is now changed, hence we get the garbage value…. If we want to get the correct value each time then must declare var i as static . by doing this when the control returns from f(), var i will not die………..