1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.

Friday, October 16, 2009

Calender Program in C

Calender Program in C

//Program to display calender for a given year


#include // here stdio.h
#include // here conio.h
#include // here process.h
#include // here ctype.h

unsigned long days=0;
//stores the days elapsed since 01.01.1899
void display(int n)
//contains the number of days to display
{
int i, column, k, flag=0, j;
printf("Sun Mon Tues Wed Thur Fri Sat
");
for(i=1; i<=n; i++)
{
k=days%7;//remainder gives the starting day of each month
if(flag==0)
{
for(j=1; j<=k; j++)//controls tabs of first week
printf(" ");
flag=1;//ensures that block is only executed once
column=k;
}
printf("%d ", i);
column++;
if(column%7==0)//prints new line at the end of each week
printf("
");
}
printf("
Press any key to continue

");
getch();
}

void calculate(int year)
//function calculates no. of days elapsed since 1899
{
int i, month;
for(i=1899; i //1899 chosen because Jan 1, 1899 is a Sunday
{
if((i%400==0)?1:((i%100==0)?0:((i%4==0)?1:0)))

/*This is because a leap year does not strictly fall on every
fourth year. If a year is divisible by 4, then it is a leap
year, but if that year is divisible by 100, then it is
not a leap year. However, if the year is also divisible by
400, then it is a leap year. Eg: 1900 is not a leap year*/

days+=366;
else
days+=365;
}
for(month=1; month<=12; month++)
{
printf("


");
switch(month)
/*switch case used to display each month and
increment no. of days*/
{
case 1: printf(" JANUARAY %d

", year);
display(31);
days+=31;
break;
case 2: printf(" FEBURARY %d

", year);
if((year%400==0)?1:((year%100==0)?0:((year%4==0)?1:0)))
{
display(29);
days+=29;
}
else
{
display(28);
days+=28;
}
break;
case 3: printf(" MARCH %d

", year);
display(31);
days+=31;
break;
case 4: printf(" APRIL %d

", year);
display(30);
days+=30;
break;
case 5: printf(" MAY %d

", year);
display(31);
days+=31;
break;
case 6: printf(" JUNE %d

", year);
display(30);
days+=30;
break;
case 7: printf(" JULY %d

", year);
display(31);
days+=31;
break;
case 8: printf(" AUGUST %d

", year);
display(31);
days+=31;
break;
case 9: printf(" SEPTEMBER %d

", year);
display(30);
days+=30;
break;
case 10: printf(" OCTOBER %d

", year);
display(31);
days+=31;
break;
case 11: printf(" NOVEMBER %d

", year);
display(30);
days+=30;
break;
case 12: printf(" DECEMBER %d

", year);
display(31);
days+=31;
break;
}
}
}

void main()
{
char ch[10];
int i, year, choice;
do
{
clrscr();
days=0;
printf("Enter the year in 'yyyy' format:
");
scanf("%s", ch);//stores input first as a string
for(i=0; i if(ch[i]<'0' || ch[i]>'9')//checks for invalid inputs
{
printf("

Invalid Year!");
printf("

END OF PROGRAM");
getch();
exit(0);
}
year = atoi(ch);
//converts the year from string to integer datatype
clrscr();
printf("

Calender for Year %d", year);
printf("
**********************

");
calculate(year);
//calls function to calculate no. of days elapsed

printf("
*******************************************
");
printf("

Press 1 to continue, 2 to exit
");
scanf("%d", &choice);
}while(choice==1);
clrscr();
printf("

END OF PROGRAM");
getch();
}

Calender

Calender

#include"stdio.h"
#include"conio.h"
#include // here dos.h
#include // here stdlib.h
#include // here iostream.h
int month(int,int,int);
int yea(int);
void cal(int,int);
void print(int,int);
void main()
{

int g,year,h;
char ch,mu='y';
clrscr();
mos:
clrscr();
cout<<" INSTRUCTION FOR FINDING MONTH OF ANY YEAR";
cout<<"

ENTER MONTH IN LETTER AND YEAR ONWARDS 0000";
cout<<"

CALENDER";
printf("
PLEASE ENTER MONTH:=");
scanf("%d",&g);
printf("
NOW ENTER YEAR:=");
scanf("%d",&year);
printf("
FIND");
for(h=0;h<=3;h++)
{
printf(" .");
delay(100);
}
cal(g,year);
while(mu=='y')
{
ch=getch();
if(ch=='n')
{
if(g==12)
{
year+=1;
g=1;
cal(g,year);
}
g+=1;
cal(g,year);
}
else if(ch=='p')
{

if(g==1)
{
year-=1;
g=13;
cal(g,year);
}
g-=1;
cal(g,year);
}
else if(ch=='m')
{
year+=1;
cal(g,year);
}
else if(ch=='b')
{
year-=1;
cal(g,year);
}
else if(ch=='c')
goto mos;
else if(ch=='q')
{
exit(0);
}
}
fflush(stdin);
getch();
}
void cal(int g,int year)
{

int n,o,i;
clrscr();
cout<<"

TO FIND NEXT YEAR PRESS M";
cout<<"

TO FIND PREVIOUS YEAR PRESS B";
cout<<"

TO FIND NEXT MONTH PRESS N";
cout<<"

TO FIND PREVIOUS MONTH PRESS P";
cout<<"

TO EXIT PRESS Q";
printf("

MONTH %d",g);
printf("

YEAR %d",year);
n=yea(year);
o=month(g,year,n);
if((g==1)||(g==3)||(g==5)||(g==7)||(g==8)||(g==10)||(g==12))
{
print(31,o);
}
else if((g==4)||(g==6)||(g==9)||(g==11))
{
print(30,o);
}
else if(g==2)
{
if(year%4==0)
print(29,o);
else
print(28,o);
}
}
int yea(int year)
{
int i,k,n;
unsigned long int m,j;
for(i=0;i {
if(i%4==0)
{
m=m+366;
}
else
m=m+365;
}
j=m+7;
k=j%7;
n=k%7;
switch(n)
{
case 0:
n=1;
break;
case 1:
n=2;
break;
case 2:
n=3;
break;
case 3:
n=4;
break;
case 4:
n=5;
break;
case 5:
n=6;
break;
case 6:
n=0;
break;
}
return(n);
}
int month(int g,int year,int n)
{
int j,o;
for(j=1;j {
if((j==1)||(j==3)||(j==5)||(j==7)||(j==8)||(j==10))
n=n+31;
else if((j==4)||(j==6)||(j==9)||(j==11))
n=n+30;
else if(j==2)
{
if(year%4==0)
{
n=n+29;
continue;
}
else
n=n+28;
continue;
}
}
o=n%7;
return(o);
}
void print(int p,int q)
{
int i,j,l=0;
printf("


");
printf("MON TUE WED THU FRI SAT SUN
");
while(l!=q)
{
printf(" ");
l++;
}
for(i=1;i<=p;i++)
{
printf("%d ",i);
q++;
if(q==7)
{
printf("
");
q=0;
}
}
}

Calendar Program

Calendar Program

#include // here conio.h

int day(int m1,int y1)
{
int d;
if(m1==1 || m1==3 || m1==5 || m1==7 || m1==8 || m1==10 || m1==12)
d=31;
else if(m1==4 || m1==6 || m1==9 || m1==11)
d=30;
else if((y1%100!=0 && y1%4==0) || y1%400==0)
d=29;
else
d=28;
return d;
}

void main()
{
long unsigned int t;
unsigned int y,y1,m,m1,d,da,i,j,k;
char
a[12][20]={"January","February","March","April","May","June","July","Augus
t","September","October","November","December"};
clrscr();
textcolor(CYAN);
cprintf("Enter the year: ");
scanf("%4u",&y);
if(y<0)
y=-y;
cprintf("
Enter the month: ");
scanf("%2u",&m);
if(m<=0 || m>=13)
m=1;
clrscr();
gotoxy(32,2);
cprintf("Calendar");
y1=0;
t=0;
while(y1 {
if((y1%100!=0 && y1%4==0) || y1%400==0)
t=t+366;
else
t=t+365;
y1++;
}
m1=1;
while(m1 {
d=day(m1,y);
t=t+d;
m1++;
}
d=t%7;
printf("

Year: '%u'",y);
printf("
Month: '%s'

",a[m-1]);

printf("%6s%6s%6s%6s%6s%6s%6s

","Sun","Mon","Tue","Wed","Thu","Fri","Sa
t");
textcolor(GREEN);
k=1;
for(i=1;i<=day(m,y);i++,k++)
{
if(i==1)
{
if(d==0)
{
for(j=1;j<7;j++,k++)
printf("%6s","");
}
else
{
for(j=1;j printf("%6s","");
}
}
cprintf("%6d",i);
if(k%7==0)
printf("

");
}
gotoxy(27,22);
cprintf("www");

getch();
}

Calendar of Thousands of Years program in c

Calendar of Thousands of Years

#include // here stdio.h
#include // here conio.h
static char *months[]={"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"};
void main()
{
static int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
long int ndays,ldays,tydays,tdays;
int d,i,m,fday,y;
char ch;
textcolor(LIGHTGREEN);
textbackground(LIGHTBLUE);
clrscr();
printf("Enter year(1900 onwards) & month(number):");
scanf("%d%d",&y,&m);
while(1)
{
ndays=(y-1)*365l;
ldays=(y-1)/4-(y-1)/100+(y-1)/400;
tdays=ndays+ldays;//total days
//check for leap year
if((y%100==0 && y%400==0)||(y%4==0 && y%100!=0))
days[1]=29;
else
days[1]=28;
d=days[m-1];
tydays=0;
for(i=0;i<=m-2;i++)
tydays=tydays+days[i];
tdays=tydays+tdays;
fday=tdays%7;
cal(y,m,fday,d);
ch=getche();
switch(ch)
{
case 77:
if(m==12)
{
y++;
m=1;
}
else
m++;
break;
case 72:
y++;
continue;
case 75:
if(m==1)
{
y--;
m=12;
}
else
m--;
break;
case 80:
y--;
continue;
case 27:
exit(0);
}}}
cal(int yr,int mo,int fd,int da)
{
int i,r,c;
char a;
clrscr();
gotoxy(25,2);
printf("%s %d",months[mo-1],yr);
textcolor(LIGHTGREEN);
gotoxy(5,5);
printf("____________________________________________________");
gotoxy(10,6);
printf("MON TUE WED THU FRI SAT SUN");
gotoxy(5,7);
printf("____________________________________________________");
r=9;
c=11+(6*fd);
for(i=1;i<=da;i++)
{
gotoxy(c,r);
if(c==47)
textcolor(RED);
else
textcolor(LIGHTGREEN);
cprintf("%d",i);
if(c<=41)
c=c+6;
else
{
c=11;
r=r+1;
}
}
textcolor(LIGHTGREEN);
gotoxy(5,15);
printf("____________________________________________________");
gotoxy(11,17);
printf("UP-Next Year DOWN-Prev Year");
gotoxy(11,18);
printf("RIGHT-Next Month LEFT-Prev Month");
gotoxy(27,20);
printf("Esc-Exit");
return 0;
}

Bubble Sorting Algorithm Implementation in c

Bubble Sorting Algorithm

#include // here stdio.h
#include // here ctype.h

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;
}

Bomber Fighter Plane simulation program in c

Bomber Fighter Plane simulation

#include // here stdio.h
#include // here graphics.h
#include // here conio.h
#include // here dos.h
#include // here math.h
void main()
{
int gd=DETECT,gm;
float x1,x2,y1,y2,dx,co,j;
int flag=0;
float distance,B_SPEED,F_SPEED;

initgraph(&gd,&gm,"");
cleardevice();
textcolor(RED);
printf("Enter the Speed of Bomber Plane(1 to 20):");
scanf("%f",&B_SPEED);
printf("Enter the Speed of Fighter Plane(1 to 20):");
scanf("%f",&F_SPEED);
j=120;

x1=20.0;
y1=400.0;
x2=20.0;
y2=200.0;

while(x1<600)
{
cleardevice();
sound(j);
setfillstyle(1, RED);
fillellipse(x1, y1, 5,5);
outtextxy(x1+20,y1,"BOMBER");
//circle(x1,y1,10);
x1=x1+B_SPEED;
dx=x1-x2;
gotoxy(1,1);
printf("BOMBER X1:%2f, Y1:%f",x1,y1);
gotoxy(1,2);
printf("FIGHTER X2:%2f, Y2:%2f",x2,y2);
distance= pow((x1-x2),2)+pow((y1-y2),2);
distance=sqrt(distance);
gotoxy(1,3);
printf("DISTANCE BETWEEN BOTH PLANE:%f",distance);
co=dx/distance;
x2=x2+F_SPEED*co;
y2=y2+F_SPEED*sqrt(1-co*co);
//circle(x2,y2,10);
setfillstyle(1,GREEN);
fillellipse(x2, y2, 5,5);
outtextxy(x2+20,y2,"FIGHTER");

if(distance<=50)
{

flag=1;
for(int i=0;i<15;i++)
{
sound(i*180);
delay(50);
}
outtextxy(220,150,"Bomber Plane crashed");
nosound();
getch();
break;
}
delay(500);


}
if(flag==0)
{
outtextxy(220,250," Sorry:Bomber Plane has Passed away Safely!");

for(int i=120;i<1000;i++)
{
sound(i);
delay(8);

}
delay(50);
}
nosound();
getch();

}

Begginers of system programming

Begginers of system programming

// understanding ivt table
#include // here stdio.h
#include // here dos.h
main()
{
unsigned long far *address = (unsigned long far *)0x00000000;
unsigned long intadd[256];
unsigned int segment, offset;
int i;
FILE *fp;
fp = fopen("IVT.txt", "wb");
for(i = 0; i < 256; i++)
{
intadd[i] = *(address++);
segment = FP_SEG(intadd[i]);
offset = FP_OFF(intadd[i]);
fprintf(fp, "interrupt %3X : vector %Fp(hex) : %lu(dec)
",
i, intadd[i], (unsigned long)segment * 16 + offset);
}
fclose(fp);
}

Analog and Digital clock program in c

Analog and Digital clock

# include // here graphics.h
# include // here stdio.h
# include // here dos.h
# include // here string.h
# include // here math.h
# define pi 3.141592654
int x;
float x30,x60,y30,y60;
void paint1()
{
setcolor(GREEN);
outtextxy(297,60,"");
outtextxy(297,332,"");
outtextxy(435,198,"");
outtextxy(160,198,"");
setcolor(RED);
outtextxy(375,85,"è");
outtextxy(420,260,"è");
outtextxy(170,135,"è");
outtextxy(220,310,"è");
setcolor(LIGHTBLUE);
outtextxy(420,135,"ì");
outtextxy(375,310,"ì");
outtextxy(220,83,"ì");
outtextxy(175,260,"ì");
}
void paint2()
{
setcolor(RED);
outtextxy(297,60,"è");
outtextxy(297,332,"è");
outtextxy(435,198,"è");
outtextxy(160,198,"è");
setcolor(LIGHTBLUE);
outtextxy(375,85,"ì");
outtextxy(420,260,"ì");
outtextxy(170,135,"ì");
outtextxy(220,310,"ì");
setcolor(GREEN);
outtextxy(420,135,"");
outtextxy(375,310,"");
outtextxy(220,83,"");
outtextxy(175,260,"");
}
void paint3()
{
setcolor(LIGHTBLUE);
outtextxy(297,60,"ì");
outtextxy(297,332,"ì");
outtextxy(435,198,"ì");
outtextxy(160,198,"ì");
setcolor(GREEN);
outtextxy(375,85,"");
outtextxy(420,260,"");
outtextxy(170,135,"");
outtextxy(220,310,"");
setcolor(RED);
outtextxy(420,135,"è");
outtextxy(375,310,"è");
outtextxy(220,83,"è");
outtextxy(175,260,"è");
}
void graph()
{
cleardevice();
setcolor((++x)%15+1);
if(x%2)
outtextxy(180,10,"X");
else
outtextxy(130,20,"X");
setcolor(GREEN);
circle (300,200,150);
circle(300,200,2);
setcolor(14);
circle (300,200,100);
setcolor(3);
circle (300,200,120);
setcolor(RED);
circle(300,50,2);
circle(450,200,2);
circle(150,200,2);
circle(300,350,2);
setcolor(BLUE);
circle(300+x30,200+y30,2);//1
circle(300-x30,200+y30,2);//11
circle(300+x30,200-y30,2);//5
circle(300-x30,200-y30,2);//7

circle(300+x60,200+y60,2);//2
circle(300+x60,200-y60,2);//4
circle(300-x60,200-y60,2);//8
circle(300-x60,200+y60,2);//10
if(x%2)
{
setcolor(x);
outtextxy(300+x30*1.1,200+y30*1.1,"1");//1
outtextxy(300-x30*1.1,200+y30*1.1,"11");//11
outtextxy(300+x30*1.1,200-y30*1.1,"5");//5
outtextxy(300-x30*1.1,200-y30*1.1,"7");//7

outtextxy(300+x60*1.1,200+y60*1.1,"2");//2
outtextxy(300+x60*1.1,200-y60*1.1,"4");//4
outtextxy(300-x60*1.1,200-y60*1.1,"8");//8
outtextxy(300-x60*1.15,200+y60*1.1,"10");//10
outtextxy(460,200,"3");
outtextxy(300,360,"6");
outtextxy(140,200,"9");
outtextxy(290,40,"12");
}
}

void plot(int h , int m , int s)
{
char a[2],b[2],c[2];
setcolor( LIGHTCYAN );
itoa(h,a,10);
outtextxy(450,100,a);
outtextxy(470,100,":");

itoa(m,a,10);
outtextxy(490,100,a);
outtextxy(510,100,":");

itoa(s,a,10);
outtextxy(530,100,a);
setcolor( LIGHTGREEN );
if( h<13 )
outtextxy( 290 , 250 , "AM");
else
outtextxy( 290 , 250, "PM");
h=h%12;
setlinestyle(SOLID_LINE , 1 , 3);
setcolor( RED );
line(300,200,300+floor(100*cos(((h*5+m/10.0)*6-90)*pi/180)),
200+floor(100*sin(((h*5+m/10.0)*6-90)*pi/180)));
setcolor(BLUE);
setlinestyle(SOLID_LINE,1,3);
line(300,200,300+floor(120*cos((m*6-90)*pi/180)),
200+floor(120*sin((m*6-90)*pi/180)));
setcolor(MAGENTA);
setlinestyle(SOLID_LINE,1,1);
line(300,200,300+floor(120*cos((s*6-90)*pi/180)),
200+floor(120*sin((s*6-90)*pi/180)));
}

void timexy()
{
int h,m,s;
struct time t;
while(1)
{
//clrscr();
cleardevice();
graph();
gettime(&t);
//printf("


The current time is:
%2d:%02d:%02d.%02d
",
// t.ti_hour, t.ti_min, t.ti_sec,t.ti_hund);
h=t.ti_hour;
m=t.ti_min;
s=t.ti_sec;
if(s%3==0)
paint1();
else if(s%3==1)
paint3();
else paint2();
plot(h,m,s);
delay(995);
}
}
main()
{
int i=DETECT,m;
char a[100],b[10]="jalpari";
x30=floor(150*cos((30-90)*pi/180));
y30=floor(150*sin((30-90)*pi/180));
x60=floor(150*cos((60-90)*pi/180));
y60=floor(150*sin((60-90)*pi/180));
initgraph(&i,&m,"d:\tc\bgi");
i=0;
printf("
PASSWORD==>");
do
{
a[i]=getch();
if(!(a[i]==(char)13))
{
printf("vasim");
i++;
}
else {a[i]='

All types of Linked List Operations

All types of Linked List Operations

#include // here stdio.h
#include // conio.h
#include // stdlib.h
#include //alloc.h
#include // dos.h
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;
}

A program to implement Heap Sort

A program to implement Heap Sort

#include //here stdio.h

void restoreHup(int*,int);
void restoreHdown(int*,int,int);

void main()
{
int a[20],n,i,j,k;
printf("
Enter the number of elements to sort : ");
scanf("%d",&n);

printf("
Enter the elements :
");
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
restoreHup(a,i);
}


j=n;
for(i=1;i<=j;i++)
{
int temp;
temp=a[1];
a[1]=a[n];
a[n]=temp;
n--;
restoreHdown(a,1,n);
}

n=j;

printf("
Here is it...
");
for(i=1;i<=n;i++)
printf("%4d",a[i]);
}



void restoreHup(int *a,int i)
{
int v=a[i];

while((i>1)&&(a[i/2] {
a[i]=a[i/2];
i=i/2;
}
a[i]=v;
}

void restoreHdown(int *a,int i,int n)
{
int v=a[i];
int j=i*2;
while(j<=n)
{
if((j j++;
if(a[j]
a[j/2]=a[j];
j=j*2;
}
a[j/2]=v;
}

A chat program in C

A chat program in C

//here the shared folder is in "computer21"

#include // here stdio.h

#include // here conio.h

#include // here process.h

#include // here string.h



char c[30],ch[70];

FILE *stream,*stream1;



void read(void)

{ stream1 = fopen("//computer21/s/read.txt","r");

fread(ch,1000,1,stream1);

printf("%s",ch);

fclose(stream1); }



void clearhist()

{ stream=fopen("//computer21/s/write1.txt","w");

fprintf(stream," ");

fclose(stream); }





void main ()

{ int i,d=0;

char temp,name[10];

clrscr ();

gotoxy(10,12);

printf("Enter Name:");

scanf("%s",name);

clrscr ();

for(i=0;i<=100;i++)

{ clrscr ();

read();

gotoxy(1,21);

printf("--------------Press ENTER Without Message to Check For New
Message--------------");

gotoxy(1,23);

printf("Enter the Message(30 chars max) : ");

gets(c);

//checking message

if((c[0]=='e')&&(c[1]=='x')&&(c[2]=='i')&&(c[3]=='t'))

{ clearhist ();

exit(0); }

//checking message for "enter"

if(c[0]!='

A Calculator in C Using Graphics & Mouse Operations

A Calculator in C Using Graphics & Mouse Operations

#include"graphics.h"
#include"dos.h"
#include"stdio.h"
#include"math.h"
union REGS i,o;
char *text[]={ "7","8","9","*",
"4","5","6","/",
"1","2","3","+",
"0","00",".","-",
"M","M+","M-","+/-",
"MR","MC","x^2","sr",
"OFF","AC","CE","="};

int k=0,pass,op,prop,newnum=1,bt,memo=1,d=0,sq;
long double num=0,accum,m;


void normalbutton(int ,int ,int ,int,char**);

void main()

{
int gd=DETECT,gm,x1,x2,y1,y2,i,j,maxx,maxy,x,y,button;
char *text1[]={""","T","o"," ","K","n","o","w"," ","a","b","o",
"u","t"," ","m","e"," ","l","o","g","o","n"," ",":"};
char *text2[]={"w","w","w",".","g","e","o","c","i","t","i","e","s",
".","c","o","m","/","t","a","l","k","d","e","e","p",
"e","s","h"};

initgraph(&gd,&gm,"");

if(initmouse()==0)
{
closegraph();
restorecrtmode();
printf("
Mouse driver not loded");
exit(1);
}
showmouseptr();
// x=y=50;
movemouseptr(&x,&y);

setbkcolor(11);
setcolor(1);
rectangle(198,140,417,163);
rectangle(199,141,418,164);
rectangle(197,139,416,162);
rectangle(185,130,430,450);
rectangle(184,129,431,451);
rectangle(182,127,433,454);
rectangle(181,126,434,453);


//setfillstyle(SOLID_FILL,3);
//bar(200,142,415,161);

outtextxy(200,50,"A Calculator in C");
outtextxy(200,100,"Press OFF button to exit....");
y1=140;
y2=160;

for(j=0;j<7;j++)
{
x1=200;
x2=235;
y1+=40;
y2+=40;

for(i=0;i<4;i++)
{
normalbutton(x1,x2,y1,y2,text);
x1+=60;
x2+=60;
}
}


while(1)
{


getmousepos(&button,&x,&y);


y1=140;
y2=160;
/*
if( (x>400&&x<450)>400&&y<420) )
{ if((button & 1)==1)
{ sound(500);
delay(5);
exit();
}
}
*/
for(j=0;j<7;j++)
{
x1=200;
x2=235;
y1+=40;
y2+=40;

for(i=0;i<4;i++)
{

if((xx1)&&(yy1))
{
if((button & 1)==1)
{ gotoxy(28,10);
// printf("%d",ch=*text[j*4+i]);
// printf("char is %c",ch);
bt=j*4+i;
// printf("char is %d",j*4+i);
setcolor(11);
outtextxy(x1+12,y1+7,text[j*4+i]);

if(num>pow(10.0,18))
exit();
sound(500);delay(10);nosound();
delay(250);
sound(400);delay(10);
nosound();
switch (bt)
{
case 8 :
addnum(1);
break;
case 9 :
addnum(2);
break;
case 10 :
addnum(3);
break;
case 4 :
addnum(4);
break;
case 5 :
addnum(5);
break;
case 6 :
addnum(6);
break;
case 0 :
addnum(7);
break;
case 1 :
addnum(8);
break;
case 2 :
addnum(9);
break;
case 12 :
addnum(0);
break;
case 11 :
// plus
operation(1);
break;

case 15 :
// minus
operation(2);
break;
case 3 :
// multiplication
operation(3);
break;
case 7 :
// division
operation(4);
break;
case 13:
doublezero();
break;
case 14 :
decimal();
break;

case 16:
mem();
break;
case 20:
recallmem();
break;
case 19:
plusminus();
break;
case 17:
plusm();
break;
case 18:
minusm();
break;
case 21:
clearm();
break;
case 22 :
square();
break;
case 23:

sqroot();
break;
case 24:
// OFF
hidemouseptr();
setcolor(1);
for(j=0;j<20;j++)
{
for(i=75;i<481;i+=20)

line(0,0+i+j,640,j+0+i);

delay(100);
}
setcolor(14);
outtextxy(225,200,"Thanks for using it !");
delay(2000);
setcolor(13);
for(j=0;j<20;j++)
{
for(i=0;i<640;i+=20)

line(0+i+j,0,j+0+i,640);

delay(100);
}
setcolor(1);

for(i=0;i<25;i++)
{
outtextxy(75+10*i,200,text1[i]);
sound(3000);
delay(50);
nosound();
}
for(i=0;i<29;i++)
{
outtextxy(125+10*i,225,text2[i]);
sound(3000);
delay(50);
nosound();
}


delay(2500);
sound(5000);
delay(10);
exit();
break;
case 25:
allclear();
break;

case 26:
clear();
break;

case 27:
// equalto
operation(5);
break;



}
setcolor(1);
outtextxy(x1+12,y1+7,text[j*4+i]);

}
}
x1+=60;
x2+=60;

}

}

}



}

void normalbutton(int x1,int x2,int y1,int y2,char **text)
{
setcolor(15);
rectangle(x1-2,y1-2,x2+1,y2+1);
rectangle(x1-1,y1-1,x2+2,y2+2);
setcolor(7);
rectangle(x1,y1,x2+2,y2+2);
rectangle(x1,y1,x2+1,y2+1);

setfillstyle(SOLID_FILL,14);
bar(x1,y1,x2,y2);
setcolor(1);
outtextxy(x1+12,y1+7,text[k]);
k++;
}
/* initmouse */
initmouse()
{
i.x.ax=0;
int86 (0x33,&i,&o);
return(o.x.ax);
}
hidemouseptr()
{
i.x.ax=2;
int86(0x33,&i,&o);
}

/* displays mouse pointer */
showmouseptr()
{
i.x.ax=1;
int86(0x33,&i,&o);
return 0;
}

/*gets mouse coordinates and button status*/

getmousepos(int *button,int *x,int *y)
{
i.x.ax=3;
int86(0x33,&i,&o);
*button=o.x.bx;
*x=o.x.cx;
*y=o.x.dx;
return 0;
}
/* Move mouse ptr to x,y */
movemouseptr(int *x,int *y)
{
i.x.ax=4;
int86(0x33,&i,&o);
o.x.cx=*x;
o.x.dx=*y;
return 0;
}

addnum(int pass)
{ if(sq)
newnum=1;

if(newnum)
{ if(d)
{
num=pass/(pow(10.0,d));
d++;
newnum=0;
}
else
{ num=pass;
newnum=0;
}
}
else
{
/* if(num==0)
{ if(d)
{
num=num+pass/(pow(10.0,d));
d++;
}
else
num=pass;
}
*/
// else
{ if(d)
{
if(num<0)
num=num-pass/(pow(10.0,d));
else
num=num+pass/(pow(10.0,d));
d++;
}
else
{
num=num*10+pass;
}
}
}
printf("%25.5Lf",num);
}

operation(int opr)
{ long double pnum;
pnum=num;

if(newnum && (prop != 5) && memo)
{
}
else
{ newnum=1;
d=0;
sq=0;
switch(prop)
{
case 1:
accum=accum+pnum;
break;
case 2:
accum=accum-pnum;
break;
case 3:
accum=accum*pnum;
break;
case 4:
accum=accum/pnum;
break;
default:
accum=pnum;
}
}
prop=opr;
num=accum;
printf("%25.5Lf",num);
}

allclear()
{
sq=0;
accum=0;
num=0;
d=0;
newnum=1;
printf("%25.5Lf",num);
}

mem()
{
m=num;
}
recallmem()
{
memo=0;
printf("%25.5Lf",m);
num=m;
}
plusminus()
{ if(num!=0)
{ num*=-1;
printf("%25.5Lf",num);
}
}


plusm()
{
m+=num;
}
minusm()
{
m-=num;
}
clearm()
{
m=0;
}
decimal()
{
if(!d)
{d=1;
if(newnum==1)
{
num=0;
}
printf("%25.5Lf",num);
}
}

square()
{ sq=1;
num*=num;
printf("%25.5Lf",num);
// newnum=1;
}
sqroot()
{ sq=1;
num=pow(num,0.5);
printf("%25.5Lf",num);
// newnum=1;
}
doublezero()
{
if(d)
{
// num=num+pass/(pow(100.0,d));
d++;
d++;
}
else
num*=100;
printf("%25.5Lf",num);
}

clear()
{
num=0;
printf("%25.5Lf",num);
}

Thursday, October 15, 2009

Interview questions on c part-7

7.1: I had the definition char a[6] in one source file, and in another I declared extern char *a. Why didn’t it work?

A: The declaration extern char *a simply does not match the actual definition. The type pointer-to-type-T is not the same as array- of-type-T. Use extern char a[].

7.2: But I heard that char a[] was identical to char *a.

A: Not at all. (What you heard has to do with formal parameters to functions; see question 7.4.) Arrays are not pointers. The array declaration char a[6] requests that space for six characters be set aside, to be known by the name “a.” That is, there is a location named “a” at which six characters can sit. The pointer declaration char *p, on the other hand, requests a place which holds a pointer, to be known by the name “p.” This pointer can point almost anywhere: to any char, or to any contiguous array of chars, or nowhere

As usual, a picture is worth a thousand words. The declarations char a[] = “hello”;

char *p = “world”;

would initialize data structures which could be represented like this:

+---+---+---+---+---+---+

a: | h | e | l | l | o |\0 |

+---+---+---+---+---+---+

+-----+ +---+---+---+---+---+---+

p: | *======> | w | o | r | l | d |\0 |

+-----+ +---+---+---+---+---+---+

It is important to realize that a reference like *x*[3] generates different code depending on whether x is an array or a pointer. Given the declarations above, when the compiler sees the expression a[3], it emits code to start at the location “a,” move three past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the location “p,” fetch the pointer value there, add three to the pointer, and finally fetch the character pointed to. In other words, a[3] is three places past (the start of) the object named a, while p[3] is three places past the object pointed to by p. In the example above, both a[3] and p[3] happen to be the character ‘l’, but the compiler gets there differently.

7.3: So what is meant by the “equivalence of pointers and arrays” in C?

A: Much of the confusion surrounding arrays and pointers in C can be traced to a misunderstanding of this statement. Saying that arrays and pointers are “equivalent” means neither that they are identical nor even interchangeable. “Equivalence” refers to the following key definition:

An lvalue of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T.

(The exceptions are when the array is the operand of a sizeof or & operator, or is a string literal initializer for a character array.)

As a consequence of this definition, the compiler doesn’t apply the array subscripting operator [] that differently to arrays and pointers, after all. In an expression of the form a[i], the array decays into a pointer, following the rule above, and is then subscripted just as would be a pointer variable in the expression p[i] (although the eventual memory accesses will be different, as explained in question 7.2). If you were to assign the array’s address to the pointer:

p = a;

then p[3] and a[3] would access the same element.

7.4: Then why are array and pointer declarations interchangeable as function formal parameters?

A: It’s supposed to be a convenience.

Since arrays decay immediately into pointers, an array is never actually passed to a function. Allowing pointer parameters to be declared as arrays is a simply a way of making it look as though the array was being passed – a programmer may wish to emphasize that a parameter is traditionally treated as if it were an array, or that an array (strictly speaking, the address) is traditionally passed. As a convenience, therefore, any parameter declarations which “look like” arrays, e.g.

f(a)

char a[];

{ ... }

are treated by the compiler as if they were pointers, since that is what the function will receive if an array is passed:

f(a)

char *a;

{ ... }

This conversion holds only within function formal parameter declarations, nowhere else. If the conversion bothers you, avoid it; many people have concluded that the confusion it causes outweighs the small advantage of having the declaration “look like” the call or the uses within the function.

7.5: How can an array be an lvalue, if you can’t assign to it?

A: The ANSI C Standard defines a “modifiable lvalue,” which an array is not.

7.6: Practically speaking, what is the difference between arrays and pointers?

A: Arrays automatically allocate space, but can’t be relocated or resized. Pointers must be explicitly assigned to point to allocated space (perhaps using malloc), but can be reassigned (i.e. pointed at different objects) at will, and have many other uses besides serving as the base of blocks of memory.

Due to the so-called equivalence of arrays and pointers (see question 7.3), arrays and pointers often seem interchangeable, and in particular a pointer to a block of memory assigned by malloc is frequently treated (and can be referenced using []) exactly as if it were a true array. See questions 7.14 and 7.16. (Be careful with sizeof, though.)

7.7: Someone explained to me that arrays were really just constant pointers.

A: This is a bit of an oversimplification. An array name is “constant” in that it cannot be assigned to, but an array is not a pointer, as the discussion and pictures in question 7.2 should make clear. See also questions 7.3 and 7.8.

7.8: I came across some “joke” code containing the “expression” 5[”abcdef”] . How can this be legal C?

A: Yes, Virginia, array subscripting is commutative in C. This curious fact follows from the pointer definition of array subscripting, namely that a[e] is identical to *((a)+(e)), for any two expressions a and e, as long as one of them is a pointer expression and one is integral. This unsuspected commutativity is often mentioned in C texts as if it were something to be proud of, but it finds no useful application outside of the Obfuscated C Contest

7.9: Since array references decay into pointers, if arr is an array, what’s the difference between arr and &arr?

A: The type.

In Standard C, &arr yields a pointer, of type pointer-to-array- of-T, to the entire array. (In pre-ANSI C, the & in &arr generally elicited a warning, and was generally ignored.) Under all C compilers, a simple reference (without an explicit &) to an array yields a pointer, of type pointer-to-T, to the array’s first element. (See also questions 7.3, 7.13, and 7.18.)

7.10: How do I declare a pointer to an array?

A: Usually, you don’t want to. When people speak casually of a pointer to an array, they usually mean a pointer to its first element.

Instead of a pointer to an array, consider using a pointer to one of the array’s elements. Arrays of type T decay into pointers to type T (see question 6.3), which is convenient; subscripting or incrementing the resultant pointer will access the individual members of the array. True pointers to arrays, when subscripted or incremented, step over entire arrays, and are generally useful only when operating on arrays of arrays, if at all. (See question 7.18.)

If you really need to declare a pointer to an entire array, use something like “int (*ap)[N];” where N is the size of the array. If the size of the array is unknown, N can in principle be omitted, but the resulting type, “pointer to array of unknown size,” is useless.

7.11: How can I set an array’s size at compile time? How can I avoid fixed- sized arrays?

A: The equivalence between arrays and pointers (see question 7.3) allows a pointer to malloc’ed memory to simulate an array quite effectively. After executing

#include int *dynarray = (int )malloc(10 sizeof(int)); (and if the call to malloc() succeeds), you can reference dynarray[i] (for i from 0 to 9) just as if dynarray were a conventional, statically-allocated array (int a[10]). See also question 7.16.

7.12: How can I declare local arrays of a size matching a passed-in array?

A: You can’t, in C. Array dimensions must be compile-time constants. (gcc provides parameterized arrays as an extension.) You’ll have to use malloc(), and remember to call free() before the function returns. See also questions 7.14, 7.16, 7.19.

7.13: How can I dynamically allocate a multidimensional array?

A: It is usually best to allocate an array of pointers, and then initialize each pointer to a dynamically-allocated “row.” Here is a two-dimensional example:

#include

int **array1 = (int **)malloc(nrows * sizeof(int *)); for(i = 0; i <>

array1[i] = (int *)malloc(ncolumns * sizeof(int));

(In real code, of course, all of malloc’s return values would be checked.) You can keep the array’s contents contiguous, while making later reallocation of individual rows difficult, with a bit of explicit pointer arithmetic:

int **array2 = (int **)malloc(nrows * sizeof(int *)); array2[0] = (int )malloc(nrows ncolumns *

sizeof(int));

for(i = 1; i <>

array2[i] = array2[0] + i * ncolumns; In either case, the elements of the dynamic array can be accessed with normal-looking array subscripts: arrayx[i][j] (for 0 <= i <= NROWS and 0 <= j <= NCOLUMNS). If the double indirection implied by the above schemes is for some reason unacceptable, you can simulate a two-dimensional array with a single, dynamically-allocated one- dimensional array:

int *array3 = (int )malloc(nrows ncolumns * sizeof(int));

However, you must now perform subscript calculations manually, accessing the i,jth element with array3[i * ncolumns + j]. (A macro could hide the explicit calculation, but invoking it would require parentheses and commas which wouldn’t look exactly like multidimensional array syntax, and the macro would need access to at least one of the dimensions, as well. See also question 7.19.)

Finally, you could use pointers to arrays:

int (*array4)[NCOLUMNS] =

(int (*)[NCOLUMNS])malloc(nrows * sizeof(*array4));

but the syntax starts getting horrific and at most one dimension may be specified at run time.

With all of these techniques, you may of course need to remember to free the arrays (which may take several steps; see question 7.23) when they are no longer needed, and you cannot necessarily intermix dynamically-allocated arrays with conventional, statically-allocated ones (see question 7.20, and also question 7.18). All of these techniques can also be extended to three or more dimensions.

7.14: Here’s a neat trick: if I write

int realarray[10];

int *array = &realarray[-1];

I can treat “array” as if it were a 1-based array.

A: Although this technique is attractive (and was used in old editions of the book _Numerical Recipes in C_), it does not conform to the C standards. Pointer arithmetic is defined only as long as the pointer points within the same allocated block of memory, or to the imaginary “terminating” element one past it; otherwise, the behavior is undefined, *even if the pointer is not dereferenced*. The code above could fail if, while subtracting the offset, an illegal address were generated (perhaps because the address tried to “wrap around” past the beginning of some memory segment).

7.15: My compiler complained when I passed a two-dimensional array to a function expecting a pointer to a pointer.

A: The rule (see question 6.3) by which arrays decay into pointers is not applied recursively. An array of arrays (i.e. a two- dimensional array in C) decays into a pointer to an array, not a pointer to a pointer. Pointers to arrays can be confusing, and must be treated carefully; see also question 6.13. (The confusion is heightened by the existence of incorrect compilers, including some old versions of pcc and pcc-derived lints, which improperly accept assignments of multi-dimensional arrays to multi-level pointers.) If you are passing a two-dimensional array to a function:

int array[NROWS][NCOLUMNS];

f(array);

the function’s declaration must match:

f(int a[][NCOLUMNS])

{ ... }

or

f(int (*ap)[NCOLUMNS]) /* ap is a pointer to an array

*/

{ ... }

In the first declaration, the compiler performs the usual implicit parameter rewriting of “array of array” to “pointer to array” (see questions 6.3 and 6.4); in the second form the pointer declaration is explicit. Since the called function does not allocate space for the array, it does not need to know the overall size, so the number of rows, NROWS, can be omitted. The “shape” of the array is still important, so the column dimension NCOLUMNS (and, for three- or more dimensional arrays, the intervening ones) must be retained.

If a function is already declared as accepting a pointer to a pointer, it is probably meaningless to pass a two-dimensional array directly to it.

7.16: How do I write functions which accept two-dimensional arrays when the “width” is not known at compile time?

A: It’s not easy. One way is to pass in a pointer to the [0][0] element, along with the two dimensions, and simulate array subscripting “by hand:”

f2(aryp, nrows, ncolumns)

int *aryp;

int nrows, ncolumns;

{ ... array[i][j] is accessed as aryp[i * ncolumns + j]

... }

This function could be called with the array from question 6.18 as f2(&array[0][0], NROWS, NCOLUMNS);

It must be noted, however, that a program which performs multidimensional array subscripting “by hand” in this way is not in strict conformance with the ANSI C Standard; according to an official interpretation, the behavior of accessing (&array[0][0])[x] is not defined for x >= NCOLUMNS. gcc allows local arrays to be declared having sizes which are specified by a function’s arguments, but this is a nonstandard extension.

When you want to be able to use a function on multidimensional arrays of various sizes, one solution is to simulate all the arrays dynamically, as in question 6.16.

7.17: How can I use statically- and dynamically-allocated multidimensional arrays interchangeably when passing them to functions?

A: There is no single perfect method. Given the declarations int array[NROWS][NCOLUMNS];

int **array1; /* ragged */

int **array2; /* contiguous */

int array3; / “flattened” */

int (*array4)[NCOLUMNS];

with the pointers initialized as in the code fragments in question 6.16, and functions declared as

f1(int a[][NCOLUMNS], int nrows, int ncolumns); f2(int *aryp, int nrows, int ncolumns); f3(int **pp, int nrows, int ncolumns);

where f1() accepts a conventional two-dimensional array, f2() accepts a “flattened” two- dimensional array, and f3() accepts a pointer-to-pointer, simulated array (see also questions 6.18 and 6.19), the following calls should work as expected:

f1(array, NROWS, NCOLUMNS);

f1(array4, nrows, NCOLUMNS);

f2(&array[0][0], NROWS, NCOLUMNS); f2(*array, NROWS, NCOLUMNS);

f2(*array2, nrows, ncolumns);

f2(array3, nrows, ncolumns);

f2(*array4, nrows, NCOLUMNS);

f3(array1, nrows, ncolumns);

f3(array2, nrows, ncolumns);

The following two calls would probably work on most systems, but involve questionable casts, and work only if the dynamic ncolumns matches the static NCOLUMNS:

f1((int (*)[NCOLUMNS])(*array2), nrows, ncolumns); f1((int (*)[NCOLUMNS])array3, nrows, ncolumns);

It must again be noted that passing &array[0][0] (or, equivalently, *array) to f2() is not strictly conforming; see question 7.19.

If you can understand why all of the above calls work and are written as they are, and if you understand why the combinations that are not listed would not work, then you have a very good understanding of arrays and pointers in C. Rather than worrying about all of this, one approach to using multidimensional arrays of various sizes is to make them all dynamic, as in question 7.16. If there are no static multidimensional arrays – if all arrays are allocated like array1 or array2 in question 7.16 -- then all functions can be written like f3().

7.18: Why doesn’t sizeof properly report the size of an array when the array is a parameter to a function?

A: The compiler pretends that the array parameter was declared as a pointer (see question 7.4), and sizeof reports the size of the pointer.

Interview questions on c part-6

6.1: What is this infamous null pointer, anyway?

A: The language definition states that for each pointer type, there is a special value -- the "null pointer" -- which is distinguishable from all other pointer values and which is "guaranteed to compare unequal to a pointer to any object or function." That is, the address-of operator & will never yield a null pointer, nor will a successful call to malloc(). (malloc() does return a null pointer when it fails, and this is a typical use of null pointers: as a "special" pointer value with some other meaning, usually "not allocated" or "not pointing anywhere yet.")

A null pointer is conceptually different from an uninitialized pointer. A null pointer is known not to point to any object or function; an uninitialized pointer might point anywhere.

As mentioned above, there is a null pointer for each pointer type, and the internal values of null pointers for different types may be different. Although programmers need not know the internal values, the compiler must always be informed which type of null pointer is required, so that it can make the distinction if necessary.

6.2: How do I get a null pointer in my programs?

A: According to the language definition, a constant 0 in a pointer context is converted into a null pointer at compile time. That is, in an initialization, assignment, or comparison when one side is a variable or expression of pointer type, the compiler can tell that a constant 0 on the other side requests a null pointer, and generate the correctly-typed null pointer value. Therefore, the following fragments are perfectly legal:
char *p = 0;
if(p != 0)

However, an argument being passed to a function is not necessarily recognizable as a pointer context, and the compiler may not be able to tell that an unadorned 0 "means" a null pointer. To generate a null pointer in a function call context, an explicit cast may be required, to force the 0 to be recognized as a pointer. For example, the Unix system call execl takes a variable-length, null-pointer-terminated list of character pointer arguments,
and is correctly called like this:
execl("/bin/sh", "sh", "-c", "date", (char *)0);

If the (char *) cast on the last argument were omitted, the compiler would not know to pass a null pointer, and would pass an integer 0 instead. (Note that many Unix manuals get this example wrong .)

When function prototypes are in scope, argument passing becomes an "assignment context," and most casts may safely be omitted, since the prototype tells the compiler that a pointer is required, and of which type, enabling it to correctly convert an unadorned 0.Function prototypes cannot provide the types for variable arguments in variable-length argument lists however, so explicit casts are still required for those arguments. It is safest to properly cast all null pointer constants in function calls: to guard against varargs functions or those without prototypes, to allow interim use of non-
ANSI compilers, and to demonstrate that you know what you are doing. (Incidentally, it's also a simpler rule to remember.)

Summary:
Unadorned 0 okay: Explicit cast required:
initialization function call,
no prototype in scope
assignment
variable argument in
comparison varargs function call
function call,
prototype in scope,
fixed argument

6.3: Is the abbreviated pointer comparison "if(p)" to test for non- null
pointers valid? What if the internal representation for null pointers is
nonzero?

A: When C requires the Boolean value of an expression (in the if, while, for, and do statements, and with the &&, ||, !, and ?: operators), a false value is inferred when the expression compares equal to zero, and a true value otherwise. That is, whenever one writes

if(expr)

where "expr" is any expression at all, the compiler essentially acts as if it had been written as

if((expr) != 0)

Substituting the trivial pointer expression "p" for "expr," we have

if(p) is equivalent to if(p != 0)

and this is a comparison context, so the compiler can tell that the (implicit) 0 is actually a null pointer constant, and use the correct null pointer value. There is no trickery involved here; compilers do work this way, and generate identical code for both constructs. The internal representation of a null pointer does *not* matter.

The boolean negation operator, !, can be described as follows:

!expr is essentially equivalent to (expr)?0:1
or to ((expr) == 0)

which leads to the conclusion that

if(!p) is equivalent to if(p == 0)

"Abbreviations" such as if(p), though perfectly legal, are considered by some to be bad style.

6.4: What is NULL and how is it #defined?

A: As a matter of style, many programmers prefer not to have unadorned 0's scattered through their programs. Therefore, the preprocessor macro NULL is #defined (by or ) with the value 0, possibly cast to (void *) . A programmer who
wishes to make explicit the distinction between 0 the integer and 0 the null pointer constant can then use NULL whenever a null pointer is required.

Using NULL is a stylistic convention only; the preprocessor turns NULL back into 0 which is then recognized by the compiler, in pointer contexts, as before. In particular, a cast may still be necessary before NULL (as before 0) in a function call argument. The table under question 5.2 above applies for NULL as well as 0 (an unadorned NULL is equivalent to an unadorned 0).

NULL should *only* be used for pointers;

6.5: How should NULL be defined on a machine which uses a nonzero bit
pattern as the internal representation of a null pointer?

A: The same as on any other machine: as 0 (or ((void *)0)).

Whenever a programmer requests a null pointer, either by writing "0" or "NULL," it is the compiler's responsibility to generate whatever bit pattern the machine uses for that null pointer. Therefore, #defining NULL as 0 on a machine for which internal null pointers are nonzero is as valid as on any other: the compiler must always be able to generate the machine's correct null pointers in response to unadorned 0's seen in pointer contexts.

6.6: If NULL were defined as follows:
#define NULL ((char *)0)
wouldn't that make function calls which pass an uncast NULL work?

A: Not in general. The problem is that there are machines which use different internal representations for pointers to different types of data. The suggested definition would make uncast NULL arguments to functions expecting pointers to characters work correctly, but pointer arguments of other types would still be problematical, and legal constructions such as

FILE *fp = NULL;
could fail. Nevertheless, ANSI C allows the alternate definition
#define NULL ((void *)0)
for NULL. Besides potentially helping incorrect programs to work (but only on machines with homogeneous pointers, thus questionably valid assistance), this definition may catch programs which use NULL incorrectly (e.g. when the ASCII NUL character was really intended;).

6.7: If NULL and 0 are equivalent as null pointer constants, which should I
use?

A: Many programmers believe that NULL should be used in all pointer contexts, as a reminder that the value is to be thought of as a pointer. Others feel that the confusion surrounding NULL and 0 is only compounded by hiding 0 behind a macro, and prefer to use unadorned 0 instead. There is no one right answer.C programmers must understand that NULL and 0 are interchangeable in pointer contexts, and that an uncast 0 is perfectly acceptable. Any usage of NULL (as opposed to 0) should be considered a gentle reminder that a pointer is involved; programmers should not depend on it (either for their own understanding or the compiler's) for distinguishing pointer 0's from integer 0's.

NULL should *not* be used when another kind of 0 is required, even though it might work, because doing so sends the wrong stylistic message. (Furthermore, ANSI allows the definition of NULL to be ((void *)0), which will not work at all in non- pointer contexts.) In particular, do not use NULL when the ASCII null character (NUL) is desired. Provide your own definition

#define NUL '\0'
if you must.

6.8: But wouldn't it be better to use NULL (rather than 0), in case the value of NULL changes, perhaps on a machine with nonzero internal null
pointers?

A: No. (Using NULL may be preferable, but not for this reason.) Although symbolic constants are often used in place of numbers because the numbers might change, this is *not* the reason that NULL is used in place of 0. Once again, the language guarantees that source-code 0's (in pointer contexts) generate null pointers. NULL is used only as a stylistic convention.

6.9: I use the preprocessor macro
#define Nullptr(type) (type *)0
to help me build null pointers of the correct type.

A: This trick, though popular and superficially attractive, does not buy much. It is not needed in assignments and comparisons;It does not even save keystrokes. Its use may suggest to the reader that the program's author is shaky on the subject of null pointers, requiring that the #definition of the macro, its invocations, and *all* other pointer usages be checked.

6.10: This is strange. NULL is guaranteed to be 0, but the null pointer is
not?

A: When the term "null" or "NULL" is casually used, one of several things may be meant:
1. The conceptual null pointer, the abstract language concept defined in question 6.1. It is implemented with...
2. The internal (or run-time) representation of a null pointer, which may or may not be all-bits-0 and which may be different for different pointer types. The actual values should be of concern only to compiler writers. Authors of C programs never see them, since they use...
3. The null pointer constant, which is a constant integer 0 (see question 6.2). It is often hidden behind...
4. The NULL macro, which is #defined to be "0" or "((void *)0)" (see question 6.4). Finally, as red herrings, we have...
5. The ASCII null character (NUL), which does have all bits zero, but has no
necessary relation to the null pointer except in name; and...
6. The "null string," which is another name for the empty string (""). Using the term "null string" can be confusing in C, because an empty string involves a null ('\0') character, but *not* a null pointer, which brings us full circle...
This article uses the phrase "null pointer" (in lower case) for sense 1, the character "0" or the phrase "null pointer constant" for sense 3, and the capitalized word "NULL" for sense 4.

6.11: Why is there so much confusion surrounding null pointers? Why do
these questions come up so often?

A: C programmers traditionally like to know more than they need to about the underlying machine implementation. The fact that null pointers are represented both in source code, and internally to most machines, as zero invites unwarranted assumptions. The use of a preprocessor macro (NULL) may seem to suggest that the value could change some day, or on some weird machine. The construct "if(p == 0)" is easily misread as calling for conversion of p to an integral type, rather than 0 to a pointer type, before the comparison. Finally, the distinction between the several uses of the term "null" (listed in question 6.10 above) is often overlooked. One good way to wade out of the confusion is to imagine that C used a keyword (perhaps "nil", like Pascal) as a null pointer constant. The compiler could either turn "nil" into the correct type of null pointer when it could determine the type from the source code, or complain when it could not. Now in fact, in C the keyword for a null pointer constant is not "nil" but "0", which works almost as well, except that an uncast "0" in a non- pointer context generates an integer zero instead of an error message, and if that uncast 0 was supposed to be a null pointer constant, the code may not work.

6.12: I'm confused. I just can't understand all this null pointer stuff.

A: Follow these two simple rules:
1. When you want a null pointer constant in source code, use "0" or "NULL".
2. If the usage of "0" or "NULL" is an argument in a function call, cast it to the pointer type expected by the function being called.
The rest of the discussion has to do with other people's misunderstandings, with the internal representation of null pointers (which you shouldn't need to know), and with ANSI C refinements. Understand questions 6.1, 6.2, and 6.4, and consider 6.3, 6.9, 6.10, and 6.11, and you'll do fine.

6.13: Given all the confusion surrounding null pointers, wouldn't it be
easier simply to require them to be represented internally by zeroes?

A: If for no other reason, doing so would be ill-advised because it would unnecessarily constrain implementations which would otherwise naturally represent null pointers by special, nonzero bit patterns, particularly when those values would trigger automatic hardware traps for invalid accesses. Besides, what would such a requirement really accomplish? Proper understanding of null pointers does not require knowledge of the internal representation, whether zero or nonzero. Assuming that null pointers are internally zero does not make any code easier to write (except for a certain ill-advised usage of calloc(); Known-zero internal pointers would not obviate casts in function calls, because the *size* of the pointer might still be different from that of an int. (If "nil" were used to request null pointers, as mentioned in question 6.11 above, the urge to assume an internal zero representation would not even arise.)

6.14: Seriously, have any actual machines really used nonzero null pointers, or different representations for pointers to different types?

A: The Prime 50 series used segment 07777, offset 0 for the null pointer, at least for PL/I. Later models used segment 0, offset 0 for null pointers in C, necessitating new instructions such as TCNP (Test C Null Pointer), evidently as a sop to all the extant poorly-written C code which made incorrect assumptions. Older, word-addressed Prime machines were also notorious for requiring larger byte pointers (char *'s) than word pointers (int *'s).
The Eclipse MV series from Data General has three architecturally supported pointer formats (word, byte, and bit pointers), two of which are used by C compilers: byte pointers for char * and void *, and word pointers for everything else. Some Honeywell-Bull mainframes use the bit pattern 06000 for (internal) null pointers. The CDC Cyber 180 Series has 48-bit pointers consisting of a ring, segment, and offset. Most users (in ring 11) have null pointers of 0xB00000000000. It was common on old CDC ones- complement machines to use an all-one-bits word as a special flag for all kinds of data, including invalid addresses. The old HP 3000 series uses a different addressing scheme for byte addresses than for word addresses; like several of the machines above it therefore uses different representations for char * and void * pointers than for other pointers.The Symbolics Lisp Machine, a tagged architecture, does not even have conventional numeric pointers; it uses the pair (basically a nonexistent handle) as a C null pointer.

Depending on the "memory model" in use, 8086-family processors (PC compatibles) may use 16-bit data pointers and 32-bit function pointers, or vice versa. Some 64-bit Cray machines represent int * in the lower 48 bits of a word; char * additionally uses the upper 16 bits to indicate a byte address within a word.

6.15: What does a run-time "null pointer assignment" error mean? How do I track it down?

A: This message, which typically occurs with MS-DOS compilers means that you've written, via a null (perhaps because uninitialized) pointer, to location 0.
A debugger may let you set a data breakpoint or watchpoint or something on location 0. Alternatively, you could write a bit of code to stash away a copy of 20 or so bytes from location 0, and periodically check that the memory at location 0 hasn't changed.

Wednesday, October 14, 2009

Interview questions on c part-5

5.1: Why doesn't
strcat(string, '!');
work?

A: There is a very real difference between characters and strings, and strcat()
concatenates *strings*. Characters in C are represented by small integers corresponding to their character set values (see also question 8.6 below). Strings are represented by arrays of characters; you usually manipulate a pointer to the first character of the array. It is never correct to use one when the other is expected. To append a ! to a string, use
strcat(string, "!");

5.2: I'm checking a string to see if it matches a particular value. Why isn't
this code working?

char *string;
...
if(string == "value") {
/* string matches "value" */
...
}
A: Strings in C are represented as arrays of characters, and C never manipulates (assigns, compares, etc.) arrays as a whole. The == operator in the code fragment above compares two pointers -- the value of the pointer variable string and a pointer to the string literal "value" -- to see if they are equal, that is, if they point to the same place. They probably don't, so the comparison never succeeds. To compare two strings, you generally use the library function strcmp():
if(strcmp(string, "value") == 0) {
/* string matches "value" */
...
}

5.3: If I can say
char a[] = "Hello, world!";
why can't I say
char a[14];
a = "Hello, world!";

A: Strings are arrays, and you can't assign arrays directly. Use strcpy() instead:
strcpy(a, "Hello, world!");

5.4: How can I get the numeric (character set) value corresponding to a
character, or vice versa?

A: In C, characters are represented by small integers corresponding to their values (in the machine's character set), so you don't need a conversion routine: if you have the character, you have its value.

5.5: I think something's wrong with my compiler: I just noticed that
sizeof('a') is 2, not 1 (i.e. not sizeof(char)).

A: Perhaps surprisingly, character constants in C are of type int, so sizeof('a') is sizeof(int) (though it's different in C++).

 
# #