博文
C++ 中使用 goto 增强 break 和 continue(转)(2007-05-27 21:00:00)
摘要:C++ 的 goto 语句在大多数时间是被打入冷宫的,就因为它容易使代码晦涩难读。同时,break 和 continue 又经常在多重循环中黔驴技穷——不能越层控制循环。
相比之下,Java 就兼顾这两种情况,将 goto 彻底禁用,而标签则限制其只能用于循环之前,以此增加 break 和 continue 的功能,使其能越层控制循环 [参阅:《带标签的 break 和 continue (Java)》]
Java 尚能如此,为何不在 C++ 中用标签和 goto 语句模仿 Java 来增强 break 和 continue 的功能呢?
于是照 Java 代码写了一份 C++ 的试验样例,结果第一次试验失败。代码如下:
int main(int argc, char* argv[])
...{
cout << "[begin>" << endl;
continuei:
for (int i = 0; i < 10; i++) ...{
for (int j = 0; j < 5; j++) ...{
if ((i + j) % 5 == 0) ...{
cout <<&nbs......
排序算法比较(2007-05-02 18:14:00)
摘要:排序算法是数据结构学科经典的内容,其中内部排序现有的算法有很多种,究竟各有什么特点呢?本文力图设计实现常用内部排序算法并进行比较。分别为起泡排序,直接插入排序,简单选择排序,快速排序,堆排序,针对关键字的比较次数和移动次数进行测试比较.
问题分析和总体设计
ADT OrderableList{
数据对象:D={ai| ai∈IntegerSet,i=1,2,…,n,n≥0}
数据关系:R1={〈ai-1,ai〉|ai-1, ai∈D, i=1,2,…,n}
基本操作:
InitList(n)
操作结果:构造一个长度为n,元素值依次为1,2,…,n的有序表。
Randomizel(d,isInverseOrser)
操作结果:随机打乱
BubbleSort( )
操作结果:进行起泡排序
InserSort( )
操作结果:进行插入排序
SelectSort( )
操作结果:进行选择排序
QuickSort( )
操作结果:进行快速排序
HeapSort( )
操作结果:进行堆排序
ListTraverse(visit( ))
操作结果:依次对L种的每个元素调用函数visit( )
}ADT OrderableList
待排序表的元素的关键字为整数.用正序,逆序和不同乱序程度的不同数据做测试比较,
对关键字的比较次数和移动次数(关键字交换计为3次移动)进行测试比较.
要求显示提示信息,用户由键盘输入待排序表的表长(100-1000)和不同测试数据的组数(8-18).每次测试完毕,要求列表现是比较结果.
要求对结果进行分析.
详细设计
1、起泡排序
算法:核心思想是扫描数据清单,寻找出现乱序的两个相邻的项目。当找到这两个项目后,交换项目的位置然后继续扫描。重复上面的操作直到所有的项目都按顺序排好
bubblesort(struct rec r[],int n)
{
int i,j;
struct rec w;
unsigned long int compare=0,move=0;
for(i=1;i<=n-1;i++)
for(j=n;j>=i+1;j--)
{......
void心得(2007-04-12 16:24:00)
摘要:void指针和其它类型指针一样,可以表示一个地址。但不同的是,一个void指针指向的数据可以是各种类型,其它指针指向的数据是固定类型。
int *p; 则p可以指向一个int。
void *p; 则p可以指向各种数据类型,那么在使用*p时,就不知道到底是什么类型了,无法使用cout输出。
类似的,也不能写++p或者p+=2之类的代码,因为p所指的类型不确定,其大小也就不确定。......
c++心得(2007-04-01 15:38:00)
摘要:
MSDN里面有一些专题值得读一下,至少知道MFC的目的和一些方法或者手段。随便乱写一些,如果以后发现还有价值的话就整理。
1)MFC是对平台SDK的一个大封装。
学了C++,还不知道C++能干嘛,不知道就算能干这些,又有什么用,甚至不知道为什么要设计类,为什么要封装。
WINDOWS里的资源是用句柄表示的,句柄这个词不知道是哪个中国IT菜手翻译的,handle干嘛要这么翻译?它的意义很明显嘛,处理,为什么要处理?有人说,它是微软要隐含内部实现,因为它是商业软件嘛,我觉得不是,这不是根本原因,它原本的目的还是为了代码的向后兼容和可复用性。比如最重要一种资源,文件,它是和具体设备相关的,但文件操作只对一个文件的HANDLE进行处理,就是把它的定义和处理分开,C语言里的FILE也是一样的道理。各种各样的资源统一处理,在系统里统一表示,这样系统就会有条不紊地工作。也算是一个小的封装吧,具体实现和外部代码的分开,封装。于是有了SDK编程。
MFC封装在外面,更大的封装,它是为了让程序员把搭建一个复杂的WIN32程序,从设计那些复杂的实现中解放出来,把开发重点放在软件的数据结构和算法上。由于SDK封装得低,所以可以认为那些handle本身就是资源本身,可以这样认为。再在这之上进行面向类的封装,就是MFC。
有人说懂得了继承,才真正懂得了面向对象,或者C++。C++的目标或许也是这样吧,虽然语言本身没告诉我们它的目的是什么,做为了个成熟的类库,比如MFC,我们不仅仅是简单的利用它的一些功能调用,比如用CCommonDialog,而关键是选择合适的类继承下来,设计自己的子类,来实现整个软件的功能。
在面对各种各样的MFC中的类,要记住一点,类生成的对象,本身并不代表资源本身,比如CEdit并不是EditBox,它们之间可以有联系,但这个联系可以人为的剪断,对象只是一个从操作到资源的一个纽带。这也是为什么它有构造函数,却要用::Create()创建的原因。
2)弄清消息分发的过程。
消息的机制是为了让WINDOWS变迟顿,让它‘慢’下来,只有你‘叫’它做事它才做,由主动工作变为被动工作。有时候发送消息本身也可以看成消息处理本身。MFC对消息的处理封装得可就复杂了,不是非要弄得非常清楚才行,要知道消息被MFC丢来丢去的先后顺序,比如一个按钮的COMMAND响应可以给......
c细节啊(2007-03-31 21:58:00)
摘要:** 非常好的程序:(考虑程序的可移植性)
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
void PRINTBIT(int);
/* 打印 n 的每个比特位 */
void PRINTBIT(int n){
/* 这里开始我定义为 int 型,结果如下:
2 : 0000 0000 0000 0000 0000 0000 0000 0011
4 : 0000 0000 0000 0000 0000 0000 0000 0111
2 ^ 4 : 0000 0000 0000 0000 0000 0000 0000 0111
2 & 4 : 0000 0000 0000 0000 0000 0000 0000 0000
2 | 4 : 0000 0000 0000 0000 0000 0000 0000 0111
最后改为unsigned int 则正确,仔细想了一下
原因:
check = 1;
check <<= (i - 1);
这样如果 check 为 int 则最高为永远为 1,且会
向右移动,移完后
check=bit(1111 1111 1111 1111 1111 1111 1111 1111);
*/
unsigned int j;
unsigned int i = sizeof(int) * CHAR_BIT;
unsigned int check = 1;
check <<= (i - 1);
for(j = 1; j <= i; j ++){
putchar(((check & n) ? '1' : '0'));
&n......
函数指针(2007-03-31 21:24:00)
摘要:typedef void (*FunType)(int ); //这样只是定义一个函数指针类型
FunType FunP; //然后用FunType类型来申明全局FunP变量
int main(int argc, char* argv[])
{
//FunType FunP; //函数指针变量当然也是可以是局部的 ,那就请在这里申明了。
MyFun(10);
FunP=&MyFun;
(*FunP)(20);
return 0;
}
void MyFun(int x)
{
printf(“%d\n”,x);
}
看黑体部分:
首先,在void (*FunType)(int ); 前加了一个typedef 。这样只是定义一个名为FunType函数指针类型,而不是一个FunType变量。
然后,FunType FunP; 这句就如PINT px;一样地申明一个FunP变量。
其它相同。整个程序完成了相同的事。
这样做法的好处是:
有了FunType类型后,我们就可以同样地、很方便地用FunType类型来申明......
时间(2007-03-30 20:49:00)
摘要:摘要:
本文从介绍基础概念入手,探讨了在C/C++中对日期和时间操作所用到的数据结构和函数,并对计时、时间的获取、时间的计算和显示格式等方面进行了阐述。本文还通过大量的实例向你展示了time.h头文件中声明的各种函数和数据结构的详细使用方法。
关键字:UTC(世界标准时间),Calendar Time(日历时间),epoch(时间点),clock tick(时钟计时单元)
1.概念
在C/C++中,对字符串的操作有很多值得注意的问题,同样,C/C++对时间的操作也有许多值得大家注意的地方。最近,在技术群中有很多网友也多次问到过C++语言中对时间的操作、获取和显示等等的问题。下面,在这篇文章中,笔者将主要介绍在C/C++中时间和日期的使用方法.
通过学习许多C/C++库,你可以有很多操作、使用时间的方法。但在这之前你需要了解一些“时间”和“日期”的概念,主要有以下几个:
Coordinated Universal Time(UTC):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间(Greenwich Mean Time,GMT)。比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5。
Calendar Time:日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。这个标准时间点对不同的编译器来说会有所不同,但对一个编译系统来说,这个标准时间点是不变的,该编译系统中的时间对应的日历时间都通过该标准时间点来衡量,所以可以说日历时间是“相对时间”,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。
epoch:时间点。时间点在标准C/C++中是一个整数,它用此时的时间和标准时间点相差的秒数(即日历时间)来表示。
clock tick:时钟计时单元(而不把它叫做时钟滴答次数),一个时钟计时单元的时间长短是由CPU控制的。一个clock tick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位。
我们可以使用ANSI标准库中的time.h头文件。这个头文件中定义的时间和日期所使用的方法,无论是在结构定义,还是命名,都具有明显的C语言风格。......
读文件一点见解(2007-03-29 15:24:00)
摘要:做开发的经常碰到文件的操作,特别是文件的“读”操作。在java中,读文件有很多种方法,有FileReader、BufferReader等,当然,各种方法的效率是不一样的,FileReader经BufferReader包装后效率明显提高,在个别时候,我们可以用java.nio包进行文件操作,如下:
private static String fileReader(File fileName) {
String fileContent = null;
FileInputStream fis = null;
FileChannel fc = null;
try {
fis = new FileInputStream(fileName);
// get a file channel
fc = fis.getChannel();
&nbs......
招聘网站(2007-03-29 14:50:00)
摘要:chinahr.com
从1999年以来我所有的工作都是通过这个网站找得,国内知名企业大多都使用此媒体,在北京的朋友一般不会没有收获,今年春节后一周内,通过此网站,居然有7家企业邀请我去面试。
zhaopin.com
如果你能被这家网站上的企业相中,那说明你一定是很有实力得,此网站集中了很多知名外企,当然如果你相被猎中的话,一定要具备英文功底,曾经两家IT世界知名公司面试,可以被E文所限,失之交臂。
www.jobcn.com,www.cjol.com
在广东的朋友可以集中在这两个网站找工作,以前在老家的时候,就是接到了这两个网站上的公司的机会,可惜来了北京。
还有家著名的网络招聘媒体我没说,我想大家都知道,我在这家网站发布过很多次简历及应聘信息,但从无回音,以至我很是怀疑它的数据的真实性,NASDAQ又怎么了,后来听一位业内朋友说,此网站主要以HR外包业务为主,网站只是个摆设。
www.gongzuo123.com
如果您接到应聘通知的时候,一定要到这家网站转转,看看别人怎么评价这家企业得,或者直接从同事录里给同事发MAIL问问内部情况,
往往有意向不到的收获。此网站汇集了15W家网络上招聘的企业,包括各行业。......
堆、栈及静态数据区详解 (转)(2007-03-25 18:10:00)
摘要:
堆、栈及静态数据区详解
五大内存分区
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)
明确区分堆与栈
在bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。
首先,我们举一个例子:
void f() { int* p=new int[5]; }
这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下:
00401028 push  ......