Exemple

Un prim exemplu de lucru cu biblioteca graphics

Dintre toate bibliotecile poate cea mai interesanta pentru un programator incepator este biblioteca graphics. Exemplul urmator ilustreaza utilizarea catorva functii din aceasta biblioteca.

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>

int ixl=10,ixh=290,iyl=290,iyh=10;
/* o valoare x din [xl, xh] este scalata la
o valoare y in intervalul [yl, yh]
*/
double scale(double x,double xl, double xh, double yl, double yh){
double yy,m;double retval=-1;
if (xl==xh || (x-xl)*(x-xh)>=0) return retval;
m=(yh-yl)/(xh-xl);
yy=m*(x-xl)+yl;
retval=yy;
return retval;
}
double funct(double x){
return 0.5*sin(x)+0.5;
}
double mycos(double x){
return cos(2*x);
}
void grafic(double (* fun) (double),int nr, double xl, double xh, double yl, double yh, int color){
int i,xx,yy;double x;
for (i=0;i<=nr;i++){
x=scale(i,0,nr,xl,xh);
xx=scale(x,xl,xh,ixl,ixh);
yy=scale(fun(x),yl,yh,iyl,iyh);
putpixel(xx,yy,color);
}
return;
}
int main(void)
{

/* request auto detection */
int gdriver = DETECT, gmode, errorcode;

/* initialize graphics mode */
initgraph(&gdriver, &gmode, "d:\\tc\\bgi\\");
/* poteca catre fisierul egavga.bgi*/

/* read result of initialization */
errorcode = graphresult();

if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}

/* draw a line */
setcolor(CYAN);
rectangle(0,0,300,300);
setcolor(YELLOW);
rectangle(3,3,297,297);
setcolor(BLUE);
rectangle(9,9,291,291);
setcolor(WHITE);
circle (400,150,99);
setcolor(MAGENTA);
ellipse(200,370,0,360,200,69);
setcolor(LIGHTCYAN);

line(301, 301, getmaxx(), getmaxy());
grafic(*funct,100,0,atan(1.0)*8,-1.0,1.0, YELLOW);
grafic(*mycos,100,0,atan(1.0)*8,-1.0,1.0, GREEN);
/* clean up */
getch();
closegraph();
return 0;
}

Doua exemple de sortare

Exemplul 1 (sort1.c)

#include <stdio.h>
#include <conio.h>
float a[5]={4,2,1,3,5};
void piksrt(int n, float arr[])
{
int i,j,k;
float a;
for (j=1;j<n;j++) { /*extrage cate un element pe rand.*/
for(k=0;k<n;k++)printf("%g ",arr[k]);
printf("\n");
a=arr[j];
i=j-1;
while (i > -1 && arr[i] > a) { /*cauta locul de insertie.*/
arr[i+1]=arr[i];
i--;
}
arr[i+1]=a; /*Insereaza-l.*/
}
}
int main(void){
clrscr();
piksrt(5,a);
return 0;
}
/* rezultatul la consola text este:
4 2 1 3 5
2 4 1 3 5
1 2 4 3 5
1 2 3 4 5
*/

Exemplul 2 (sort2.c)

#include <stdio.h>
#include <conio.h>
float ar[5]={4,2,1,3,5};
void sort(int n, float a[])
{
int i,j,k,noper=0;
float aa;
for (i=0;i<n-1;i++){
for (j=i+1;j<n;j++) { /**/
for(k=0;k<n;k++)printf("%g ",a[k]);
printf("noper=%d\n",noper);
if (a[i]>=a[j]){
aa=a[i];a[i]=a[j];a[j]=aa;noper++;}
}
}
}
int main(void){
clrscr();
sort(5,ar);
return 0;
}
/* rezultatul la consola text este:
4 2 1 3 5 noper=0
2 4 1 3 5 noper=1
1 4 2 3 5 noper=2
1 4 2 3 5 noper=2
1 4 2 3 5 noper=2
1 2 4 3 5 noper=3
1 2 4 3 5 noper=3
1 2 4 3 5 noper=3
1 2 3 4 5 noper=4
1 2 3 4 5 noper=4
*/

Biblioteca conio

Exemplul 1. Citirea caracterelor de la tastatura (tstkbd.c)

#include <conio.h>

int key;

int main(void){
clrscr();
textmode(C80);
key=0;
while(key!=27){ /*unele taste genereaza mai mult de un caracter la consola*/
while (kbhit()!=0){
key=getch();
cprintf("%02x ",key);
}
}
return 0;
}

Exemplul 2. Scrierea caracterelor interfetei dos (tstcoo.c)

#include <conio.h>


int main(void){
clrscr();textmode(C80);
gotoxy(4,1);for (int i=0;i<32;i++)cprintf("%x ",i % 16);

for (i=32;i<255;i++){
if((i % 32)==0) cprintf("\n\r\n\r%02x ",i);
cprintf("%c ",i);
}
return 0;
}

care genereaza la consola urmatoarele:

Exemplul 3. Scrierea intregilor in baza 2 (conio1.c)

#include <conio.h>
int key,i;
char biti[32];
unsigned long int ul;

void inttobiti(long a, char * biti){
int c,r,nrbiti=32;
if((a & 0xff000000)==0) nrbiti=24;
if((a & 0xffff0000)==0) nrbiti=16;
if((a & 0xffffff00)==0) nrbiti=8;
for (int i=0;i<nrbiti;i++)biti[i]='0';
biti[nrbiti]=0;
c=a;i=nrbiti-1;
while (c!=0){
r=c % 2;
if (r==1) biti[i]='1';
c=c/2;
i--;
}

}

int main(void){
clrscr();

key=0;
while (key!=27) {
key=getch();
gotoxy(1,21);clreol();
cprintf("%02x",key);
inttobiti(key, biti);
gotoxy(10,21);
cprintf("%s",biti);
gotoxy(1,22);clreol(); cprintf("%d",key);
gotoxy(1,23);clreol();
ul=256*256+3;
inttobiti(ul, biti); cprintf("%d %s %d",ul,biti,sizeof(unsigned long));
}
return 0;
}

care returneaza la consola urmatoarele

6b 01101011
107
16777216 00000001000000000000000000000011 4

Nota. Mediul TurboC nu opereaza corect cu unsigned long. Un cod executabil se afla aici.

Exemplul 4. Implementeaza o suprafata de joc pe care se pot juca diferite jocuri orientate pe text (ritipiti.c)

#include <conio.h>
#define lf 75
#define rt 77
#define up 72
#define dw 80
#define dl 0x53
#define ins 0x52
#define home 0x47
#define end 0x4f
#define maxx 39
#define maxy 24
int key,i,x,y;
char pozitie[maxx][maxy];

void wrxy(void){
x=wherex();y=wherey();
gotoxy(40,1);clreol();cprintf("x = %2d y = %2d",x/2-1,y-1-1);
gotoxy(x,y);
}
void wrpoz(void){
x=wherex();y=wherey();
for (int i=0;i<maxx;i++){
for (int j=0;j<maxy;j++){
gotoxy(2*(i+1),j+2);cprintf("%c",pozitie[i][j]);
}
}
gotoxy(x,y);
}

void del(void){
x=wherex();y=wherey();
clrscr();gotoxy(x,y);wrxy();gotoxy(x,y);
}
void delpoz(){
for (int i=0;i<maxx;i++){
for (int j=0;j<maxy;j++){
pozitie[i][j]=' ';
}
}
}

int main(void){
clrscr();
textmode(C80);gotoxy(40,13);
wrxy();
delpoz();
key=0;
while (key!=27) {
key=getch();
switch (key){
case 0: break;
case dl: del();break;
case ins: wrpoz();break;
case end: delpoz();del();break;
case home: gotoxy(40,13);break;
case lf: if(wherex()>2) gotoxy(wherex() -2,wherey() );wrxy();break;
case rt: if(wherex()<77) gotoxy(wherex() +2,wherey() );wrxy();break;
case up: if(wherey()>2) gotoxy(wherex(), wherey() -1);wrxy();break;
case dw: if(wherey()<25) gotoxy(wherex(), wherey() +1);wrxy();break;
default: wrxy();cprintf("%c",key);gotoxy(x,y);pozitie[x/2-1][y-2]=(char)key;break;
}
}
return 0;
}

Preluarea argumentelor liniei de comanda. Exemplul 1  (arg0.c)

#include <stdio.h>
int main(int nrarg, char **args){
int i;
printf("Acest program are %d argumente\n",nrarg);
for(i=0;i<nrarg;i++){
printf("args[%d] = %s\n",i,args[i]);
}
}
/* raspunsul la comanda
D:\_work>args0 1 2 33 444 555 6666 77777

este:

Acest program are 8 argumente
args[0] = D:\_WORK\ARGS0.EXE
args[1] = 1
args[2] = 2
args[3] = 33
args[4] = 444
args[5] = 555
args[6] = 6666
args[7] = 77777
*/

Preluarea argumentelor liniei de comanda. Exemplul 2  (arg1.c)

#include <stdio.h>
int main(int nrarg, char args[]){
int i;
printf("Acest program are %d argumente\n",nrarg);
for(i=0;i<nrarg;i++){
printf("args[%d] = %s\n",i,args[i]);
}
}
/* raspunsul la comanda
D:\_work>args0 1 2 33 444 555 6666 77777

este:

Acest program are 8 argumente
args[0] = D:\_WORK\ARGS0.EXE
args[1] = 1
args[2] = 2
args[3] = 33
args[4] = 444
args[5] = 555
args[6] = 6666
args[7] = 77777
*/

Testarea starii unor chei (ALT, CTRL, SHIFT, etc.) ale tastaturii (kbdkey.c)

#include <stdio.h>
#include <conio.h>
char biti[33];
void inttobiti(long a, char * biti){
int c,r,nrbiti=32;
if((a & 0xff000000)==0) nrbiti=24;
if((a & 0xffff0000)==0) nrbiti=16;
if((a & 0xffffff00)==0) nrbiti=8;
for (int i=0;i<nrbiti;i++)biti[i]='0';
biti[nrbiti]=0;
c=a;i=nrbiti-1;
while (c!=0){
r=c % 2;
if (r==1) biti[i]='1';
c=c/2;
i--;
}
}
void main(void){
union {
char far *mm;
struct {
unsigned short depl;
unsigned short base;
}pm;
unsigned short w[2];
#define base pm.base
#define depl pm.depl
}mem;
char key,status;
/*mem=0x417;*/
clrscr();
mem.w[1]=0;
mem.w[0]=0x417;
printf("mem[%04x:%04x]",mem.base,mem.depl);
key=0;
while(key!=27){
if(kbhit()!=0){ key=getch();}
gotoxy(1,5);clreol();
status=*mem.mm;
inttobiti(status,biti);
cprintf("%02x %s",*mem.mm,biti);
if(status & 128) printf("\nINS");else printf("\n ");
if(status & 64) printf("\nCAPS LOCK");else printf("\n ");
if(status & 32) printf("\nNUM LOCK");else printf("\n ");
if(status & 16) printf("\nSCROLL LOCK");else printf("\n ");
if(status & 8) printf("\nALT");else printf("\n ");
if(status & 4) printf("\nCONTROL");else printf("\n ");
if(status & 2) printf("\nLEFT SHIFT");else printf("\n ");
if(status & 1) printf("\nRIGHT SHIFT");else printf("\n ");

}
/*printf("%d\n",sizeof(uch.b));*/
}

Lucrul cu rutinele de intrerupere

Microcalculatoarele IBM PC si compatibile recunosc 256 de intreruperi numerotate de la 0 la 255. Fiecarui tip de intrerupere ii este asociat cuvantul dublu de la adresa 0:i*4, numit vector de intrerupere. Aceasta locatie contine adresa unei rutine care deserveste intreruperea respectiva. Spre exemplu vectorul de intrerupere 0x33 este alocat mouse-ului.

Argumentele si rezultatele rutilelor de intrerupere  sunt transmise prin intermediul unei structuri de tip REGPACK declarata in biblioteca <dos.h>

struct REGPACK {
unsigned r_ax, r_bx, r_cx, r_dx;
unsigned r_bp, r_si, r_di, r_ds, r_es, r_flags;
};

in care indetificatorii r_ax, r_bx, ... , desemneaza evident continutul registrelor corespunzatoare, ax, bx etc., inainte si dupa executia rutinei de intrerupere.

Lucrul cu mouse-ul in fereastra de text (mouse0.c)

/* in dos.h este definita structura
struct REGPACK {
unsigned r_ax, r_bx, r_cx, r_dx;
unsigned r_bp, r_si, r_di, r_ds, r_es, r_flags;
};

ca si rutina intr de apel a 
void _Cdecl intr (int __intno, struct REGPACK *__preg);

*/
#include <stdio.h>
#include <dos.h>
#include <conio.h>
enum but {nobut,leftbut,rightbut,bothbut};
char mouse_inited(void){
struct REGPACK regs;
/* rutina peek are prototipul
int peek(unsigned segm, unsigned offs);
Ea intoarce un intreg de la adresa [segm:offs]
*/
if (peek(0,0x33*4)==0) return 0;
else { regs.r_ax=0;
intr(0x33,&regs);
return regs.r_ax !=0;}

}
void mouse_setcursor(void){
struct REGPACK regs;
regs.r_ax=10;
regs.r_bx=0;
regs.r_cx=0x77ff;
regs.r_dx=0x7700;
intr(0x33,&regs);
}
void mouse_showcursor(void){
struct REGPACK regs;
regs.r_ax=1;
intr(0x33,&regs);
}
void mouse_hidecursor(void){
struct REGPACK regs;
regs.r_ax=2;
intr(0x33,&regs);
}

void mouse_status(but *b,int *h,int *v){
struct REGPACK regs;
regs.r_ax=3;
intr(0x33,&regs);
*h=regs.r_cx / 8; *v=regs.r_dx /8;
switch (regs.r_bx & 3) {
case 0:*b=nobut;break;
case 1:*b=leftbut;break;
case 2:*b=rightbut;break;
case 3:*b=bothbut;break;
}
}

void main(void){
char key;but b;int h,v;
clrscr();
if(!mouse_inited()) {printf("Mouse not instaled");return;}
else printf("Mouse well instaled");
mouse_setcursor();
mouse_showcursor();
/*mouse_hidecursor();*/
key=0;
while (key!=27){
mouse_status(&b,&h,&v);
gotoxy(1,24);clreol();printf("[%2d,%2d]",h,v);
if(b==nobut)printf(" nobut");
if(b==leftbut)printf(" leftbut");
if(b==rightbut)printf(" rightbut");
if(b==bothbut)printf(" bothbut");

if(kbhit()!=0)key=getch();

}

}

Cornel Mironel Niculae, 2003-2004

16-Dec-2003