博文

写给想当程序员的朋友(2005-12-06 11:47:00)

摘要:   软件以程序员为本(《程序员》)  谨以此文献给所有想当程序员的朋友  (一) 文章由来及个人经历  我是一名计算机专业的本科毕业生,毕业已经1年多了。毕业后从事的是软件编程工作,经常有其他专业的朋友想从事软件编程工作,向我请教如何,因为我自觉涉世不深,不敢信口开河,无奈朋友信任,我不得不郑重考虑一下这个问题了,来帮助朋友选择和回报朋友的信任。  这也就是此文的由来。  还是先谈谈我个人的经历吧。(是不是有点俗套,但我觉得了解我的经历,有助于理解我话的含义;我一向认为不了解古龙的生活经历的,不会真正读懂古龙的作品和古龙笔下的英雄的)我本科就读于南方一所著名的高校(因为自己的不成气,愧谈母校名谓),学的就是计算机专业。上本科时,几乎没有认真的听完一门专业课程,上课看报纸睡大觉,下课看录像看小说看球赛,临考抱佛脚,每次考试和课程设计都是蒙混过关。(于之相对是,我选修的工商管理和经济贸易方面的课到是听得不亦乐乎,考的分数颇高,也许这才是我的真正兴趣所在。)  总而言之,大学是混过来了,对专业的理解和掌握程度,应该没有达到毕业要求的合格水平。(也很后悔,但是有什么用呢,当时不知道珍惜;如果上天再给我一次机会的话,我一定会抓住,多看点美国大片,少看点港片;现在,重回校园是我的一大理想)但是大学的学习使我有了一个简单的知识框架(总算学费没白交),我对一个朋友这样形容过我的这个知识框架,“它不是钢筋铸的,是稻草扎的”,哈哈哈,不要笑,真的,我敢说很多本科毕业的朋友的本专业的知识框架也只不过是“稻草扎的”。直到现在,我一直觉得自己的基础知识还是很薄弱,一直想抓点时间,把基础书本好好的温习一下。(此项任务正在计划和实施中)  毕业后,分配到某研究所工作。当领导让我选择自己以后的工作方向时,我毫不犹豫的选择了软件(也不知道到底是对还是错,但我决不后悔)。此研究所主要是以硬件为核心搞通信控制设备的研发生产;软件是辅助,所以也不受什么重视,很多搞软件的人都跳槽走了,留下来的大都是一些已经废掉和行将废掉的“伪/萎”程序员(名副其实的“软件人员”)。在这里感觉不到什么高紧张和高技术程度的研究和开发;软件开发的技术含量极低,以至于大部分人只有半年的学习和开发经验,以后都是这些知识和经验的重复......

阅读全文(15944) | 评论:1

Visual C++模拟对话框消息处理机制的分析(2005-12-05 16:00:00)

摘要:    摘要:消息驱动机制是Windows操作系统的根本,模态对话框消息处理又是不同于一般消息处理的特殊形式。通过分析这种消息机制的原理,可用来处理类似的程序设计要求。  在Windows操作系统中,面向用户的GUI基本上可分为对话框形式和文档/视图两种表现形式。对话框的显示方式又可分为模态对话框和非模态对话框,以适应不同的用户交互需求。由于对话框和文档/视图框架结构各有特色,能不能将文档/视图框架结构当作一对话框来使用,或在对话框中实现文档/视图框架结构内的特色功能呢,答案是肯定的。  下面,从Windows 操作系统消息驱动机制开始,进而探讨模态对话框实现过程的消息封装、传递和处理机制,最后以模态的形式显示应用到文档/视图框架结构中的实例作为对所讲内容的验证和实践。   一、Windows消息机制   Windows是一种面向对象的体系结构,Windows环境和应用程序都是通过消息来交互的。Windows应用程序开始执行后,Windows为该程序创建一个"消息队列(message queue)",用以存放邮寄给该程序可能创建的各种不同窗口的消息。消息队列中消息的结构(MSG)为: typedef struct tagMSG{  HWND hwnd;  UINT message;  WPARAM wParam;  LPARAM lParam;  DWORD time;  POINT pt; }MSG;    其中第一个成员变量是用来标识接收消息的窗口句柄;第二个参数便是消息标识号,如WM_PAINT;第三个和第四个参数的具体意义同message值有关,均为消息参数。前四个参数是非常重要和经常用到的,至于后两个参数则分别表示邮寄消息的时间和光标位置(屏幕坐标)。把消息传送到应用程序有两种方法:一种是由系统将消息"邮寄(post)"到应用程序的"消息队列"这是"进队消息"Win32 API有对应的函数: PostMessage(),此函数不等待该消息处理完就返回;而另一种则是由系统在直接调用窗口函数时将消息"发送(send)"给应用程序的窗口函数,属于"不进队消息"对应的函数是SendMessage()其必须等待该消息处理完后方可返回。   对于每一个正在执行的Windows应用程序,系统为其建立一个"消息队列",即应用程序......

阅读全文(4882) | 评论:0

WinPcap编程渐进教程(2005-12-04 14:05:00)

摘要:    原文出处:http://winpcap.polito.it/docs/man/html/index.html 作者: Loris Degioanni (degioanni@polito.it), NetGroup, Politecnico di Torino http://winpcap.polito.it 译者: 记忆碎片 (val_cong@htomail.com) http://www.s8s8.net 概述: 这篇教程将会指引读者逐步了解WinPcap编程, 从简单的基础函数(获取网络接口列表, 捕捉数据包)到更高级的内容(处理发送队列, 网络流量统计). 教程中包括一些代码片断, 以及一些简单但完整的例子, 读者可以参考这些例子更好的理解教程的内容. 这些例子全部用C语言写成, 所以基本的C语言编程知识是必要. 同时, 因为这篇教程的内容是与底层网络紧密相连的, 所以笔者假设读者已经具备有关网络和协议的相关知识. 译者的话: WinPcap是一套免费的, 基于Windows的网络接口API, 它在底层网络操作方面对程序员很有帮助. 这篇文档翻译自 "WinPcap Documentation 3.0" 中的 "WinPcap tutorial: a step by step guide to program WinPcap" 一部分. 这篇教程对初学者的帮助很大, 尤其是简短清晰的例子, 但这篇教程只是整个文档的一小部分, 我认为你仍然需要参考文档的其它部分来了解各种结构等信息. 教程中注有前缀 "Y-" 的部分是译者为了让读者更明白作者的意思添加的, 原文中没有. 1. 获取网络接口列表 通常, 一个基于WinPcap的应用程序所要做的第一件事, 就是获得适合的网络接口的列表. Libpcap中的pcap_findalldevs()函数就是干这活的: 这个函数然回一个pcap_if结构的列表, 每个元素都记录了一个接口的信息. 其中, name和description以人类可以阅读的形式, 记录了设备的信息. 下面的源代码输出可用的网络接口的列表, 并且在没有找到任何借口的情况下输出错误信息: 代码  #i nclude "pcap.h" main() { pcap_if_t *alldevs;......

阅读全文(17857) | 评论:1

Visual C++6.0 API函数操作技巧集(2005-12-04 13:50:00)

摘要:我们在编制应用软件的过程中,常常需要对光标和鼠标操作,本人在文中介绍了Windows系统中有关实现对鼠标和光标进行操作的API函数,并给出了在Visual C6.0++中利用所介绍的API函数实现对鼠标和光标的操作的代码。  一、隐藏和显示光标  函数: int ShowCursor ( BOOL bShow );   参数 bshow,为布尔型,bShow的值为False时隐藏光标,为True时显示光标;该函数的返回值为整型,为鼠标隐藏或显示的指数器;返回值大于等于0时显示光标,否则隐藏鼠标;如果安装了鼠标初值为0。  实例:  在基于对话框的应用程序中放置两个Button,名称分别为HideCursor和ShowCursor;再放置一个CStatic控件,名称为Label1,用于显示光标计数器。  源程序为: // 使光标计数器的值减一,如果小于零,隐藏光标void CMyTestDlg::OnHideCursor(){int i;i=ShowCursor(FALSE);Cstring string;string.Format(_T("%d" ),i);Label1.SetWindowText(&string);}// 使光标计数器的值加一,如果大于等于零,显示光标void CMyTestDlg::OnShowCursor(){int j;j=ShowCursor(TRUE);Cstring string;string.Format(_T("%d" ),j);Label1.SetWindowText(&string);}   运行程序,连续单击ShowCursor按钮,你会见到计数器从1(光标显示时初值为0)开始不断加1;再连续单击HideCursor按钮,又会见到计数器不断减1,当计数器为-1时开始隐藏光标。  二、交换鼠标左右键和恢复  函数: BOOL SwapMouseButton ( BOOL fSwap );   参数 fSwap,为布尔型,TRUE表示交换鼠标左右键,FALSE表示恢复系统默认左右手习惯;返回值亦为布尔型,交换后,返回值TRUE,恢复正常值为FALSE。  实例:  在应用程序中放置两个Button,名称分别为ReverseMouse和RestoreMouse。  源程序为: //交换鼠标左右键void CMyTes......

阅读全文(5953) | 评论:0

VC实现波形不闪烁动态绘图(2005-12-03 19:58:00)

摘要:      在信号处理中,通常需要把采集信号的实时波形显示出来。 如果直接在屏幕上动态绘图的话,会出现闪烁现象,为了克服这个问题,本文采用的就是先在内存绘图,然后再拷贝到屏幕,从而实现动态绘图而不闪烁。详细介绍如下: 2.1 首先在头文件中定义以下私有变量,并在对话框资源中放置一个picture控件 private: CDC *pDC; //屏幕绘图设备 CDC memDC; //内存绘图设备 int m_High; //绘图起点 int m_Low; //绘图终点 int m_lCount[1024]; //数据存储数组 int m_now; //记录波形当前点 2.2 在实现文件中初始化变量,并设置定时器 BOOL CDrawTest::OnInitDialog()? { CDialog::OnInitDialog(); // TODO: Add extra initialization here m_Low = 0; m_High = 1024; m_now =0; SetTimer(1,100,NULL); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } 2.3 在定时器里创建内存绘图设备,并调用绘图函数在内存设备中绘图,绘图完毕后把内存设备中图拷贝到屏幕 void CDrawTest::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default CRect rect; // 获取绘制坐标的文本框 CWnd* pWnd = GetDlgItem(IDC_COORD);                //获得对话框上的picture的窗口句柄 pWnd->GetClientRect(&rect); // 指针 pDC = pWnd->Ge......

阅读全文(4031) | 评论:0

Raw Socket(原始套接字)实现Sniffer(嗅探)(2005-12-03 19:57:00)

摘要:     一. 摘要   Raw Socket: 原始套接字   可以用它来发送和接收 IP 层以上的原始数据包, 如 ICMP, TCP, UDP...     int sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);   这样我们就创建了一个 Raw Socket   Sniffer: 嗅探器   关于嗅探器的原理我想大多数人可能都知道   1. 把网卡置于混杂模式;   2. 捕获数据包;   3. 分析数据包.   但具体的实现知道的人恐怕就不是那么多了. 好, 现在让我们用 Raw Socket 的做一个自已的 Sniffer. 二. 把网卡置于混杂模式   在正常的情况下,一个网络接口应该只响应两种数 据帧:   一种是与自己硬件地址相匹配的数据帧   一种是发向所有机器的广播数据帧   如果要网卡接收所有通过它的数据, 而不管是不是 发给它的, 那么必须把网卡置于混杂模式. 也就是说 让它的思维混乱, 不按正常的方式工作. 用 Raw Socket 实现代码如下:     setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag); //设置 IP 头操作选 项     bind(sockRaw, (PSOCKADDR)&addrLocal, sizeof(addrLocal); //把 sockRaw 绑定到本地网卡 上     ioctlsocket(sockRaw, SIO_RCVALL, &dwValue);       //让 sockRaw 接受所有的数据   flag 标志是用来设置 IP 头操作的, 也就是说要 亲自处理 IP 头: bool flag = ture;   addrL......

阅读全文(5143) | 评论:0

ACM代码总结(续)(2005-10-06 19:41:00)

摘要:20、大数运算处理基本函数#include#includeusing namespace std;const int N = 1100;struct big_num{    int ele[N];    int front;};typedef struct big_num bigNum;void print_bigNum(const bigNum& num){    for(int i = num.front; i < N; ++i)        printf("%d", num.ele[i]);}void println_bigNum(const bigNum& num){    for(int i = num.front; i < N; ++i)        printf("%d", num.ele[i]);    printf("\n");}bigNum multi_bigNum(const bigNum& num1, const bigNum& num2){    bigNum temp;    bigNum num3;    int i, j, carry;    int temp_int;    num3.front = num1.front + num2.front - N;    for(i = num3.front; i < N; ++i)        num3.ele[i] = 0;   &nb......

阅读全文(25845) | 评论:6

ACM代码总结(2005-10-06 19:38:00)

摘要:    经过了一段时间的努力,我再Pku上也算是有了一个阶段性的总结拉,下面是我就这段时间搞ACM来的一些代码的总结,具体的一些题目类型的总结看本Blog的相关文章。 huicpc26 ACM_PKU 代码总结 1、DP(动态规划)/*1080-HumanGeneFunctions.cpp*/观察题目给出的一个最优解: AGTGATG -GTTA-G 将其从某一处切开,如果左边部分的分值不是最大,那么将其进行调整,使其分值变大,则整个解分值变大,与已知的最优矛盾。所以左边部分的分值必是最大。同理,右边也是。可见满足最优子结构的性质。考虑使用DP: 设两个DNA序列分别为s1,s2,长度分别为len1,len2,score为分值表。f[i,j]表示子串s1[1..i]和s2[1..j]的分值。考虑一个f[i,j],我们有:   1.s1取第i个字母,s2取“-”:f[i-1,j] + score[s1[i],''-'']   2.s1取“-”,s2取第j个字母:f[i,j-1] + score[''-'',s2[j]]   3.s1取第i个字母,s2取第j个字母:f[i-1,j-1] + score[s1[i],s2[j]]   即f[i,j] = max(f[i-1,j] + score[s1[i],''-''], f[i,j-1] + score[''-'',s2[j]], f[i-1,j-1] + score[s1[i],s2[j]]); 然后考虑边界条件,这道题为i或j为0的情况。 当i=j=0时,即为f[0,0],这是在计算f[1,1]时用到的,根据f[1,1] = f[0,0] + score[s1[i], s2[j]],明显有f[0,0] = 0。 当i=0时,即为f[0,1..len2],有了f[0,0],可以用f[0,j] = f[0,j-1] + table[''-'',s2[j]]来计算。 当j=0时,即为f[1..len1,0],有了f[0,0],可以用f[i,0] = f[i-1,0] + table[s1[i],''-'']来计算。 至于计算顺序,只要保证计算f[i,j]的时候,使用到的f[i-1,j],f[i,j-1],f[i......

阅读全文(21214) | 评论:2

zju-1489-2^x mod n = 1(2005-10-06 19:30:00)

摘要: #include<stdio.h> int modular(int a,long b,int n) {     long d,t ;     d=1 ;     t=a ;     while(b>0)     {         if(b%2==1)         d=d*t%n ;         b=b/2 ;         t=t*t%n ;     }     if(d==1)     return 1 ;     else return 0 ; } int main() {     long n ;     long i ;     while(scanf("%ld",&n)!=EOF)     {         if((n%2==0)||(n==1))         {             printf("2^? mod %ld = 1\n",n);  &nb......

阅读全文(17119) | 评论:0

比赛经验总结(2005-10-06 19:29:00)

摘要:摘录: 在天大,偶参加的比赛可以算是最多的了,说说比赛经验。 可能现在说早了点,需要大家在正式比赛之前再看一遍。 推荐此篇文章打印,与模板放在一起。 1. 比赛中评测会有些慢,偶尔还会碰到隔10分钟以上才返回结果的情况,这段时间不能等结果,必须开工其他题,如果WA,两道题同时做。交完每道题都要先打印。 2. 比赛时发的饭不是让你当时就吃的,那是给你赛后吃的。基本上比赛中前几名的队都没人吃,除非领先很多。 3. 很多选手,尤其是第一次参加比赛的,到一个新环境,全当旅游了,参观的参观,找同学的找同学,玩玩乐乐就把正事抛到脑后了,结果比赛自然没什么好成绩,这样的例子太多了。所以到参赛地后要时刻不忘自己是来比赛的,好好休息、备战。 4. 参赛前一天要睡10个小时以上,非常有助于保持比赛中的精力,很多时候比赛到3个多小时队员就没劲了就是这个原因。前一天晚饭与当天早饭要吃好,理由同上,要知道下顿饭得下午3点赛后才能吃。 5. 到新环境,时刻注意远离疾病,感冒肠炎病不大,却是成绩的天敌。 6. 英语不好,看不懂的,要勤查词典,懒一次就少一道题,远离奖牌。 7. 可以紧张,杜绝慌张,慌张是出题的敌人,任何时候,如果发现自己或者队友出现慌张的情况,提醒深呼吸。 8. 照着纸敲代码和sample数据时不要敲错,特别注意文字信息。 9. 第一道简单题交给队中最稳的人做,万一遇到麻烦也不要慌,如果有很多队都出了就更不必着急了,它必定是简单题,必定是可以很快做出来的,晚几分钟也比罚掉20分好。另外注意不要PE。 10. 最后一小时是出题高峰,谁松懈,谁落后。最后一小时出一道是正常,出两道更好。 以上各条均有出处,每条都包含着以往教训,每条都可能浪费掉你一年的努力,不可小视。 以下各条有些来自于其他学校,有些是总结: 11. 无论是否有人通过,所有题必须全读过,最好每道题都有两人以上读过,尽量杜绝讲题现象。要完全弄清题意,正确的判断出题目的难易,不要想当然。 12. 虽然讨论有助于出题,但是以往每赛区第一名基本都是各自为战,但是互相了解,觉得一道题适合其他人做就转手。 13. 保持头脑灵活,在正常方法不行时想想歪门邪道,比如换种不常见的特殊的数据结构,加预处理,限时搜索等。效率是第一位的,如果觉得DP麻烦就用记忆化搜索,总之考虑清楚后就要在最短时间出题......

阅读全文(16282) | 评论:1