C语言已死? 这个论题成为优快云博客们的热点.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: hoya-lee@sohu.com
*/
#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: hoya-lee@sohu.com
--------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 != '