博文
C++ 历史纪实 [转] (2007-05-11 21:09:00)
摘要:
C++ 历史纪实
语言的发展是一个逐步递进的过程,C++ 是直接从 C 语言发展过来的,而 C 语言是从 B 语言发展过来的,B 语言是 BCPL 的一个解释性后代,BCPL 是 Basic CPL。其中最有趣的是 CPL 中 C 的由来,由于当时这个语言是剑桥大学和伦敦大学合作开发的,在伦敦的人员加入之前,C 表示剑桥,伦敦人员加入之后,C 表示 Combined 组合。还有一种非正式的说法,C 表示 Christopher,因为 Christopher 是 CPL 背后的主要动力。
最初导致C++诞生的原因是在Bjarne博士等人试图去分析UNIX的内核的时候,这项工作开始于1979年4月,当时由于没有合适的工具能够有效的分析由于内核分布而造成的网络流量,以及怎样将内核模块化。同年10月,Bjarne博士完成了一个可以运行的预处理程序,称之为Cpre,它为C加上了类似Simula的类机制。在这个过程中,Bjarne博士开始思考是不是要开发一种新的语言,当时贝尔实验室对这个想法很感兴趣,就让Bjarne博士等人组成一个开发小组,专门进行研究。
当时不是叫做C++,而是C with class,这是把它当作一种C语言的有效扩充。由于当时C语言在编程界居于老大的地位,要想发展一种新的语言,最强大的竞争对手就是C语言,所以当时有两个问题最受关注:C++要在运行时间、代码紧凑性和数据紧凑性方面能够与C语言相媲美,但是还要尽量避免在语言应用领域的限制。在这种情况下,一个很自然的想法就是让C++从C语言继承过来,但是我们的Bjarne博士更具有先见之明,他为了避免受到C语言的局限性,参考了很多的语言,例如:从Simula继承了类的概念,从Algol68继承了运算符重载、引用以及在任何地方声明变量的能力,从BCPL获得了//注释,从Ada得到了模板、名字空间,从Ada、Clu和ML取来了异常。
下面让我们来一起看一下C++历史上的主要事件:
1983年8月, 第一个C++实现投入使用(所以我喜欢说1983年C++开了天界)
 ......
gcc 简介(2007-05-07 19:35:00)
摘要:gcc 简介
本节学习GNU推出的Linux系统下C编译器----gcc,主要介绍这种编译器的基本原理和使用方法,以及编译过程中所产生的错误的原因及对策。
gcc简介
Linux系统下的gcc(GNU C Compiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。
gcc编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件。在Linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。而gcc则通过后缀来区别输入文件的类别,下面我们来介绍gcc所遵循的部分约定规则。
.c为后缀的文件,C语言源代码文件;
.a为后缀的文件,是由目标文件构成的档案库文件;
.C,.cc或.cxx 为后缀的文件,是C++源代码文件;
.h为后缀的文件,是程序所包含的头文件;
.i 为后缀的文件,是已经预处理过的C源代码文件;
.ii为后缀的文件,是已经预处理过的C++源代码文件;
.m为后缀的文件,是Objective-C源代码文件;
.o为后缀的文件,是编译后的目标文件;
.s为后缀的文件,是汇编语言源代码文件;
.S为后缀的文件,是经过预编译的汇编语言源代码文件。
gcc的执行过程
虽然我们称gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。
命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇......
标准模板库介绍(2007-05-07 19:19:00)
摘要:标准模板库介绍
标准模板库,也叫 STL,是一个 C++ 容器类库,算法和迭代器。他提供许多基本算法,数据结构。STL 是一个通用库,即可以充份定制:几乎所有的 STL 组件都是模板。在你使用 STL 前,你必须了解模板的工作情况。
容器和算法
和许多类库一样,STL 包含容器类 - 可以包含其他对象的类。STL 包含向量类,链表类,双向队列类,集合类,图类,等等。他们中的每个类都是模板,能包含各种类型的对象。例如,你可以用 vector<int> ,就象常规的 C 语言中的数组,除了 vector 不要你象数组那样考虑到动态内存分配的问题。
vector<int> v(3); // 定义一个有三个元素的向量类
v[0] = 7;
v[1] = v[0] + 3;
v[2] = v[0] + v[1]; // v[0] == 7, v[1] == 10, v[2] == 17
STL 还包含了大量的算法。他们巧妙地处理储存在容器中的数据。你能够颠倒 vector 中的元素,只是简单使用 reverse 算法。
reverse(v.begin(), v.end()); // v[0] == 17, v[1] == 10, v[2] == 7
在调用 reverse 的时候有两点要注意。首先,他是个全局函数,而不是成员函数。其次,他有两个参数,而不是一个:他操作一定范围的元素而不是操作容器。 在这个例子中他正好是对整个容器 V 操作。
以上两点的原因是相同的:reverse 和其他 STL 算法一样,他们是通用的,也就是说, reverse 不仅可以用来颠倒向量的元素,也可以颠倒链表中元素的顺序。甚至可以对数组操作。下面的程序是合法的。
double A[6] = { 1.2, 1.3, 1.4, 1.5, 1.6, 1.7 };
reverse(A, A + 6);
for (int i = 0; i < 6; ++i)
cout << "A[" << i << "] = " << A[i];
这个例子也用到......
C语言之C语言的底层操作(2007-05-07 17:13:00)
摘要:C语言之C语言的底层操作
作者:未知 来源:不详 编辑:
概述
C语言的内存模型基本上对应了现在von Neumann(冯·诺伊曼)计算机的实际存储模型,很好的达到了对机器的映射,这是C/C++适合做底层开发的主要原因,另外,C语言适合做底层开发还有另外一个原因,那就是C语言对底层操作做了很多的的支持,提供了很多比较底层的功能。
下面结合问题分别进行阐述。
问题:移位操作
在运用移位操作符时,有两个问题必须要清楚:
(1)、在右移操作中,腾空位是填 0 还是符号位;
(2)、什么数可以作移位的位数。
答案与分析:
">>"和"<<"是指将变量中的每一位向右或向左移动, 其通常形式为:
右移: 变量名>>移位的位数
左移: 变量名<<移位的位数
经过移位后, 一端的位被"挤掉",而另一端空出的位以0 填补,在C语言中的移位不是循环移动的。
(1) 第一个问题的答案很简单,但要根据不同的情况而定。如果被移位的是无符号数,则填 0 。如果是有符号数,那么可能填 0 或符号位。如果你想解决右移操作中腾空位的填充问题,就把变量声明为无符号型,这样腾空位会被置 0。
(2) 第二个问题的答案也很简单:如果移动 n 位,那么移位的位数要不小于 0 ,并且一定要小于 n 。这样就不会在一次操作中把所有数据都移走。
比如,如果整型数据占 32 位,n 是一整型数据,则 n << 31 和 n << 0 都合法,而 n << 32 和 n << -1 都不合法。
注意即使腾空位填符号位,有符号整数的右移也不相当与除以 。为了证明这一点,我们可以想一下 -1 >> 1 不可能为 0 。
问题:位段结构
struct RPR_ATD_TLV_HEADER
{
ULONG res1:6;
ULONG type:10;
ULONG res1:6;
ULONG length:10;
};
位段结构是一种特殊的结构, ......
在中国搞技术只能混碗饭吃(大话IT)(2007-05-06 21:49:00)
摘要:在中国搞技术只能混碗饭吃,没有太大希望,原因如下:
1、中国的文化传统决定的
在中国,技术以及技术人员缺乏社会地位,具有悠久的历史传统,自古就被斥为“奇技淫巧”,工匠(技术人员)在古代的地位非常低下; 而欧洲从几个世纪以前就非常重视科技了,各国都成立了皇家科学院,很多科学家拥有爵位,地位非常高。
2、中国是个官本位的社会
这导致了“唯官正确”的怪象,很多事情,当官的并不懂,但是他发表几句狗p不通的指示,人人都点头称是。我们在做项目的过程中这种事情屡见不鲜,领导的话不管对错,都跟圣旨一样,没人敢去怀疑和辩驳,其实也不是大家都傻到不明是非,而是辩驳只会给自己带来麻烦。
但是如果某个技术人员发表一番见解,则会遭来诸多诘难,原因不是你说错了,而是因为你没权力,人家不怕你,每个人都敢辩驳你,不管他的观点多么荒谬。
在这样一种氛围下,试问还有多少人有兴趣继续搞技术。
3、中国几乎有无限的劳力供应
在几大生产力要素中:土地、资本、劳力(在中国还要加上权力),资本最值钱(在中国也许是权力),而劳力最不值钱,原因在于中国几乎拥有无限的劳力供应,供大于求,价格当然下跌(也包括劳力的地位);而资本是最紧缺的,供不应求,当然价格上涨(也包括资本家的地位)。
当然有人会说高端技术人才并不多,甚至极度紧缺,这点我承认,但是我们当中(来此论坛的)有几个是紧缺的高端技术人才呢?99.99%的不都是普通技术人员嘛。
4、缺乏支持技术创新的体制,缺乏良好的知识产权保护环境
没有上述二者,请问还有多少技术人员有无穷的热忱投身于技术创新和发明创造?
5、企业宁可去买技术,也不愿投入资金进行研发
君不见上汽南汽抢着收购罗孚汽车,TCL收购阿尔卡特手机研发部门和飞利浦彩电研发部门,我们的政策是市场换技术,而不是加大研发投入自己搞技术。
6、企业内的“政治”让技术人员心灰意冷
大部分热衷于技术的人员在“政治”上都相当低能,这也不是他们笨,而是“一心不能二用”,满脑袋都琢磨的是技术,怎么可能天天去琢磨人,但是,企业里混得好的都是成天琢磨人的主。
这也是为什么很多搞技......
软件企业需求的人才(开发人员与软件开发工程师综合对比篇)(2007-05-06 21:43:00)
摘要:软件企业需求的人才(开发人员与软件开发工程师综合对比篇)
普通开发人员与软件工程师的区别:
对比1:
A、普通开发人员:
掌握了计算机基础知识;
熟悉计算机资源,学会了编程语言,喜欢卖弄技巧,喜欢比较编程语言的优劣;
以能编出某种特殊功能的程序为荣,不懂原理,不求甚解;
喜欢个人开发,不重视文档编写;
B、软件工程师:
计算机基础知识扎实;
掌握两门以上编程语言,很少停留在表面比较编程语言的优劣;
以编写出用户满意的高质量软件为荣。
懂得个人开发和团队开发的利弊,文档规范,齐全。
google_ad_client = "pub-4475724770859924";google_alternate_color = "E6E6E6";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_type = "text_image";google_ad_channel ="4150302033";google_color_border = "F8F8F8";google_color_bg = "FFFFFF";google_color_link = "FF6FCF";google_color_url = "38B63C";google_color_text = "B3B3B3";
对比2:
A、普通开发人员:
只重视功能的实现,不重进度和质量的把握。
怕被“管”得太死,动不动就说限制了思路,没有发挥空间。
不喜欢做测试工作,认为测试低人一等,从来没有做过测试工作。
只根据自己的爱好学习技术;
B、软件工程师:
懂得在进度、质量(功能)和成本之间平衡。
懂得规范的目的在于重用,重用有利于提高效率和集中精力创新。
认为测试工作比编码更具挑战性,自己经常为同伴的代码做白盒测试。
根据企业项目的需求和自己发展目标的共同点选择学习内容和方向;
对比3:
A、普通开发人员:
认为别人程序很差,不喜欢看别......
MFC中消息循环处理的几个函数之间的区别(2007-05-05 11:10:00)
摘要:MFC中消息循环处理的几个函数之间的区别以下说明几个消息循环中的常用函数进行对比 1 PostMessage 与 SendMessage 函数对比 SendMessage把消息直接发送到窗口,并调用此窗口的相应消息处理函数,等消息处理函数结束后SendMessage才返回!SendMessage发送的消息不进入系统的消息队列;SendMessage函数有返回值 PostMessage将消息发送到与创建窗口的线程相关联的消息队列后立即返回;PostMessage函数没有返回值; 2 GetMessage 与 PeekMessage函数的对比 GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) PeekMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax,UINT wRemoveMsg) 根据参数可以看出以上2个函数的区别,参数wRemoveMsg的作用是指定消息获取的方式,如果设为PM_NOREMOVE,那么消息将不会从消息队列中被移出,如果设为PM_REMOVE,那么消息将会从消息队列中被移出; 还有区别: 他们如果没有捕获到消息,程序的主线程会被操作系统挂起。当操作系统再次回来照顾此线程时,发现消息队列中仍然没有消息可取,此时两个函数的行为就不同了: GetMessage : 过门不入,操作系统再次挂起此线程,去照顾别的线程; PeekMessage: 取回控制权,使程序执行一段时间,等待可能的消息进入消息队列并将其捕获;这时程序进入空闲时间阶段; ......
gcc 常用命令行列表(2007-05-04 18:08:00)
摘要:gcc 常用命令行列表
-o FILE
指定输出文件名,在编译为目标代码时,这一选项不是必须的。如果FILE没有指定,缺省文件名是a.out.
-c
只编译不链接
-DFOO=BAR
在命令行定义预处理宏FOO,其值为BAR
-IDIRNAME
将DIRNAME加入到头文件的搜索目录列表中
-LDIRNAME
将DIRNAME加入到库文件的搜索目录列表中,缺省情况下gcc 只链接共享库
-static
链接静态库,即执行静态链接
-lFOO
链接名为libFOO的函数库
-g
在可执行程序中包含标准调试信息
-ggdb
在可执行程序中包含只有GNU debugger才能使别的达两条是信息
-O
优化编译过的代码
-ON
指定代码优化的级别为N,o......
C语言初学者入门讲座 第十六讲 文件(2)(2007-05-04 17:25:00)
摘要:C语言初学者入门讲座 第十六讲 文件(2)
字符串读写函数fgets和fputs
一、读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符数组中,函数调用的形式为: fgets(字符数组名,n,文件指针);其中的n是一个正整数。表示从文件中读出的字符串不超过 n-1个字符。在读入的最后一个字符后加上串结束标志'/0'。例如:fgets(str,n,fp);的意义是从fp所指的文件中读出n-1个字符送入字符数组str中。
[例10.4]从e10_1.c文件中读入一个含10个字符的字符串。
#include
main()
{
FILE *fp;
char str[11];
if((fp=fopen("e10_1.c","rt"))==NULL)
{
printf("Cannot open file strike any key exit!");
getch();
exit(1);
}
fgets(str,11,fp);
printf("%s",str);
fclose(fp);
}
本例定义了一个字符数组str共11个字节,在以读文本文件方式打开文件e101.c后,从中读出10个字符送入str数组,在数组最后一个单元内将加上'/0',然后在屏幕上显示输出str数组。输出的十个字符正是例10.1程序的前十个字符。
对fgets函数有两点说明:
1. 在读出n-1个字符之前,如遇到了换行符或EOF,则读出结束。
2. fgets函数也有返回值,其返回值是字符数组的首地址。
二、写字符串函数fputs
fputs函数的功能是向指定的文件写入一个字符串,其调用形式为: fputs(字符串,文件指针) 其中字符串可以是字符串常量,也可以是字符数组名, 或指针 变量,例如:
fputs(“abcd“,fp);
其意义是把字符串“abcd”写入fp所指的文件之中。[例10.5]在例10.2中建立的文件string中追加一个字符串。
#include
main()
{
FILE *fp;
char ch,st[20];
if((fp=fopen("string","at+"))==NULL)
{
printf("Can......
C语言初学者入门讲座 第十六讲 文件(1)(2007-05-04 17:24:00)
摘要:C语言初学者入门讲座 第十六讲 文件(1)
所谓“文件”是指一组相关数据的有序集合。 这个数据集有一个名称,叫做文件名。实际上在前面的各章中我们已经多次使用了文件,例如源程序文件、目标文件、可执行文件、库文件 (头文件)等。文件通常是驻留在外部介质(如磁盘等)上的,在使用时才调入内存中来。从不同的角度可对文件作不同的分类。从用户的角度看,文件可分为普通文件和设备文件两种。
普通文件是指驻留在磁盘或其它外部介质上的一个有序数据集,可以是源文件、目标文件、可执行程序; 也可以是一组待输入处理的原始数据,或者是一组输出的结果。对于源文件、目标文件、 可执行程序可以称作程序文件,对输入输出数据可称作数据文件。
设备文件是指与主机相联的各种外部设备,如显示器、打印机、键盘等。在操作系统中,把外部设备也看作是一个文件来进行管理,把它们的输入、输出等同于对磁盘文件的读和写。 通常把显示器定义为标准输出文件,一般情况下在屏幕上显示有关信息就是向标准输出文件输出。如前面经常使用的printf,putchar 函数就是这类输出。键盘通常被指定标准的输入文件, 从键盘上输入就意味着从标准输入文件上输入数据。scanf,getchar函数就属于这类输入。
从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种。
ASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。例如,数5678的存储形式为:
ASC码: 00110101 00110110 00110111 00111000
↓ ↓ ↓ ↓
十进制码: 5 6 7 8 共占用4个字节。ASCII码文件可在屏幕上按字符显示, 例如源程序文件就是ASCII文件,用DOS命令TYPE可显示文件的内容。 由于是按字符显示,因此能读懂文件内容。
二进制文件是按二进制的编码方式来存放文件的。 例如, 数5678的存储形式为: 00010110 00101110只占二个字节。二进制文件虽然也可在屏幕上显示,但其内容无法读懂。C系统在处理这些文件时,并不区分类型,都看成是字符流,按字节进行处理。输入输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。 因此也把这种文......