C語言已死? 這個論題成爲CSDN博客們的熱點.C語言到底有沒有死?其實我也說不清楚,因爲我現在從事的工作是用C++開發圖形程序,但是我仍然有必要寫這樣一篇文章,如果你覺得C沒有死,並且正準備學習她,那麼希望我的經歷對你有啓示作用,如果你是曾經的C癡迷者並且現在不再用C,那麼就和我一起懷念逝去的癡迷吧.
02年我進入大學計算機系,作爲一個只會用QQ聊天的電腦白癡,我內心對計算機充滿了崇拜和嚮往,我心裏想,我要通過我的學習成爲一個黑客,因爲在我心裏黑客就是計算機高手,能夠用代碼來實現自由的夢想.那時通過一些文章瞭解到真正的高手都是用底層的語言,比如彙編,比如C,甚至是機器碼(現在看起來這些觀點其實很可笑),所以我的目標就是先學好這些語言.大一我們開了C語言課,我認真的學習C的每一個特性,指針,指針的指針,結構,聯合,動態分配內存,每個現在看來很簡單的東西都讓我覺得很神祕,就這樣整個大一就在C的特性上度過了,當同學們都在接受更加神奇的VF,VB時,我仍然在dos下看着枯燥的TEXT方式(我學的時TC),有些同學不解的問我,"C語言可以象Windows程序那樣有漂亮的界面,和圖象嗎?",面對這些問題和質疑,我也開始動搖,爲什麼我學了幾乎所有見到的C的特性還是不能構造界面,還是不能繪製圖形,網絡更遙不可及..這些疑問一直伴隨我到了大二.
大二,我知道了編程這東西不是靠各種技巧,而是要靠編程思想,和算法,因爲我們開始學了數據結構,令我開心的是數據結構老師讓我用TC去構造各種結構,而不是VF,VB,這些,同學們開始一籌莫展,而我卻得意於積累下來的C的良好基礎迅速的實現並接受了數組,鏈表,樹,棧...等等這些結構,我發現我不再苦惱於我的程序結構的不堪,不再沉迷於C的精巧,而是真正開始感受編程的樂趣,不得不說的是這中間我的C語言基礎給我帶來的成就感是我學習數據結構的一個很重要的動力...當我可以熟練的應用大部分數據結構(課本上)的時候,寢室的一個哥們問我"爲什麼老師總讓我們在dos下用TC做程序呢?只能實現字符模式太沒意思了"...當時我並沒有想到老師的真正目的(應該是撇開其他應用專著於數據結構和算法的目的),而是堅信C語言的強大,我相信dos一樣可以給我繽紛的世界,就在這時開了彙編,也正好讓我更加堅信dos實際上可以更加多彩(我們學的8086,16位),學過彙編的朋友可能還記得有一張dos系統和bios系統調用的表,裏面可以對顯示器,對串口,對鍵盤鼠標,這些硬件進行操作,對顯示器的操作更是讓我眼前一亮,因爲我看到在顯示器上顯示彩色點的功能,從第一個點被打印出來我便深深的陷入其中...
我拿着自己寫的打印彩色點的C語言函數(TC裏提供彙編接口),向別的同學的請教怎樣才能打印一條線出來,結果那個經典的直線算法就在我們的討論中誕生了(算法名字忘記了,下面附帶的程序裏有),當我興高采烈的那着我彩色的直線去找老師請教(其實是想讓她表揚我)的時候老師竟然問我圖形學課本還沒發你提前買了嗎?她認爲我是看了課本.打擊啊...呵呵,但是讓我高興的是我知道了還有圖形學這門課,接下來就是飛快的跑到圖書館借到書,是清華大學孫家廣的那本,就這樣我的編程學習真正的進入的正規,圖形學,就是我的算法啓蒙領域....
現在我從事的工作仍然是圖形程序的開發,大學的日子早已遠去,學習C語言的癡迷也早已不在,但我知道C一定還在她擅長的領域發揮着領導作用,我知道在我內心深處仍懷念着她那令人琢磨不定的神祕.如果有一天真的不需要底層開發了,或者底層不在用C了,如果C真的死了,我還是願意讓她永遠留在我心裏...
附帶大二時寫的代碼:
一個dos用的定時器:
/*
=============DOS TIMER Head File
=============CopyRight (C) LGc
=============QQ:66855618
=============E-Mail: [email protected]
*/
#ifndef _TIMER
#define _TIMER
/*===========head file include============*/
#if !defined(__DOS_DEF_)
#include <dos.h>
#endif
#include <math.h>
/*===========macro defined================*/
#define TIMER (0x1c) //dos timer interrupt
/*===========globe variable===============*/
int timer_counter=0;
//be used for save old interrupt function pointer for restore interrupt
void interrupt (*old_interrupt)()=NULL;
/*===========data structure===============*/
/*===========function declare=============*/
void interrupt new_interrupt(); //set this function beto new 0x1c interrupt what call next function
void set_timer(void interrupt (*interrupt_fun)()); //set 0x1c interrupt (look last function)
void kill_timer(); //restore old 0x1c interrupt
void delay_ms(int ms);
/*===========function implement===========*/
void interrupt new_interrupt(){
timer_counter++;
return ;
}
void set_timer(void interrupt (*interrupt_fun)()){
timer_counter=0;
old_interrupt=getvect(TIMER); //get one interrupt vector
if(interrupt_fun==NULL) return ;
disable();
setvect(TIMER,interrupt_fun); //set one interrupt vector
enable();
}
void kill_timer(){
if(old_interrupt==NULL) return ;
disable();
setvect(TIMER,old_interrupt);
enable();
}
void delay_ms(int ms){
int t_timer=timer_counter;
set_timer(new_interrupt);
while(1)
if(ms==(abs(timer_counter-t_timer)*100)){
kill_timer();
return ;
}
}
/*===========END==========================*/
#endif
一個dos下的簡單圖形函數庫
=============0x13h display mode version 1.1 Header
=============CopyRight (C) LiGungcun
=============QQ:66855618
=============E-Mail: [email protected]
--------Compiler is Borland TC++3.0 for DOS
---------The last modification 08/02/2004
*/
#ifndef __V_13__
#define __V_13__
/*===========head file include============*/
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <mem.h>
#include <math.h>
#include <stdarg.h>
#include <process.h>
#include <bios.h>
/*===========macro defined================*/
/*===========globe variable===============*/
unsigned char g_current_color; //setcolor current color for draw
unsigned char g_back_color; //setcolor backgrand color for draw
int g_image_height; //get image from screen height
int g_image_width; //get image from screen width
void far *g_bitmap; //a bit_image pointer
/*===========data structure===============*/
typedef struct {
unsigned char r; //Dos VGA 13 Mode
unsigned char g; //256Color
unsigned char b; //wei cai
} palette_type; //palette
typedef struct{
unsigned long fsize; /*2文件大小4B*/
unsigned long offset; /*10圖象數據在文件中的偏移地址4B*/
unsigned long width,height; /*18,22寬高(像素)4B+4B*/
unsigned int bit; /*28指明每個像素點需要的位數2B*/
unsigned long compres; /*30壓縮標誌0爲不壓1爲256色壓4B*/
unsigned long bsize; /*34圖象數據所佔用的字節數4B*/
}BMP; // Load Bitmap to this struct
/*===========function declare=============*/
void init_graph (void);
void close_graph (void);
void draw_pixel (unsigned x,unsigned y,unsigned char color);
void draw_line (unsigned x1,unsigned y1,unsigned x2,unsigned y2);
void draw_rectangle (unsigned left, unsigned top, unsigned right, unsigned bottom);
void draw_bar (unsigned left, unsigned top, unsigned right, unsigned bottom);
void draw_circle (unsigned x, unsigned y, unsigned r);
void draw_solid_circle (unsigned x, unsigned y, unsigned r);
void clear_device (unsigned left,unsigned top,unsigned right,unsigned bottom);
void set_back_color (unsigned char color);
unsigned char get_back_color (void);
void set_current_color (unsigned char color);
unsigned char get_current_color (void);
void far * get_image (unsigned left, unsigned top, unsigned right, unsigned bottom);
void put_image (unsigned left,unsigned top,void far *bitmap);
int get_max_x (void);
int get_max_y (void);
unsigned get_pixel (unsigned x,unsigned y);
void out_text_xy (unsigned x,unsigned y,const unsigned char *text);
void set_palette (unsigned color_index,palette_type rgb);
palette_type get_palette (unsigned color_index);
int show_bmp (int x,int y,char *path);
/*===========function implement===========*/
void init_graph(void){
union REGS r;
r.x.ax=0x13;
int86(0x10,&r,&r);
g_current_color=0;
g_image_height=0;
g_image_width=0;
g_bitmap=NULL;
}
void close_graph(void){
union REGS r;
r.x.ax=0x03;
int86(0x10,&r,&r);
}
void draw_pixel (unsigned x,unsigned y,unsigned char color){
unsigned char *video_buffer=NULL;
if(x<320&&y<200){
*(video_buffer=MK_FP(0xa000,((y<<8)+(y<<6))+x))=color;
}
else
return;
}
//these algorithm reference my <<digital image>>
void draw_line (unsigned x1,unsigned y1,unsigned x2,unsigned y2){
int dx,dy,index,x_inc,y_inc;
int error=0;
if(x1>319||x2>319) return ;
if(y1>199||y2>199) return ;
dx=x2-x1; dy=y2-y1;
if(dx>=0){
x_inc=1;
}
else{
x_inc=-1;
dx=-dx;
}
if(dy>=0){
y_inc=1;
}
else{
y_inc=-1;
dy=-dy;
}
if(dx>dy){
for(index=0;index<=dx;index++){
draw_pixel(x1,y1,g_current_color);
error+=dy;
if(error>dx){
error-=dx;
y1+=y_inc;
}
x1+=x_inc;
}
}
else{
for(index=0;index<=dy;index++) {
draw_pixel(x1,y1,g_current_color);
error+=dx;
if(error>0){
error-=dy;
x1+=x_inc;
}
y1+=y_inc;
}
}
}
void draw_rectangle (unsigned left, unsigned top, unsigned right, unsigned bottom){
unsigned t;
if(left>319||right>319) return ;
if(top>199||bottom>199) return ;
if(left>right){
t=left; left=right; right=t;
}
if(top>bottom){
t=top; top=bottom; bottom=t;
}
draw_line(left,top,right,top);
draw_line(left,top,left,bottom);
draw_line(left,bottom,right,bottom);
draw_line(right,top,right,bottom);
}
void draw_bar (unsigned left, unsigned top, unsigned right, unsigned bottom){
int i;
unsigned x,y,t;
if(left>319||right>319) return ;
if(top>199||bottom>199) return ;
if(left>right){
t=left; left=right; right=t;
}
if(top>bottom){
t=top; top=bottom; bottom=t;
}
for(y=top;y<=bottom;y++){
/*draw_line(left,y,right,y);*/
for(i=left;i<=right;i++)
draw_pixel(i,y,g_current_color);
}
}
void draw_circle (unsigned x, unsigned y, unsigned r){
int t_x,t_y,i;
float pi_2=6.283;
if(x>319||y>199) return ;
if(r>319) return ;
for(i=1;i<720;i++){
t_x=x+r*cos(pi_2/720*i);
t_y=y+r*sin(pi_2/720*i);
draw_pixel(t_x,t_y,g_current_color);
}
}
void draw_solid_circle(unsigned x, unsigned y, unsigned r){
int i;
if(x>319||y>199) return ;
if(r>319) return ;
for(i=1;i<r;i++)
draw_circle(x,y,i);
}
void clear_device (unsigned left,unsigned top,unsigned right,unsigned bottom){
unsigned char t_color;
t_color=g_current_color;
set_current_color(get_back_color());
draw_bar(left,top,right,bottom);
set_current_color(t_color);
}
void set_back_color (unsigned char color){
unsigned char t_color;
g_back_color=color;
t_color=get_current_color();
set_current_color(color);
draw_bar(0,0,get_max_x(),get_max_y());
set_current_color(t_color);
}
unsigned char get_back_color (void){
return g_back_color;
}
void set_current_color (unsigned char color){
g_current_color=color;
}
unsigned char get_current_color (void){
return g_current_color;
}
void far *get_image (unsigned left, unsigned top, unsigned right, unsigned bottom){
unsigned char *t_video=NULL,*t_bitmap=NULL;
int i; unsigned t;
if(left>319||right>319) return NULL;
if(top>199||bottom>199) return NULL;
if(left>right){
t=left; left=right; right=t;
}
if(top>bottom){
t=top; top=bottom; bottom=t;
}
g_image_height=bottom-top+1; g_image_width=right-left+1;
if((g_bitmap=(unsigned char *)malloc(g_image_height*g_image_width))==NULL)
return NULL;
t_video=MK_FP(0xa000,((top<<8)+(top<<6))+left);
t_bitmap=g_bitmap;
for(i=0;i<g_image_height;i++){
memcpy(t_bitmap,t_video,g_image_width);
t_bitmap+=g_image_width;
t_video+=320;
}
return g_bitmap;
}
void put_image (unsigned left,unsigned top,void far *bitmap){
unsigned char *t_video=NULL,*t_bitmap=NULL;
int i;
if(bitmap==NULL) return ;
if(left>319||top>199) return ;
if(left+g_image_width>321||top+g_image_height>201) return ;
t_video=MK_FP(0xa000,((top<<8)+(top<<6))+left);
t_bitmap=bitmap;
for(i=0;i<g_image_height;i++){
memcpy(t_video,t_bitmap,g_image_width);
t_bitmap+=g_image_width;
t_video+=320;
}
free(bitmap); bitmap=NULL;
g_image_width=0;
g_image_height=0;
}
int get_max_x (void){
return 319;
}
int get_max_y (void){
return 199;
}
unsigned get_pixel (unsigned x,unsigned y){
unsigned char *video_buffer=NULL;
if(x<320){
video_buffer=MK_FP(0xa000,((y<<8)+(y<<6))+x);
return *(video_buffer);
}
else
return 300;
}
/*==========out_text function=============*/
void print_hz(char *zimo,int size,int x,int y){
int i,j,k,n;
if(x<0||x>303||y<0||y>183) return ;
n=(size-1)/8+1;
for(j=0;j<size;j++)
for(i=0;i<n;i++)
for(k=0;k<8;k++)
if(zimo[j*n+i]&(0x80>>k))
draw_pixel(x+i*8+k,y+j,g_current_color);
}
void print_hzk(char *hz,int x,int y,const char *path){
int c1,c2;
FILE *fp=NULL;
char buf[32];
unsigned long offset;
if(x<0||x>303||y<0||y>183) return ;
fp=fopen(path,"rb");
if(fp==NULL){ close_graph(); printf("Can't find file hzk16"); exit(0);}
c1=hz[0]-0xa0; //c1=(c1<<8)>>8;
c2=hz[1]-0xa0; //c2=(c2<<8)>>8;
offset=(94*(c1-1)+(c2-1))*32L;
fseek(fp,offset,0);
fread(buf,32,1,fp);
print_hz(buf,16,x,y);
fclose(fp);
}
void print_ascii(char c,int x,int y){
/*ascii 8*8 字模點陣地址=0xF000:0xFA6E*/
char m[8];
int i,j;
char far *p=(char far*)0xf000fa6e;
if(x<0||x>311||y<0||y>191) return ;
p=p+c*8;
memcpy(m,p,8);
if((x<311)&&(y<191)){
for(i=0;i<8;i++)
for(j=0;j<8;j++){
if(m[i]&(0x80>>j))
draw_pixel(x+j,y+i,g_current_color);
}
}
}
/*==========out_text function END=========*/
void out_text_xy (unsigned x,unsigned y,const unsigned char *text){
int t_x,t_y;
int i;
unsigned char *t_text=NULL;
if(x>311||y>191) return ;
t_x=x; t_y=y; t_text = (unsigned char *) text;
while(*t_text!='