再談main()主函數
每一C 程序都必須有一main()函數,可以根據自己的愛好把它放在程序的某個地方。有些程序員把它放在最前面,而另一些程序員把它放在最後面,無論放在哪個地方,以下幾點說明都是適合的。
1. main() 參數
在Turbo C2.0啟動過程中,傳遞main()函數三個參數:argc,argv和env。
* argc: 整數,為傳給main()的命令行參數個數。
* argv: 字符串數組。
在DOS 3.X 版本中,argv[0] 為程序運行的全路徑名;
對DOS 3.0 以下的版本,argv[0]為空串("") 。argv[1] 為在DOS 命令行中執行程序名後的第一個字符串;argv[2] 為執行程序名後的第二個字符串;
...
argv[argc]為NULL。
*env: 安符串數組。env[] 的每一個元素都包含ENVVAR=value形式的字符串。其中ENVVAR為環境變量如PATH或87。value 為ENVVAR的對應
值如C:\DOS,C:\TURBOC(對於PATH) 或YES(對於87)。
TurboC2.0啟動時總是把這三個參數傳遞給main()函數,可以在用戶程序中說明(或不說明)它們,如果說明了部分(或全部)參數,它們就成
為main()子程序的局部變量。 請注意:一旦想說明這些參數,則必須按argc,argv, env的順序,如以下的例子:
main()
main(int argc)
main(int argc, char *argv[])
main(int argc, char *argv[], char *env[])
其中第二種情況是合法的,但不常見,因為在程序中很少有只用argc,而不用argv[]的情況。以下提供一樣例程序EXAMPLE.EXE, 演示如何在main()函數中使用三個參數:
/*program name EXAMPLE.EXE*/
#include
#include
main(int argc,char *argv[],char *env[])
{
int i;
printf("These are the %d command-line arguments passed to \
main:\n\n", argc);
for(i=0; i<=argc; i++)
printf("argv[%d]:%s\n", i, argv[i]);
printf("\nThe environment string(s)on this system are: \
\n\n");
for(i=0; env[i]!=NULL; i++)
printf(" env[%d]:%s\n", i, env[i]);
}
如果在DOS 提示符下,按以下方式運行EXAMPLE.EXE: C:\example first_argument "argument with blanks" 3 4"last butone" stop!
注意:
可以用雙引號括起內含空格的參數,如本例中的:"argumentwith blanks"和"Last but one")。 應該提醒的是:傳送main() 函數的命令
行參數的最大長度為128個字符 (包括參數間的空格),這是由DOS 限制的。文本窗口的定義Turbo C2.0的字符屏幕函數主要包括文本窗口大小
的設定、窗口顏色的設置、窗口文本的清除和輸入輸出等函數。
Turbo C2.0默認定義的文本窗口為整個屏幕,共有80列(或40列)25行的文本單元,每個單元包括一個字符和一個屬性,字符即ASCII碼字符,屬性規定該字符的顏色和強度。
Turbo C2.0可以定義屏幕上的一個矩形域作為窗口,使用window()函數定義。窗口定義之後,用有關窗口的輸入輸出函數就可以只在此窗口內進行操作而不超出窗口的邊界。window()函數的調用格式為: void window(int left, int top, int right, int bottom);該函數的原型
在conio.h 中 (關於文本窗口的所有函數其頭文件均為conio.h,後面不再說明)。 函數中形式參數(int left, int top)是窗口左上角的坐標,(int right, int bottom)是窗口的右下角坐標,其中(left, top)和(right, bottom) 是相對於整個屏幕而言的。
Turbo C 2.0規定整個屏幕的左上角坐標為(1, 1),右下角坐標為(80, 25)。並規定沿水平方向為 X軸,方向朝右;沿垂直方向為 Y軸,
方向朝下。若window()函數中的坐標超過了屏幕坐標的界限,則窗口的定義就失去了意義,也就是說定義將不起作用,但程序編譯鏈接時並不
出錯。另外,一個屏幕可以定義多個窗口,但現行窗口只能有一個 (因為DOS為單任務操作系統),當需要用另一窗口時,可將定義該窗口的
window() 函數再調用一次,此時該窗口便成為現行窗口了。如要定義一個窗口左上角在屏幕(20,5)處,大小為30列15行的窗口可寫成: window(20, 5, 50, 25);文本窗口顏色的設置文本窗口顏色的設置包括背景顏色的設置和字符顏色的設置,使用的函數及其調用格式為: 設置
背景顏色: void textbackground(int color); 設置字符顏色: void textcolor(int color); 有關顏色的定義見下表:
━━━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含義 字符或背景
──────────────────────────
BLACK 0 黑 兩者均可
BLUE 1 蘭 兩者均可
GREEN 2 綠 兩者均可
CYAN 3 青 兩者均可
RED 4 紅 兩者均可
MAGENTA 5 洋紅 兩者均可
BROWN 6 棕 兩者均可
LIGHTGRAY 7 淡灰 兩者均可
DARKGRAY 8 深灰 只用於字符
LIGHTBLUE 9 淡蘭 只用於字符
LIGHTGREEN 10 淡綠 只用於字符
LIGHTCYAN 11 淡青 只用於字符
LIGHTRED 12 淡紅 只用於字符
LIGHTMAGENTA 13 淡洋紅 只用於字符
YELLOW 14 黃 只用於字符
WHITE 15 白 只用於字符
BLINK 128 閃爍 只用於字符
━━━━━━━━━━━━━━━━━━━━━━━━━━━
上表中的符號常數與相應的數值等價,二者可以互換。例如設定 蘭色背景可以使用textbackground(1), 也可以使用textbackground
(BLUE),兩者沒有任何區別,只不過後者比較容易記憶,一看就知道是蘭色。
Turbo C 另外還提供了一個函數,可以同時設置文本的字符和背景顏色,這個函數的調用格式為: void textattr(int attr); 其中: attr的值表示顏色形式編碼的信息,每一位代表的含義如下:
位 7 6 5 4 3 2 1 0
B b b b c c c c
↓ ┕━━━┙ ┖─────┘
閃爍 背景顏色 字符顏色
字節低四位cccc設置字符顏色(0到15),4 ̄6三位bbb設置背景顏色(0到7),第7位B設置字符是否閃爍。假如要設置一個蘭底黃字,定義方法
如下: textattr(YELLOW+(BLUE<<4)); 若再要求字符閃爍,則定義變為: textattr(128+YELLOW+(BLUE<<4);
注意:
(1) 對於背景只有0 到7 共八種顏色,若取大於7 小於15的數,則代表的顏色與減 7後的值對應的顏色相同。
(2) 用textbackground()和textcolor() 函數設置了窗口的背景與字符顏色後,在沒有用clrscr()函數清除窗口之前,顏色不會改變,直到
使用了函數clrscr(),整個窗口和隨後輸出到窗口中的文本字符才會變成新顏色。
(3) 用textattr()函數時背景顏色應左移4位,才能使3位背景顏色移到正確位置下面這個程序使用了關於窗口大小的定義、顏色的設置等函
數,在一個屏幕上不同位置定義了7個窗口,其背景色分別使用了7種不同的顏色。
#include
#include
main()
{
int i;
textbackground(0); /* 設置屏幕背景色 */
clrscr(); /* 清除文本屏幕 */
for(i=1; i<8; i++)
{
window(10+i*5, 5+i, 30+i*5, 15+i); /* 定義文本窗口 */
textbackground(i); /* 定義窗口背景色 */
clrscr(); /* 清除窗口 */
}
getch();
}
窗口內文本的輸入輸出函數
一、窗口內文本的輸出函數
int cprintf("<格式化字符串>", <變量表>); int cputs(char *string); int putch(int ch); cprintf() 函數輸出一個格式化的字符串或數值到窗口中。它與printf()函數的用法完全一樣,區別在於cprintf() 函數的輸出受窗口限制,而printf() 函數的輸出為整個屏幕。
cputs()函數輸出一個字符串到屏幕上,它與puts() 函數用法完全一樣, 只是受窗口大小的限制。
putch()函數輸出一個字符到窗口內。
注意:
①使用以上幾種函數, 當輸出超出窗口的右邊界時會自動轉到下一行的開始處繼續輸出。②當窗口內填滿內容仍沒有結束輸出時,窗口屏幕將會自動逐行上卷直到輸出結束為止。
二、窗口內文本的輸入函數
int getche(void); 該函數在前面已經講過,需要說明的是,getche()函數從鍵盤上獲得一個字符,在屏幕上顯示的時候,如果字符超過了窗口右邊界,則會被自動轉移到下一行的開始位置。
下面這個程序給上例中加入了一些文本的輸出函數。
#include
#include
int main()
{
int i;
char *c[]={"BLACK", "BLUE", "GREEN", "CYAN", "RED",
"MAGENTA", "BROWN", "LIGHTGRAY"};
textbackground(0); /* 設置屏幕背景色 */
clrscr(); /* 清除文本屏幕 */
for(i=1; i<8; i++)
{
window(10+i*5,5+i,30+i*5,15+i); /* 定義文本窗口 */
textbackground(i); /* 定義窗口背景色 */
clrscr(); /* 清除窗口 */
}
getch();
return 0;
}
有關屏幕操作的函數
void clrscr(void); 清除當前窗口中的文本內容, 並把光標定位在窗口的左上角(1, 1)處。 void clreol(void); 清除當前窗口中從光
標位置到行尾的所有字符, 光標位置不變。 void gotoxy(x, y); 該函數很有用, 它用來定位光標在當前窗口中的位置。這裡x,y是指光標要
定位處的坐標(相對於窗口而言),當x,y超出了窗口的大小時,該函數就不起作用了。
int gettext(int xl,int yl,int x2,int y2,void *buffer);
int puttext(int x1,int y1,int x2,int y2,void *buffer);
gettext()函數是將屏幕上指定的矩形區域內文本內容存入buffer 指針指向的一個內存空間。內存的大小用下式計算: 所用字節大小=行數*列
數*2。其中:
行數=y2-y1+1 列數=x2-x1+1 puttext()函數則是將gettext()函數存入內存buffer中的文字內容拷貝到屏幕上指定的位置。
int movetext(int x1, int x2, int y2, int x3, int y3); movetext()函數將屏幕上左上角為(x1, y1),右下角為(x2, y2)的一矩形窗口內的文本內容拷貝到左上角為(x3, y3)的新的位置。該函數的坐標也是相對於整個屏幕而言的。
注意:
1. gettext()函數和puttext() 函數中的坐標是對整個屏幕而言的, 即是屏幕的絕對坐標,而不是相對窗口的坐標。
2. movetext()函數是拷貝而不是移動窗口區域內容, 即使用該函數後, 原位置區域的文本內容仍然存在。
#include
main()
{
int i;
char *f[]={"Load F3","Pick Alt-F3","New ",
"Save F2","Write to ","Directory",
"Change dir","Os shell ","Quit Alt-X"};
char buf[11*16*2];
clrscr();
textcolor(YELLOW);
textbackground(BLUE);
clrscr();
gettext(10, 2, 24, 11, buf);
window(10, 2, 24, 11);
textbackground(RED);
textcolor(YELLOW);
clrscr();
for(i=0; i<9; i++)
{
gotoxy(1, i+1);
cprintf("%s", f[i]);
}
getch();
movetext(10, 2, 24, 11, 40, 10);
puttext(10, 2, 24, 11, buf);
getch();
}
下面再介紹一些函數:
void highvideo(void); 設置顯示器高亮度顯示字符
void lowvideo(void); 設置顯示器低亮度顯示字符
void normvideo(void); 使顯示器返回到程序運行前的顯示方式
int wherex(void); 這兩個函數返回當前窗口下光標的x,y坐標
int wherey(void); Turbo C 提供了非常豐富的圖形函數,所有圖形函數的原型均在graphics. h 中,本節主要介紹圖形模式的初始化、獨立圖形程序的建立、基本圖形功能、圖形窗口以及圖形模式下的文本輸出等函數。另外,使用圖形函數時要確保有顯示器圖形驅動程序*BGI,同時將集成開發環境Options/Linker中的Graphics lib選為on,只有這樣才能保證正確使用圖形函數。圖形模式的初始化不同的顯示器適配器有不同的圖形分辨率。即是同一顯示器適配器,在不同模式下也有不同分辨率。因此,在屏幕作圖之前,必須根據顯示器適配器種類將顯示器設置成為某種圖形模式,在未設置圖形模式之前,微機系統默認屏幕為文本模式(80列,25行字符模式),此時所有圖形函數均不能工作。設置屏幕為圖形模式,可用下列圖形初始化函數:
void far initgraph(int far *gdriver, int far *gmode,char *path);
其中gdriver和gmode分別表示圖形驅動器和模式,path是指圖形驅動程序所在的目錄路徑。有關圖形驅動器、圖形模式的符號常數及對應的分辨率見下表。
圖形驅動程序由Turbo C出版商提供,文件擴展名為.BGI。 根據不同的圖形適配器有不同的圖形驅動程序。例如對於EGA、 VGA 圖形適配器就調用驅動程序EGAVGA.BGI。
圖形驅動器、模式的符號常數及數值
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
圖形驅動器(gdriver) 圖形模式(gmode)
───────────────────── 色調 分辨率
符號常數 數值 符號常數 數值
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CGA 1 CGAC0 0 C0 320*200
CGAC1 1 C1 320*200
CGAC2 2 C2 320*200
CGAC3 3 C3 320*200
CGAHI 4 2色 640*200
──────────────────────────────
MCGA 2 MCGAC0 0 C0 320*200
MCGAC1 1 C1 320*200
MCGAC2 2 C2 320*200
MCGAC3 3 C3 320*200
MCGAMED 4 2色 640*200
MCGAHI 5 2色 640*480
──────────────────────────────
EGA 3 EGALO 0 16色 640*200
EGAHI 1 16色 640*350
──────────────────────────────
EGA64 4 EGA64LO 0 16色 640*200
EGA64HI 1 4色 640*350
──────────────────────────────
EGAMON 5 EGAMONHI 0 2色 640*350
──────────────────────────────
IBM8514 6 IBM8514LO 0 256色 640*480
IBM8514HI 1 256色 1024*768
──────────────────────────────
HERC 7 HERCMONOHI 0 2色 720*348
──────────────────────────────
ATT400 8 ATT400C0 0 C0 320*200
ATT400C1 1 C1 320*200
ATT400C2 2 C2 320*200
ATT400C3 3 C3 320*200
ATT400MED 4 2色 320*200
ATT400HI 5 2色 320*200
──────────────────────────────
VGA 9 VGALO 0 16色 640*200
VGAMED 1 16色 640*350
VGAHI 2 16色 640*480
──────────────────────────────
PC3270 10 PC3270HI 0 2色 720*350
──────────────────────────────
DETECT 0 用於硬件測試
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
使用圖形初始化函數設置VGA高分辨率圖形模式#include
int main()
{
int gdriver, gmode;
gdriver=VGA;
gmode=VGAHI;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
bar3d(100, 100, 300, 250, 50, 1); /*畫一長方體*/
getch();
closegraph();
return 0;
}
有時編程者並不知道所用的圖形顯示器適配器種類,或者需要將編寫的程序用於不同圖形驅動器,Turbo C 提供了一個自動檢測顯示器硬件的函數,其調用格式為: void far detectgraph(int *gdriver, *gmode); 其中gdriver和gmode的意義與上面相同。 自動進行硬件測試後進行圖形初始化#include
int main()
{
int gdriver, gmode;
detectgraph(&gdriver, &gmode); /*自動測試硬件*/
printf("the graphics driver is %d, mode is %d\n",
gdriver,gmode); /*輸出測試結果*/
getch();
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
/* 根據測試結果初始化圖形*/
bar3d(10, 10, 130, 250, 20, 1);
getch();
closegraph();
return 0;
}
上例程序中先對圖形顯示器自動檢測,然後再用圖形初始化函數進行初始化設置,但Turbo C提供了一種更簡單的方法, 即用driver=DETECT 語句後再跟initgraph()函數就行了。采用這種方法後,上例可改為:
#include
int main()
{
int gdriver=DETECT, gmode;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
bar3d(50, 50, 150, 30, 50, 1);
getch();
closegraph();
return 0;
}
另外,Turbo C 提供了退出圖形狀態的函數closegraph(),其調用格式為: void far closegraph(void); 調用該函數後可退出圖形狀態而進入文本方式( Turbo C 默認方式),並釋放用於保存圖形驅動程序和字體的系統內存。獨立圖形運行程序的建立Turbo C對於用initgraph()函數直接進行的圖形初始化程序,在編譯和鏈接時並沒有將相應的驅動程序(*.BGI) 裝入到執行程序,當程序進行到intitgraph()語句時,再從該函數中第三個形式參數char *path中所規定的路徑中去找相應的驅動程序。若沒有驅動程序,則在C:\TC中去找,如C:\TC中仍沒有或TC不存在,將會出現錯誤:
BGI Error: Graphics not initialized (use 'initgraph')
因此,為了使用方便,應該建立一個不需要驅動程序就能獨立運行的可執行圖形程序,Turbo C中規定用下述步驟(這裡以EGA、VGA顯示器為例):
1. 在C:\TC子目錄下輸入命令:BGIOBJ EGAVGA此命令將驅動程序EGAVGA.BGI轉換成EGAVGA.OBJ的目標文件。
2. 在C:\TC子目錄下輸入命令:TLIB LIB\GRAPHICS.LIB+EGAVGA此命令的意思是將EGAVGA.OBJ的目標模塊裝到GRAPHICS.LIB庫文
件中。
3. 在程序中initgraph()函數調用之前加上一句: registerbgidriver(EGAVGA_driver):該函數告訴連接程序在連接時把EGAVGA的驅動程序裝入到用戶的執行程序中。
經過上面處理,編譯鏈接後的執行程序可在任何目錄或其它兼容機上運行。假設已作了前兩個步驟,若再向例6中加registerbgidriver()函數則變成:
#include
#include
int main()
{
int gdriver=DETECT,gmode;
registerbgidriver(EGAVGA_driver);
/*建立獨立圖形運行程序 */
initgraph(gdriver, gmode,"c:\\caic\\bgi");
bar3d(50,50,250,150,20,1);
getch();
closegraph();
return 0;
}
上例編譯鏈接後產生的執行程序可獨立運行。如不初始化成EGA或CGA分辨率,而想初始化為CGA分辨率, 則只需要將上述步驟中有EGAVGA的地方用CGA代替即可。屏幕顏色的設置和清屏函數對於圖形模式的屏幕顏色設置,同樣分為背景色的設置和前景色的設置。
在Turbo C中分別用下面兩個函數。 設置背景色: void far setbkcolor(int color); 設置作圖色: void far setcolor(int color); 其中color 為圖形方式下顏色的規定數值,對EGA,VGA顯示器適配器,有關顏色的符號常數及數值見下表所示。
有關屏幕顏色的符號常數表:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含義 符號常數 數值 含義
──────────────────────────────
BLACK 0 黑色 DARKGRAY 8 深灰
BLUE 1 蘭色 LIGHTBLUE 9 深蘭
GREEN 2 綠色 LIGHTGREEN 10 淡綠
CYAN 3 青色 LIGHTCYAN 11 淡青
RED 4 紅色 LIGHTRED 12 淡紅
MAGENTA 5 洋紅 LIGHTMAGENTA 13 淡洋紅
BROWN 6 棕色 YELLOW 14 黃色
LIGHTGRAY 7 淡灰 WHITE 15 白色
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
對於CGA適配器,背景色可以為表3中16種顏色的一種,但前景色
依賴於不同的調色板。共有四種調色板,每種調色板上有四種顏色可
供選擇。不同調色板所對應的原色見下表:
CGA調色板與顏色值表:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
調色板 顏色值
──────────────────────────────
符號常數 數值 0 1 2 3
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
C0 0 背景 綠 紅 黃
C1 1 背景 青 洋紅 白
C2 2 背景 淡綠 淡紅 黃
C3 3 背景 淡青 淡洋紅 白
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
清除圖形屏幕內容使用清屏函數,其調用格式如下: voide far cleardevice(void); 有關顏色設置、清屏函數的使用請看例8。#include
#include
int main()
{
int gdriver, gmode, i;
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi"); /*圖形初始化*/
setbkcolor(0); /*設置圖形背景*/
cleardevice();
for(i=0; i<=15; i++)
{
setcolor(i); /*設置不同作圖色*/
circle(320, 240, 20+i*10); /*畫半徑不同的圓*/
delay(100); /*延遲100毫秒*/
}
for(i=0; i<=15; i++)
{
setbkcolor(i); /*設置不同背景色*/
cleardevice();
circle(320, 240, 20+i*10);
delay(100);
}
closegraph();
return 0;
}
另外,TURBO C也提供了幾個獲得現行顏色設置情況的函數。
int far getbkcolor(void); 返回現行背景顏色值。
int far getcolor(void); 返回現行作圖顏色值。
int far getmaxcolor(void); 返回最高可用的顏色值。
基本圖形函數
基本圖形函數包括畫點,線以及其它一些基本圖形的函數。本節對這些函數作一全面的介紹。
一、畫點
1. 畫點函數 void far putpixel(int x, int y, int color); 該函數表示有指定的象元畫一個按color 所確定顏色的點。對於顏色color的值可從表3中獲得而對x, y是指圖形象元的坐標。在圖形模式下,是按象元來定義坐標的。對VGA適配器, 它的最高分辨率為640x480,其中640為整個屏幕從左到右所有象元的個數,480 為整個屏幕從上到下所有象元的個數。屏幕的左上角坐標為(0,0),右下角坐標為(639, 479),水平方向從左到右為x 軸正向,垂直方向從上到下為y軸正向。TURBO C的圖形函數都是相對於圖形屏幕坐標,即象元來說的。關於點的另外一個函數是: int far getpixel(int x, int y); 它獲得當前點(x, y)的顏色值。
2. 有關坐標位置的函數
int far getmaxx(void); 返回x軸的最大值。
int far getmaxy(void); 返回y軸的最大值。
int far getx(void); 返回游標在x軸的位置。
void far gety(void); 返回游標有y軸的位置。
void far moveto(int x, int y); 移動游標到(x, y)點,不是畫點,在移動過程中亦畫點。
void far moverel(int dx, int dy); 移動游標從現行位置(x, y)移動到(x+dx, y+dy)的位置,移動過程中不畫點。
二、畫線
1. 畫線函數
TURBO C提供了一系列畫線函數,下面分別敘述:
void far line(int x0, int y0, int x1, int y1); 畫一條從點(x0, y0)到(x1, y1)的直線。
void far lineto(int x, int y); 畫一作從現行游標到點(x, y)的直線。
void far linerel(int dx, int dy); 畫一條從現行游標(x,y)到按相對增量確定的點(x+dx, y+dy)的直線。
void far circle(int x, int y, int radius); 以(x, y)為圓心,radius為半徑,畫一個圓。
void far arc(int x, int y, int stangle, int endangle,int radius); 以(x,y)為圓心,radius為半徑,從stangle開始到endangle結束
(用度表示)畫一段圓弧線。在TURBO C中規定x軸正向為0 度,逆時針方向旋轉一周, 依次為90,180, 270和360度(其它有關函數也按此規定不再重述)。
void ellipse(int x, int y, int stangle, int endangle,int xradius,int yradius);以(x, y)為中心,xradius,yradius為x軸和y軸半
徑,從角stangle 開始到endangle結束畫一段橢圓線,當stangle=0,endangle=360時, 畫出一個完整的橢圓。
void far rectangle(int x1, int y1, int x2, inty2); 以(x1, y1)為左上角,(x2, y2)為右下角畫一個矩形框。
void far drawpoly(int numpoints, int far *polypoints); 畫一個頂點數為numpoints,各頂點坐標由polypoints給出的多邊形。 polypoints整型數組必須至少有2 倍頂點數個無素。每一個頂點的坐標都定義為x,y,並且x在前。值得注意的是當畫一個封閉的多邊形時,numpoints 的值取實際多邊形的頂點數加一,並且數組polypoints中第一個和最後一個點的坐標相同。
下面舉一個用drawpoly()函數畫箭頭的例子。#include
#include
int main()
{
int gdriver, gmode, i;
int arw[16]={200,102,300,102,300,107,330,
100,300,93,300,98,200,98,200,102};
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
setbkcolor(BLUE);
cleardevice();
setcolor(12); /*設置作圖顏色*/
drawpoly(8, arw); /*畫一箭頭*/
getch();
closegraph();
return 0;
}
設定線型函數
在沒有對線的特性進行設定之前,TURBO C 用其默認值,即一點寬的實線,但TURBO C 也提供了可以改變線型的函數。線型包括:寬度和形狀。其中寬度只有兩種選擇:一點寬和三點寬。而線的形狀則有五種。下面介紹有關線型的設置函數。
void far setlinestyle(intlinestyle,unsigned upattern,int thickness); 該函數用來設置線的有關信息,其中linestyle是線形狀的規定,
見下表:
有關線的形狀(linestyle)
━━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含義
─────────────────────────
SOLID_LINE 0 實線
DOTTED_LINE 1 點線
CENTER_LINE 2 中心線
DASHED_LINE 3 點畫線
USERBIT_LINE 4 用戶定義線
━━━━━━━━━━━━━━━━━━━━━━━━━
有關線寬(thickness)
thickness是線的寬度,見下表。
━━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含義
─────────────────────────
NORM_WIDTH 1 一點寬
THIC_WIDTH 3 三點寬
━━━━━━━━━━━━━━━━━━━━━━━━━
對於upattern,只有linestyle選USERBIT_LINE 時才有意義 (選其它線型,uppattern取0即可)。此進uppattern的16位二進制數的每一位代表一個象元,如果那位為1,則該象元打開,否則該象元關閉。 void far getlinesettings(struct linesettingstypefar *lineinfo);該函數將有關線的信息存放到由lineinfo 指向的結構中,表中linesettingstype的結構如下:
struct linesettingstype
{
int linestyle;
unsigned upattern;
int thickness;
}
例如下面兩句程序可以讀出當前線的特性 struct linesettingstype *info;getlinesettings(info);void far setwritemode(int mode); 該函數規定畫線的方式。如果mode=0,則表示畫線時將所畫位置的原來信息覆蓋了(這是TURBO C的默認方式)。如果mode=1, 則表示畫線時用現在特性的線與所畫之處原有的線進行異或(XOR)操作, 實際上畫出的線是原有線與現在規定的線進行異或後的結果。因此,當線的特性不變,進行兩次畫線操作相當於沒有畫線。
有關線型設定和畫線函數的例子如下所示:
#include
#include
int main()
{
int gdriver, gmode, i;
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
setbkcolor(BLUE);
cleardevice();
setcolor(GREEN);
circle(320, 240, 98);
setlinestyle(0, 0, 3); /*設置三點寬實線*/
setcolor(2);
rectangle(220, 140, 420, 340);
setcolor(WHITE);
setlinestyle(4, 0xaaaa, 1);
/*設置一點寬用戶定義線*/
line(220, 240, 420, 240);
line(320, 140, 320, 340);
getch();
closegraph();
return 0;
}
封閉圖形的填充
填充就是用規定的顏色和圖模填滿一個封閉圖形。
一、先畫輪廓再填充
TURBO C提供了一些先畫出基本圖形輪廓, 再按規定圖模和顏色填充整個封閉圖形的函數。在沒有改變填充方式時,TURBO C 以默認方式填充。 下面介紹這些函數。 void far bar(int x1, int y1, int x2, int y2); 確定一個以(x1, y1)為左上角,(x2, y2)為右下角的矩形窗口,
再按規定圖模和顏色填充。
說明:此函數不畫出邊框,所以填充色為邊框。 void far bar3d(int x1, int y1, int x2, int y2,int depthint topflag);當topflag為非0時, 畫出一個三維的長方體。當topflag為0時,三維圖形不封頂,實際上很少這樣使用。
說明: bar3d()函數中,長方體第三維的方向不隨任何參數而變,即始終為45度的方向。
void far pieslice(int x,int y,int stangle,int endangle,int radius); 畫一個以(x, y)為圓心,radius為半徑,stangle為起始角度,endangle 為終止角度的扇形,再按規定方式填充。當stangle=0,endangle=360 時變成一個實心圓,並在圓內從圓點沿X軸正向畫一條半徑。
void far sector(int x, int y,int stanle,intendangle,int xradius, int yradius);畫一個以(x, y)為圓心分別以xradius, yradius為x軸和y軸半徑,stangle 為起始角,endangle為終止角的橢圓扇形,再按規定方式填充。
二、設定填充方式
TURBO C有四個與填充方式有關的函數。下面分別介紹:
void far setfillstyle(int pattern, int color); color的值是當前屏幕圖形模式時顏色的有效值。pattern的值及與其等價的符號常數如下表所示。關於填充式樣pattern的規定:
━━━━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含義
───────────────────────────
EMPTY_FILL 0 以背景顏色填充
SOLID_FILL 1 以實填充
LINE_FILL 2 以直線填充
LTSLASH_FILL 3 以斜線填充(陰影線)
SLASH_FILL 4 以粗斜線填充(粗陰影線)
BKSLASH_FILL 5 以粗反斜線填充(粗陰影線)
LTBKSLASH_FILL 6 以反斜線填充(陰影線)
HATCH_FILL 7 以直方網格填充
XHATCH_FILL 8 以斜網格填充
INTTERLEAVE_FILL 9 以間隔點填充
WIDE_DOT_FILL 10 以稀疏點填充
CLOSE_DOS_FILL 11 以密集點填充
USER_FILL 12 以用戶定義式樣填充
除USER_FILL(用戶定義填充式樣)以外,其它填充式樣均可由setfillstyle() 函數設置。當選用USER_FILL時,該函數對填充圖模和顏色不作任何改變。 之所以定義USER_FILL主要因為在獲得有關填充信息時用到此項。 void far setfillpattern(char * upattern,int color); 設置用戶定義的填充圖模的顏色以供對封閉圖形填充。其中upattern是一個指向8個字節的指針。這8個字節定義了8x8點陣的圖形。每個字節的8位二進制數表示水平8點,8個字節表示8行,然後以此為模型向個封閉區域填充。 void far getfillpattern(char * upattern); 該函數將用戶定義的填充圖模存入upattern指針指向的內存區域。
void far getfillsetings(struct fillsettingstypefar * fillinfo); 獲得現行圖模的顏色並將存入結構指針變量fillinfo中。
其中fillsettingstype結構定義如下:
struct fillsettingstype
{
int pattern; /* 現行填充模式 * /
int color; /* 現行填充模式 * /
}; 有關圖形填充圖模的顏色的選擇,請看下面例程。#include
main()
{
char str[8]={10,20,30,40,50,60,70,80}; /*用戶定義圖模*/
int gdriver,gmode,i;
struct fillsettingstype save;
/*定義一個用來存儲填充信息的結構變量*/
gdriver=DETECT;
initgraph(&gdriver,&gmode,"c:\\caic\\bgi");
setbkcolor(BLUE);
cleardevice();
for(i=0;i<13;i++)
{
setcolor(i+3);
setfillstyle(i,2+i); /* 設置填充類型 *
bar(100,150,200,50); /*畫矩形並填充*/
bar3d(300,100,500,200,70,1); /* 畫長方體並填充*/
pieslice(200, 300, 90, 180, 90);/*畫扇形並填充*/
sector(500,300,180,270,200,100);/*畫橢圓扇形並填充*/
delay(1000); /*延時1秒*/
}
cleardevice();
setcolor(14);
setfillpattern(str, RED);
bar(100,150,200,50);
bar3d(300,100,500,200,70,0);
pieslice(200,300,0,360,90);
sector(500,300,0,360,100,50);
getch();
getfillsettings(&save);
/*獲得用戶定義的填充模式信息*/
closegraph();
clrscr();
printf("The pattern is %d, The color of filling is %d",
save.pattern, save.color);
/*輸出目前填充圖模和顏色值*/
getch();
}
以上程序運行結束後,在屏幕上顯示出現行填充圖模和顏色的常數值。
三、任意封閉圖形的填充
截止目前為止,我們只能對一些特定形狀的封閉圖形進行填充,但還不能對任意封閉圖形進行填充。為此,TURBO C 提供了一個可對任意封閉圖形填充的函數,其調用格式如下: void far floodfill(int x, int y, int border); 其中:x, y為封閉圖形內的任意一點。border為邊界的顏色,也就是封閉圖形輪廓的顏色。調用了該函數後,將用規定的顏色和圖模填滿整個封閉圖形。
注意:
1. 如果x或y取在邊界上,則不進行填充。
2. 如果不是封閉圖形則填充會從沒有封閉的地方溢出去,填滿
其它地方。
3. 如果x或y在圖形外面,則填充封閉圖形外的屏幕區域。
4. 由border指定的顏色值必須與圖形輪廓的顏色值相同, 但填充色可選任意顏色。下例是有關floodfill()函數的用法,該程序填充了bar3d()所畫長方體中其它兩個未填充的面。
#include
#include
main()
{
int gdriver, gmode;
struct fillsettingstype save;
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
setbkcolor(BLUE);
cleardevice();
setcolor(LIGHTRED);
setlinestyle(0,0,3);
setfillstyle(1,14); /*設置填充方式*/
bar3d(100,200,400,350,200,1); /*畫長方體並填充*/
floodfill(450,300,LIGHTRED);
/*填充長方體另外兩個面*/
floodfill(250,150, LIGHTRED);
rectangle(450,400,500,450); /*畫一矩形*/
floodfill(470,420, LIGHTRED); /*填充矩形*/
getch();
closegraph();
}
有關圖形窗口和圖形屏幕操作函數
一、圖形窗口操作
象文本方式下可以設定屏幕窗口一樣,圖形方式下也可以在屏幕上某一區域設定窗口,只是設定的為圖形窗口而已,其後的有關圖形操作都將以這個窗口的左上角(0, 0)作為坐標原點,而且可為通過設置使窗口之外的區域為不可接觸。這樣,所有的圖形操作就被限定在窗口內進行。 void far setviewport(int xl,int yl,int x2, int y2,int clipflag); 設定一個以(xl,yl)象元點為左上角,(x2,y2)象元為右下角的圖
形窗口,其中x1,y1,x2,y2是相對於整個屏幕的坐標。若 clipflag為非0,則設定的圖形以外部分不可接觸,若clipflag為0,則圖形窗口
以外可以接觸。
void far clearviewport(void); 清除現行圖形窗口的內容。
void far getviewsettings(struct viewporttypefar * viewport); 獲得關於現行窗口的信息,並將其存於viewporttype定義的結構
變量viewport中,其中viewporttype的結構說明如下:
struct viewporttype
{
int left, top, right, bottom;
int cliplag;
};
注明:
1. 窗口顏色的設置與前面講過的屏幕顏色設置相同,但屏幕背景色和窗口背景色只能是一種顏色,如果窗口背景色改變,整個屏幕的背景色也將改變這與文本窗口不同。
2. 可以在同一個屏幕上設置多個窗口,但只能有一個現行窗口工作,要對其它窗口操作,通過將定義那個窗口的setviewport()函數再用一次即可。
3. 前面講過圖形屏幕操作的函數均適合於對窗口的操作。
二、屏幕操作
除了清屏函數以外,關於屏幕操作還有以下函數:
void far setactivepage(int pagenum); void far setvisualpage(int pagenum);這兩個函數只用於EGA,VGA 以及HERCULES圖形適配器。 setctivepage()函數是為圖形輸出選擇激活頁。所謂激活頁是指後續圖形的輸出被寫到函數選定的pagenum頁面,該頁面並不一定可見。
setvisualpage()函數才使pagenum所指定的頁面變成可見頁。頁面從0開始(Turbo C默認頁)。如果先用setactivepage() 函數在不同頁面
上畫出一幅幅圖像,再用setvisualpage() 函數交替顯示,就可以實現一些動畫的效果。
void far getimage(int xl,int yl, int x2,int y2,void far *mapbuf); void far putimge(int x,int,y,void * mapbuf, int op); unsined far imagesize(int xl,int yl,int x2,int y2);
這三個函數用於將屏幕上的圖像復制到內存,然後再將內存中的圖像送回到屏幕上。首先通過函數imagesize() 測試要保存左上角為
(xl,yl),右上角為(x2,y2)的圖形屏幕區域內的全部內容需多少個字節,然後再給mapbuf分配一個所測數字節內存空間的指針。通過調用
getimage()函數就可將該區域內的圖像保存在內存中,需要時可用putimage()函數將該圖像輸出到左上角為點(x, y)的位置上,其中
getimage()函數中的參數op規定如何釋放內存中圖像。 關於這個參數的定義參見下表:
putimage()函數中的op值
━━━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含 義
──────────────────────────
COPY_PUT 0 復制
XOR_PUT 1 與屏幕圖像異或的復制
OR_PUT 2 與屏幕圖像或後復制
AND_PUT 3 與屏幕圖像與後復制
NOT_PUT 4 復制反像的圖形
━━━━━━━━━━━━━━━━━━━━━━━━━━
對於imagesize()函數,只能返回字節數小於64K字節的圖像區域,否則將會出錯,出錯時返回-1。
本節介紹的函數在圖像動畫處理、菜單設計技巧中非常有用。
下面程序模擬兩個小球動態碰撞過程。#include
#include
#include
int main()
{
int i, gdriver, gmode, size;
void *buf;
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
setbkcolor(BLUE);
cleardevice();
setcolor(LIGHTRED);
setlinestyle(0,0,1);
setfillstyle(1, 10);
circle(100, 200, 30);
floodfill(100, 200, 12);
size=imagesize(69, 169, 131, 231);
buf=malloc(size);
if(!buf) return -1;
getimage(69, 169, 131, 231,buf);
putimage(500, 269, buf, COPY_PUT);
for(i=0; i<185; i++){
putimage(70+i, 170, buf, COPY_PUT);
putimage(500-i, 170, buf, COPY_PUT);
}
for(i=0;i<185; i++){
putimage(255-i, 170, buf, COPY_PUT);
putimage(315+i, 170, buf, COPY_PUT);
}
getch();
closegraph();
}
圖形模式下的文本輸出
在圖形模式下,只能用標准輸出函數,如printf(),puts(),putchar()函數輸出文本到屏幕。除此之外,其它輸出函數(如窗口輸出函數)不能使用,即是可以輸出的標准函數,也只以前景色為白色,按80列,25行的文本方式輸出。
Turbo C2.0也提供了一些專門用於在圖形顯示模式下的文本輸出函數。下面將分別進行介紹。
一、文本輸出函數 void far outtext(char far *textstring); 該函數輸出字符串指針textstring所指的文本在現行位置。
void far outtextxy(int x, int y, char far *textstring);該函數輸出字符串指針textstring所指的文本在規定的(x, y)位置。其中x和y為象元坐標。
說明:
這兩個函數都是輸出字符串,但經常會遇到輸出數值或其它類型的數據,此時就必須使用格式化輸出函數sprintf()。sprintf()函數的調用格式為: int sprintf(char *str, char *format, variable-list); 它與printf()函數不同之處是將按格式化規定的內容寫入str 指向的字符串中,返回值等於寫入的字符個數。
例如:
'C110F1sprintf(s, "your TOEFL score is %d", mark);這裡s應是字符串指針或數組,mark為整型變量。
二、有關文本字體、字型和輸出方式的設置
有關圖形方式下的文本輸出函數,可以通過setcolor()函數設置輸出文本的顏色。另外,也可以改變文本字體大小以及選擇是水平方向輸出還是垂直方向輸出。
void far settexjustify(int horiz, int vert); 該函數用於定位輸出字符串。
對使用outtextxy(int x, int y, char far *str textstring)函數所輸出的字符串,其中哪個點對應於定位坐標(x,y)在TurboC2.0中是有規定的。如果把一個字符串看成一個長方形的圖形,在水平方向顯示時,字符串長方形按垂直方向可分為頂部,中部和底部三個位置,水平方向可分為左,中,右三個位置,兩者結合就有9個位置。
settextjustify()函數的第一個參數horiz 指出水平方向三個位置中的一個,第二個參數vert指出垂直方向三個位置中的一個,二者就確定了其中一個位置。當規定了這個位置後,用outtextxy() 函數輸出字符串時, 字符串長方形的這個規定位置就對准函數中的(x,y)位置。而對用outtext()函數輸出字符串時,這個規定的位置就位於現行游標的位置。有關參數horiz和vert的取值參見下表:
參數horiz和vert的取值
━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 用於
────────────────────────
LEFT_TEXT 0 水平
RIGHT_TEXT 2 水平
BOTTOM_TEXT 0 垂直
TOP_TEXT 2 垂直
CENTER_TEXT 1 水平或垂直
━━━━━━━━━━━━━━━━━━━━━━━━
void far settextstyle(int font, int direction,int charsize);
該函數用來設置輸出字符的字形(由font確定)、輸出方向(由direction確定)和字符大小(由charsize確定)等特性。
Turbo C2.0對函數中各個參數的規定見下列各表所示:
font的取值
━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含義
────────────────────────
DEFAULT_FONT 0 8*8點陣字(缺省值)
TRIPLEX_FONT 1 三倍筆劃字體
SMALL_FONT 2 小號筆劃字體
SANSSERIF_FONT 3 無襯線筆劃字體
GOTHIC_FONT 4 黑體筆劃字
━━━━━━━━━━━━━━━━━━━━━━━━
direction的取值
━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含義
────────────────────────
HORIZ_DIR 0 從左到右
VERT_DIR 1 從底到頂
━━━━━━━━━━━━━━━━━━━━━━━━
charsize的取值
━━━━━━━━━━━━━━━━━━━━━━━━
符號常數或數值 含義
────────────────────────
1 8*8點陣
2 16*16點陣
3 24*24點陣
4 32*32點陣
5 40*40點陣
6 48*48點陣
7 56*56點陣
8 64*64點陣
9 72*72點陣
10 80*80點陣
USER_CHAR_SIZE=0 用戶定義的字符大小
━━━━━━━━━━━━━━━━━━━━━━━━
有關圖形屏幕下文本輸出和字體字型設置函數的用法請看下例:#include
#include
int main()
{
int i, gdriver, gmode;
char s[30];
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
setbkcolor(BLUE);
cleardevice();
setviewport(100, 100, 540, 380, 1);
/*定義一個圖形窗口*/
setfillstyle(1, 2); /*綠色以實填充*/
setcolor(YELLOW);
rectangle(0, 0, 439, 279);
floodfill(50, 50, 14);
setcolor(12);
settextstyle(1, 0, 8);
/*三重筆劃字體, 水平放大8倍*/
outtextxy(20, 20, "Good Better");
setcolor(15);
settextstyle(3, 0, 5);
/*無襯筆劃字體, 水平放大5倍*/
outtextxy(120, 120, "Good Better");
setcolor(14);
settextstyle(2, 0, 8);
i=620;
sprintf(s, "Your score is %d", i);
/*將數字轉化為字符串*/
outtextxy(30, 200, s);
/*指定位置輸出字符串*/
setcolor(1);
settextstyle(4, 0, 3);
outtextxy(70, 240, s);
getch();
closegraph();
return 0;
}
三、用戶對文本字符大小的設置
前面介紹的settextstyle()函數,可以設定圖形方式下輸出文本字符這字體和大小但對於筆劃型字體(除8*8點陣字以個的字體), 只能在水平和垂直方向以相同的放大倍數放大。為此Turbo C2.0又提供了另外一個setusercharsize() 函數,對筆劃字體可以分別設置水平和垂直方向的放大倍數。該函數的調用格式為:
void far setusercharsize(int mulx, int divx,int muly, int divy); 該函數用來設置筆劃型字和放大系數,它只有在settextstyle()
函數中的charsize為0(或USER_CHAR_SIZE)時才起作用,並且字體為函數settextstyle()規定的字體。調用函數setusercharsize()後,每個顯示在屏幕上的字符都以其缺省大小乘以mulx/divx為輸出字符寬,乘以muly/divy為輸出字符高。該函數的用法見下例:
#include
#include
int main()
{
int gdriver, gmode;
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
setbkcolor(BLUE);
cleardevice();
setfillstyle(1, 2); /*設置填充方式*/
setcolor(WHITE); /*設置白色作圖*/
rectangle(100, 100, 330, 380);
floodfill(50, 50, 14); /*填充方框以外的區域*/
setcolor(12); /*作圖色為淡紅*/
settextstyle(1, 0, 8); /*三重筆劃字體,放大8倍*/
outtextxy(120, 120, "Very Good");
setusercharsize(2, 1, 4, 1);
/*水平放大2倍,垂直放大4倍*/
setcolor(15);
settextstyle(3, 0, 5);
/*無襯字筆劃,放大5倍*/
outtextxy(220, 220, "Very Good");
setusercharsize(4, 1, 1, 1);
settextstyle(3, 0, 0);
outtextxy(180, 320, "Good");
getch();
closegraph();
return 0;
}