??xml version="1.0" encoding="utf-8" standalone="yes"?>蜜乳av另类精品一区二区,精久久久久久久久久久,国产mv久久久http://www.aygfsteel.com/morphis/Be fresh and eager every morning, and tired and satisfied every night.zh-cnWed, 18 Jun 2025 09:55:08 GMTWed, 18 Jun 2025 09:55:08 GMT60[转] Usefull Sqlhttp://www.aygfsteel.com/morphis/archive/2007/10/30/156998.htmlmorphismorphisTue, 30 Oct 2007 09:40:00 GMThttp://www.aygfsteel.com/morphis/archive/2007/10/30/156998.htmlhttp://www.aygfsteel.com/morphis/comments/156998.htmlhttp://www.aygfsteel.com/morphis/archive/2007/10/30/156998.html#Feedback0http://www.aygfsteel.com/morphis/comments/commentRss/156998.htmlhttp://www.aygfsteel.com/morphis/services/trackbacks/156998.htmlSQL语句先前写的时候,很容易把一些特D的用法忘记Q我Ҏ(gu)整理了一下SQL语句操作?br /> 一、基
1、说明:(x)创徏数据?br /> CREATE DATABASE database-name
2、说明:(x)删除数据?br /> drop database dbname
3、说明:(x)备䆾sql server
--- 创徏 备䆾数据?device
USE master
EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
--- 开?备䆾
BACKUP DATABASE pubs TO testBack
4、说明:(x)创徏新表
create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
Ҏ(gu)已有的表创徏新表Q?
AQcreate table tab_new like tab_old (使用旧表创徏新表)
BQcreate table tab_new as select col1,col2... from tab_old definition only
5、说明:(x)删除新表
drop table tabname
6、说明:(x)增加一个列
Alter table tabname add column col type
注:(x)列增加后不能删除。DB2中列加上后数据类型也不能改变Q唯一能改变的是增加varcharcd的长度?br /> 7、说明:(x)d主键Q?Alter table tabname add primary key(col)
说明Q删除主键:(x) Alter table tabname drop primary key(col)
8、说明:(x)创徏索引Qcreate [unique] index idxname on tabname(col....)
删除索引Qdrop index idxname
注:(x)索引是不可更改的Q想更改必须删除重新建?br /> 9、说明:(x)创徏视图Qcreate view viewname as select statement
删除视图Qdrop view viewname
10、说明:(x)几个单的基本的sql语句
选择Qselect * from table1 where 范围
插入Qinsert into table1(field1,field2) values(value1,value2)
删除Qdelete from table1 where 范围
更新Qupdate table1 set field1=value1 where 范围
查找Qselect * from table1 where field1 like '%value1%' ---like的语法很_֦Q查资料!
排序Qselect * from table1 order by field1,field2 [desc]
LQselect count as totalcount from table1
求和Qselect sum(field1) as sumvalue from table1
q_Qselect avg(field1) as avgvalue from table1
最大:(x)select max(field1) as maxvalue from table1
最:(x)select min(field1) as minvalue from table1
11、说明:(x)几个高查询q算?br /> AQ?UNION q算W?
UNION q算W通过l合其他两个l果表(例如 TABLE1 ?TABLE2Qƈ消去表中M重复行而派生出一个结果表。当 ALL ?UNION 一起用时Q即 UNION ALLQ,不消除重复行。两U情况下Q派生表的每一行不是来?TABLE1 是来自 TABLE2?
BQ?EXCEPT q算W?
EXCEPT q算W通过包括所有在 TABLE1 中但不在 TABLE2 中的行ƈ消除所有重复行而派生出一个结果表。当 ALL ?EXCEPT 一起用时 (EXCEPT ALL)Q不消除重复行?
CQ?INTERSECT q算W?br /> INTERSECT q算W通过只包?TABLE1 ?TABLE2 中都有的行ƈ消除所有重复行而派生出一个结果表。当 ALL ?INTERSECT 一起用时 (INTERSECT ALL)Q不消除重复行?
注:(x)使用q算词的几个查询l果行必L一致的?
12、说明:(x)使用外连?
A、left outer joinQ?
左外q接Q左q接Q:(x)l果集几包括q接表的匚w行,也包括左q接表的所有行?
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
BQright outer join:
叛_q接(双?Q结果集既包括连接表的匹配连接行Q也包括双接表的所有行?
CQfull outer joinQ?
全外q接Q不仅包括符可接表的匹配行Q还包括两个q接表中的所有记录?br /> 二、提?br /> 1、说明:(x)复制?只复制结?源表名:(x)a 新表名:(x)b) (Access可用)
法一Qselect * into b from a where 1<>1
法二Qselect top 0 * into b from a
2、说明:(x)拯?拯数据,源表名:(x)a 目标表名Qb) (Access可用)
insert into b(a, b, c) select d,e,f from b;
3、说明:(x)跨数据库之间表的拯(具体数据使用l对路径) (Access可用)
insert into b(a, b, c) select d,e,f from b in '具体数据? where 条g
例子Q?.from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..
4、说明:(x)子查?表名1Qa 表名2Qb)
select a,b,c from a where a IN (select d from b ) 或? select a,b,c from a where a IN (1,2,3)
5、说明:(x)昄文章、提交h和最后回复时?br /> select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
6、说明:(x)外连接查?表名1Qa 表名2Qb)
select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
7、说明:(x)在线视图查询(表名1Qa )
select * from (SELECT a,b,c FROM a) T where t.a > 1;
8、说明:(x)between的用?between限制查询数据范围时包括了边界?not between不包?br /> select * from table1 where time between time1 and time2
select a,b,c, from table1 where a not between 数? and 数?
9、说明:(x)in 的用方?br /> select * from table1 where a [not] in ('?','?','?','?')
10、说明:(x)两张兌表,删除主表中已l在副表中没有的信息
delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )
11、说明:(x)四表联查问题Q?br /> select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....
12、说明:(x)日程安排提前五分钟提?
SQL: select * from 日程安排 where datediff('minute',f开始时?getdate())>5
13、说明:(x)一条sql 语句搞定数据库分?br /> select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段
14、说明:(x)?0条记?br /> select top 10 * form table1 where 范围
15、说明:(x)选择在每一lb值相同的数据中对应的a最大的记录的所有信?cMq样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成l排?{等.)
select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)
16、说明:(x)包括所有在 TableA 中但不在 TableB和TableC 中的行ƈ消除所有重复行而派生出一个结果表
(select a from tableA ) except (select a from tableB) except (select a from tableC)
17、说明:(x)随机取出10条数?br /> select top 10 * from tablename order by newid()
18、说明:(x)随机选择记录
select newid()
19、说明:(x)删除重复记录
Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)
20、说明:(x)列出数据库里所有的表名
select name from sysobjects where type='U'
21、说明:(x)列出表里的所有的
select name from syscolumns where id=object_id('TableName')
22、说明:(x)列示type、vender、pcs字段Q以type字段排列Qcase可以方便地实现多重选择Q类似select 中的case?br /> select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type
昄l果Q?br /> type vender pcs
?sh)?A 1
?sh)?A 1
光盘 B 2
光盘 A 2
手机 B 3
手机 C 3
23、说明:(x)初始化表table1
TRUNCATE TABLE table1
24、说明:(x)选择?0?5的记?br /> select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc
三、技?br /> 1?=1Q?=2的用,在SQL语句l合时用的较?br /> "where 1=1" 是表C选择全部   "where 1=2"全部不选,
如:(x)
if @strWhere !=''
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere
end
else
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + ']'
end
我们可以直接写成
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere
2、收~数据库
--重徏索引
DBCC REINDEX
DBCC INDEXDEFRAG
--收羃数据和日?br /> DBCC SHRINKDB
DBCC SHRINKFILE
3、压~数据库
dbcc shrinkdatabase(dbname)
4、{UL据库l新用户以已存在用户权限
exec sp_change_users_login 'update_one','newname','oldname'
go
5、检查备份集
RESTORE VERIFYONLY from disk='E:\dvbbs.bak'
6、修复数据库
ALTER DATABASE [dvbbs] SET SINGLE_USER
GO
DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK
GO
ALTER DATABASE [dvbbs] SET MULTI_USER
GO
7、日志清?br /> SET NOCOUNT ON
DECLARE @LogicalFileName sysname,
        @MaxMinutes INT,
        @NewSize INT

USE     tablename             -- 要操作的数据库名
SELECT  @LogicalFileName = 'tablename_log',  -- 日志文g?br /> @MaxMinutes = 10,               -- Limit on time allowed to wrap log.
        @NewSize = 1                  -- 你想讑֮的日志文件的大小(M)
-- Setup / initialize
DECLARE @OriginalSize int
SELECT @OriginalSize = size
  FROM sysfiles
  WHERE name = @LogicalFileName
SELECT 'Original Size of ' + db_name() + ' LOG is ' +
        CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' +
        CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB'
  FROM sysfiles
  WHERE name = @LogicalFileName
CREATE TABLE DummyTrans
  (DummyColumn char (8000) not null)

DECLARE @Counter   INT,
        @StartTime DATETIME,
        @TruncLog  VARCHAR(255)
SELECT  @StartTime = GETDATE(),
        @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY'
DBCC SHRINKFILE (@LogicalFileName, @NewSize)
EXEC (@TruncLog)
-- Wrap the log if necessary.
WHILE     @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired
      AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName) 
      AND (@OriginalSize * 8 /1024) > @NewSize 
  BEGIN -- Outer loop.
    SELECT @Counter = 0
    WHILE  ((@Counter < @OriginalSize / 16) AND (@Counter < 50000))
      BEGIN -- update
        INSERT DummyTrans VALUES ('Fill Log') 
        DELETE DummyTrans
        SELECT @Counter = @Counter + 1
      END  
    EXEC (@TruncLog) 
  END  
SELECT 'Final Size of ' + db_name() + ' LOG is ' +
        CONVERT(VARCHAR(30),size) + ' 8K pages or ' +
        CONVERT(VARCHAR(30),(size*8/1024)) + 'MB'
  FROM sysfiles
  WHERE name = @LogicalFileName
DROP TABLE DummyTrans
SET NOCOUNT OFF
8、说明:(x)更改某个?br /> exec sp_changeobjectowner 'tablename','dbo'
9、存储更改全部表
CREATE PROCEDURE dbo.User_ChangeObjectOwnerBatch
 @OldOwner as NVARCHAR(128),
 @NewOwner as NVARCHAR(128)
AS
DECLARE @Name   as NVARCHAR(128)
DECLARE @Owner  as NVARCHAR(128)
DECLARE @OwnerName  as NVARCHAR(128)
DECLARE curObject CURSOR FOR
 select 'Name'   = name,
  'Owner'   = user_name(uid)
 from sysobjects
 where user_name(uid)=@OldOwner
 order by name
OPEN  curObject
FETCH NEXT FROM curObject INTO @Name, @Owner
WHILE(@@FETCH_STATUS=0)
BEGIN    
 if @Owner=@OldOwner
 begin
  set @OwnerName = @OldOwner + '.' + rtrim(@Name)
  exec sp_changeobjectowner @OwnerName, @NewOwner
 end
-- select @name,@NewOwner,@OldOwner
 FETCH NEXT FROM curObject INTO @Name, @Owner
END
close curObject
deallocate curObject
GO

10、SQL SERVER中直接@环写入数?br /> declare @i int
set @i=1
while @i<30
begin
   insert into test (userid) values(@i)
   set @i=@i+1
end
记存储q程中经常用到的本周Q本月,本年函数
Dateadd(wk,datediff(wk,0,getdate()),-1)
Dateadd(wk,datediff(wk,0,getdate()),6)
Dateadd(mm,datediff(mm,0,getdate()),0)
Dateadd(ms,-3,dateadd(mm,datediff(m,0,getdate())+1,0))
Dateadd(yy,datediff(yy,0,getdate()),0)
Dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))
上面的SQL代码只是一个时间段
Dateadd(wk,datediff(wk,0,getdate()),-1)
Dateadd(wk,datediff(wk,0,getdate()),6)
是表示本周旉D?
下面的SQL的条仉?是查询旉D在本周范围内的:
Where Time BETWEEN Dateadd(wk,datediff(wk,0,getdate()),-1) AND Dateadd(wk,datediff(wk,0,getdate()),6)
而在存储q程?
select @begintime = Dateadd(wk,datediff(wk,0,getdate()),-1)
select @endtime = Dateadd(wk,datediff(wk,0,getdate()),6)



morphis 2007-10-30 17:40 发表评论
]]>
c,c++水^相关http://www.aygfsteel.com/morphis/archive/2007/09/08/143698.htmlmorphismorphisSat, 08 Sep 2007 15:35:00 GMThttp://www.aygfsteel.com/morphis/archive/2007/09/08/143698.htmlhttp://www.aygfsteel.com/morphis/comments/143698.htmlhttp://www.aygfsteel.com/morphis/archive/2007/09/08/143698.html#Feedback0http://www.aygfsteel.com/morphis/comments/commentRss/143698.htmlhttp://www.aygfsteel.com/morphis/services/trackbacks/143698.html1. 在类的普通成员函C调用虚函敎ͼ情况是怎么L(fng)Q(对象、引用、指针)(j)

多态, 事实上,q是 Template Method模式的关?/span>
2.
关于成员变量初始化顺序,几个有依赖关pȝ成员变量要初始化Q让写出构造函数?/strong>

在初始化列表中,成员变量的初始化序是其在类中声明顺序,而非列表中的序?br />

3. 写一个双链表?/span>

Struct ListNode

{

    int nData;

    ListNode* pPreviousNode;

    ListNode* pNextNode;

}

一般链表都?x)有一个表头节点与指向表头节点的头指针Q?/span> 应该?x)提供列表接口?/span> 按此数据l构实现卛_?/span>

4. 写个is-a?/span>has-a?/span>

q个比较?/p>

Class Pet{};

Class Dog: public Pet{};

Class Boy{Pet* m_pPet;};

5. struct vs. class.

1)默认讉K属性, struct?/span>public, class?/span>private

2) 默认l承属性,struct?/span>public, class?/span>private
3)class
可以用来声明模板参数Q?/span>struct不能

6. U?/span>8个小球的问题

没题

7. stl 里面vector的实玎ͼ内部I间的申请与分配Q?/span>

Vector中文名字是动态数l, 其内部数据结构就是一个数l, 但是在数l元素不够用的时候,p动态的重新分配Q?/span> 一般是现在大小的两倍, 然后把原数组的内Ҏ(gu)贝过厅R所以, 在一般情况下Q?/span> 其访问速度同一般数l, 只有在重新分配发生时Q?/span> 其性能才会(x)下降

8. struct /class的区?/span>

重复?/p>

9. Z么要?/span>struct

成员的默认属性不同,?/span>struct的话Q主要是作ؓ(f)数据的集合?/span>

10. 怎样使一?/span>class不能被实例化

1Q构造函数私有化Q?/span>2Q抽象类

11. U有l承?/span>publicl承的区别?/span>

U有l承Q?/span> 只承实玎ͼ不承实?/span> has-a

公有l承Q承接口与实现    is-a

12. void *p的问?/span>

不能++

13. 引用和指针的区别与联pR引用是否可以更?/span>

联系Q?/span> 支持多态,可以用来引用同一对象

区别Q指针可以ؓ(f)NULLQ?/span> 引用不可以; 指针可以重赋| 引用不可以;

14. windows~程基础Q线E与q程的区?/span>

E序是一pd静态的指o(h)序列

q程是程序的一ơ动态执行,q程其实是一个资源的容器Q包括一个私有的虚拟地址I间Q一些初始的代码与数据, 一些系l资源的句柄{?/span>

U程是一个进E中的执行体Q?/span> 一般包?/span>CPU寄存器状态,两个栈(内核模式Q用h式)(j)以及(qing)一?/span>TLS(Thread-Local Storage){?/span>

15. com+是否熟?zhn)?/span>

COM+?/span>COM技术的延与发展, 它包括了所?/span>COM的基本功能(Z接口的编E模型,基本lg服务Q,q组合了DCOMQɾlg技术g伸到了分布式领域Q和MTS-Microsoft Transaction ServerQ提供了服务器端的组件管理与配置理Q,q新增了一些服务:(x)负蝲qQ内存数据库Q事件模型,队列服务{,主要用于Windows DNA(Distributed interNet Application Architecture)三层l构的中间层?/span>

16. qC?/span>hash

哈希表的目的是表查询插入修改能够辑ֈO(1)的算法复杂度Q?/span> 通过?/span>key~码来确定其存储地址来实玎ͼ 当不同的key得到相同的编码时Q便需要进行冲H检与处理Q一般方法有除留余数法, U性探法Q^Ҏ(gu)法Q?/span> q其无法真正达?/span>O(1)

17. 一?/span>32位的数据Q怎样扑ֈ最左边的一?/span>1Q?/span>

如果是在最左位Q这个数是负敎ͼ否则的话Q左UM位,看是否变成负敎ͼq是O(n)的算?/span>Q?/span> 也可以用一个模板去与,q不断改变这个模?/span>

O(n/2)的算法:(x)二分方式查找 Q?Q?/span>

18. 一?/span>4*4的格子,填入1~15 然后l个目标状态,怎样L索?br /> 比如Q?br />  1   2  3    6
 0   4  5    7
 8   9  10 11
12 13 14 14

再给Z最l的状?Q随侉K可以Q?
0 表示一个空|可以UdQ有点像拼图Q?/strong> 

人工的教材上用的应该是q个例子Q用A*法Q它既不是广度搜索,也不是深度搜索,而是一U启发式搜烦(ch)Q在q行下一步搜索之前,?x)用一个估价函数来对后面的节点评分Q?取评分最优的q行下一步搜索,如果找不到结果,回溯。对于本题,用曼哈顿距离作ؓ(f)评分标准是个不错的选择?/p>

19. l你100万个数据Q数据的值在0~65535之间 用最快的速度排序

多关键字基数排序MSD(MOST SIGNIFICANT DIGIT FIRST)

20. 如果我们的一个Y件品,用户回复_(d)(x)q行速度很慢Q你怎么处理Q?/span>

询问?/span>Workflow, 用户的硬件环?/span>

21. 八皇后问题,详述解法 Q?/span>八皇后问题说的是?/span>8*8国际象棋盘?/span>,要求在每一行放|一个皇?/span>,且能做到在竖方向,斜方向都没有冲突Q?/span>

回溯?/p>

22. kmp快速匹配算?/span> ---不算L的搞?/span>

普通的模式匚w法Q一旦不匚wQ模式串右移一位;但是其实Ҏ(gu)一直条Ӟ我们可以出应该向右Ud位以避免不必要的比较Q算法实现比较曲?/p>

23. 无向图中两点间最短\问题 ---伟大的_杰克斯拉法

假设一共有N个节点, 需要一个一l数l?/span>Previous[N]来记录前一个节点序P一个一l数l?/span>TotalLength[N]来记录从原点到当前节Ҏ(gu)短\径;一个二l数l?/span>Weights[N][N]来记录各点之间边的权?/span>(如果存在)Q?/span> 然后从源点到l点q行深度搜烦(ch)或广度搜索, 按以下规则:(x)搜烦(ch)到某个节?/span>bӞ假设其前一个节点ؓ(f)a, ?/span>TotalLength[a] + Weights[a][b]?/span>TotalLength[b]相比较,如果于TotalLength[b]Q?/span> ?/span>TotalLength[b] = TotalLength[a] + Weights[a][b], Previous[b] = a; 反之则不做Q何操作。这样到搜烦(ch)l束后, ?/span>Previous[N]数组中就能得到整条最短\径了

24. I间中Q意给两个向量Q求角^分线

先单位化Q?/span> 假设单位化后l果?/span>nv1, nv2, 则角q_Uؓ(f)(nv1+nv2) / 2

25. 什么是q?/span>

左右子树(wi)都是q?wi),且高度相差不?/span>1的有序二叉树(wi)

26. 哈夫曼编码问?/span>

理论基础:霍夫曼树(wi)是带权\径长度(WPLQ?/span>Weighted Path LengthQ最的二叉?wi),它不一定是完全二叉?wi),应该是权值大的外l点L节点最q的扩充二叉?wi)。霍夫曼~码是ؓ(f)了实现数据的最冗余编码,是数据压~学的基?/span> 它根据字W在甉|中出现的频率为权|构造霍夫曼?wi),左?f)0Q?/span> 右ؓ(f)1. 其有两个效果Q一是保证电(sh)文有最短的~码Q二是字W间不需要分隔符Q因Z同的字符必定有不同的开_(d)成ؓ(f)前缀~码Q?/span>

27. 有向图求?/span>

以该节点为源点与l点吗进行深度优先或q度优先搜烦(ch)

28. .l?/span>n个点Q求凸包问题

凸包(convex hull)是指一个最凸多边形,满q?/span>N个点都在多边形上Q或其内。算法描qͼ(x)

求出最右的那个点作为凸多边形的一个顶?/span>(P0)Q遍历其他所有点(Pi)Q?/span> 如果其他炚w在向?/span>P0Pi的同一侧,?/span>Pi也ؓ(f)凸多边Ş的顶炏V?/span>

29. 四则q算Q给一个前~表达式(波兰式)(j)或后~表达?/span>(逆L兰式)Q然后求解;l一个中~表达式)(j)

+*-CDBA -/EF---------------------> A+B*(C-D)-E/F       前缀-中缀

操作W进栈,一个变?/span>tmp放上一个中间操作数Q运结果)(j)Q遇到操作数(g)?/span>tmp是否为空Q?/span> I的话取两个操作敎ͼ不空的话取一个操作数Q另一个就?/span>tmp了,操作W出栈运,l果攑օtmp中,如果是操作符Q?/span>tmp清空

 ABCD-*+EF/- ---------------------> A+B*(C-D)-E/F     后缀-中缀

操作数进栈,遇到操作W,两个操作数出栈,计算l果入栈

30. STL?/span>container有哪些?

序列容器Q?/span> vector, list, deque, bitset

兌容器:     set, multiset, map, multimap

适配容器Q?/span>stack, queue, priority_queue

cd?/span>:         string, valarray, bitset

扩展容器Q?/span>hash_set, hash_multiset, hash_map, hash_multimap

31. map中的数据存储方式是什么?

U黑?wi)?/span> 是一U^衡二叉搜索树(wi)Q?/span> h良好的最坏情况运行时_(d)l计性能好与AVL?wi)?j)

32. map?/span>hashmap有什么区别?

内部数据l构不同Q?/span> map是红黑树(wi)Q?/span>hashmap是哈希表

33. hashmap是标准库中的吗?

不是的,但在SGI stl?/span>vc2005中都提供了?/span>

34. vector中的eraseҎ(gu)?/span>algorithm?/span>remove有什么区别?

vector?/span>erase是真正删除了元素Q?/span> q代器访问不C?/span> algorithm中的remove只是单的把要remove的元素移C容器最后面QP代器q是可以讉K到的。因?/span>algorithm通过q代器操作,不知道容器的内部l构Q所以无法做到真正删除?/span>

35. object是什么?

h内部状态,以及(qing)操作?/span> 软g构造,用来表示真实存在Q物理上或概念上Q的对象

36. C++中如何阻止一个类被实例化Q?/span>

U虚函数Q构造函数私有化Q友元)(j)

37. 一般在什么时候构造函数被声明?/span>private呢?

 singleton模式Q?/span> L某些操作Q如L拯构?/span>Q?/span>

38. 什么时候编译器?x)生成默认?/span>copy constructor呢?

用户没有自定?/span>copy constructorQ在代码中用到?/span>copy constructor;

39. 如果你已l写了一个构造函敎ͼ~译器还?x)生?/span>copy constructor吗?

如果我写的是copy constructor, 不会(x)

如果我写的不?/span>copy constructor, ?/span>38

40. Z么说如果一个类作ؓ(f)基类Q则它的析构函数要声明成virtual的?

因ؓ(f)Q如?/span>delete一个基cȝ指针Ӟ 如果它指向的是一个子cȝ对象Q那么析构函C׃(x)D无法调用子类析构函数Q从而导致资源泄霌Ӏ?/span> 当然Q另一U做法是基cL构函数设?/span>protected.

41. inline的函数和#define有什么区别?什么时候会(x)真的?/span>inlineQ什么时候不?x)呢Q?/span>

1) 宏是在预~译阶段单文本替代, inline在编译阶D实现展开

2)宏肯定会(x)被替代,而复杂的inline函数不会(x)被展开

3)宏容易出错(q算序Q,且难以被调试,inline不会(x)

4)宏不是类型安全,?/span>inline是类型安全的Q会(x)提供参数与返回值的cd(g)?/span>

当出C下情冉|inlinep|

函数size太大

inline虚函?/span>

函数中存在@环或递归

函数调用其他inline函数

42. 如果把一个类的成员函数写在类的声明中是什么意思?

inline此函?/span> Q?/span>inline?/span>templatecMQ?/span> 必须?/span>.h中实玎ͼ(j)

43. publicl承?/span>privatel承有什么架构上的区别?

public?/span>is-a的关p,l承接口与实?/span>

private?/span>has-a的关p?/span> Q只l承实现

44. 在多l承的时候,如果一个类l承同时l承?/span>class A?/span>class BQ?/span>class A?/span>B中都有一个函数叫foo()Q如何明的在子cM指出override哪个父类?/span>foo()Q?/span>

首先Q?/span>foo?/span>A,Bd该都是虚函数Q否则就直接覆盖了,没有这个问题了Q其ơ,q个问题从语法角度来看似乎是无法解决。因为我们不能改原有设计Q不然也没这个问题了:)Q?/span>,所有只好从extend来考虑Q?/span>

class EA: public class A

{

public:

   virtual void foo(){fooA();}

private:

   virtual void fooA() = 0;

}

 

class EB: public class B

{

public:

   virtual void foo(){fooB();}

private:

   virtual void fooB() = 0;

}

 

q样Q?/span> 我就可以override不同的函数来辑ֈq个目的?/span>

class AB: public EA, pubic EB

{

private:

virtual void fooA(){}

virtual void fooB(){}

}

45. 虚拟l承的语法是什么?

    A

 /     \

B      C

   \ /

    D

class A{};

class B: virtual public A{};

class C: virtual public A{};

class D: public B, public C{};

46. 部分模版特例化和全部模版特例化有什么区别?

偏特化只使用于类模板Q而全特化适用与函数模板,cLѝ?/p>

偏特化的l果q是一个模板,而全特化的结果是一个具体的cd?/p>

47. ~一个函敎ͼ使一个单w表{|?/span>

应该是逆序?/p>

q个算法竟然花了我不少旉Q没有测试过的:(x)

struct ListNode
{
    
int data;
    ListNode
* next;
};

void ReverseList(ListNode* p)
{
    ListNode
* p0 = NULL;
    ListNode
* p1 = p->next;
    ListNode
* p2 = p1 ? p1->next : NULL;

    
// 三个指针Q分别表C当前处理节点,前一节点与后一节点
    
// 复用头节点的next来保存节?/span>
    while (NULL != p2)
    {
        p
->next = p2->next; //暂存

        p1
->next = p0;      //逆{
        p2->next = p1;

        p0 
= p1;            //往下一个节?/span>
        p1 = p2;
        p2 
= p->next;
    }
    p
->next = p1;    //p1末元素变为首元素Q链到头节点?/span>
}

 

48. 拆解一个整敎ͼ比如4,可以拆解?/span>4=3+1Q?/span>4=2+2Q?/span>4=2+1+1Q?/span>4=1+1+1+1

首先Q对一个数q行拆分后,可能又要Ҏ(gu)后一个因子进行拆分,所以要用递归Q其ơ,W?/span>n+1个因子是于{于W?/span>n个因子的Q再者,Ҏ(gu)后一个因子,我可以直接输出,也可以l拆分?/span>

法如下Q?br />

void print(int res[], int num)
{
    
for (int i = 0; i < num; ++i)
    {
        printf(
"%d ", res[i]);
    }
    printf(
"\n");
}
// n表示LQm表示最大因?/span>
void split(int n, int m)
{
    
static int res[100]; //保存l果
    static int num = -1//当前因子下标
    num++;
    
//递归l止条gQؓ(f)0不可再分Q直接输?/span>
    if(0 == n) 
    {
        print(res, num
+1);
        num
--;
        
return;
    }
    
else
    {
        
if(n == m) 
        {
            
// 不拆Q直接输?/span>
            res[num] = m;
            print(res,num
+1);
            num
--;
        }
        
else
        {
            
// 拆分出第一?/span>
            res[num] = m;
            n 
= n-m;
            
//最大因子不可能大于L
            if(m>n) m = n;

            
// 循环Q第二个因子可以l箋拆分Q而且按照最大因子不同可以拆分成多个
            for (int i = m; i>=1--i)
            {
                split(n, i);
            }
            num
--;
        }    
    }
}

void Split(int n)
{
    
for (int i = n-1; i>=1; i--)
    {
        split(n, i);
    }
}


唉,老了Q这个小东西搞了?span>N久的。。。?/span>

49. 不用库函敎ͼ实现strcpy或?/span>memcpy{函?/span>

一个字节一个字节的拯dQ但是要考虑源内存与目标内存的重叠?/p>

50. 内联函数的作用和~点

把代码直接插入到调用的地方,可以减少函数调用的次敎ͼ但是?x)增加代码?/span>sizeQ还有,如果内联p|Q在每个调用?/span>obj里,都会(x)产生一份该函数的拷贝,q样既没有怎么减少代码?/span>sizeQ又没有减少函数的调用,赔了夫h又折c(din)。?/span>

51. 指针和引用的区别

指针可以不初始化Q引用必d始化

指针可以?/span>NULLQ而引用必d用一个实在的对象

指针可以重指向其他对象,引用一旦初始化Q便不再改变

52. 友元的意?/span>

使被声明为友元的函数或类可以讉K某个cȝ非共有成?/span>?/p>

53. 虚函数的意义

实现多?/p>

54. Overload, Overwrite, Override 各自的特点和意义

Overload: 函数重蝲(名字相同Q参C?/span>)

OverwriteQ覆?/span>

Override: 虚函数重?/span>

55. 头文件中?/span>ifndef/define/endif q什么用Q?/span>

防止该头文g被重复引?/span>?/span>

56. Q?/span>i nclude <filename.h> 和#i nclude “filename.h” 有什么区别?

Q?/span>i nclude <filename.h>Q?/span> 从标准库路径d找该文gQ对?/span>VC来说Q应该还包括VC环境讄选项中的包含目录以及(qing)工程属性中指定的目?/span>

Q?/span>i nclude “filename.h”Q先在当前目录查找,如果找不刎ͼ按上面那U方式寻?/span>

57. ?/span>C++ E序中调用被C ~译器编译后的函敎ͼZ么要?/span>extern “C”Q?/span>

C++语言支持函数重蝲Q?/span>C 语言不支持函数重载。函数被C++~译后在库中的名字与C 语言的不同?/span>C++提供?/span>C q接交换指定W号extern“C”来解军_字匹配问?/span>

58. 一个类有基cR内部有一个其他类的成员对象,构造函数的执行序是怎样的?

先执行基cȝQ如果基cd中有虚基c,要先执行虚基cȝQ其他基cd按照声明zcL的顺序依ơ执行)(j)Q再执行成员对象的,最后执行自q?/span>

59. hqC个你熟?zhn)的设计模?/span>

q个看你熟?zhn)什么了?/span>singleton最单了Q?/span>template method用的最多了Q?/span>bridge挺炫的,command吹吹undo,redo也不错。。。。?/span>

60. ?/span>UML 中,聚合(aggregation)和组?/span>(composition)有什么区别?

其实从名字就能分别出来了?/p>

聚合表示只是单的聚聚Q没什么本质的联系Q所以这些对象的生存旉也就没什么关pMQ?/p>

l合表示了更加紧密的一U关p,q些对象有着共同的生存期?/p>

一个典型的例子是孙(zhn)空Q手臂,金箍的关系。。。?/p>

61. C#?/span>C++除了语法上的差别以外Q有什么不同的地方Q?/span>

C++是直接生成可执行代码Q?/span>C#是先生成中间代码Q等到第一ơ执行时Q才?/span>JITQ?/span>Just In TimeQ生成可执行的机器码?/span>

q有是(1) c#有垃圾自动回收机ӞE序员不用担心对象的回收?/span>(2)c#严禁使用指针Q只能处理对象。如果希望用指针,则仅可在unsafe E序块中能用指针?/span>(3)c#只能单ѝ?/span>(4)必须通过cd讉K静态成员。不能像C++中那P通过对象讉K静态成员?/span>(5)在子cM重写父类的虚函数时必ȝ关键?/span>override,覆盖父类的方法要用关键字new

62. New delete?/span>malloc free 的区?/span>

对于c,New ?/span>delete?x)调用构造,析构函数

newQ?/span>delete都是能感知到cd的?/span>newq回一个制定的cdQ?/span>delete删除一个指定的cdQ从而不用给?/span>size。?/span>malloc?/span>free都是处理voidcd的。用时时必须l过强制cd转换?/span>

63. #define DOUBLE(x) x+xQ?/span>i = 5*DOUBLE(10)Q?/span>i是多?正确的声明是什么?

I = 5*10+10 = 60 60

正确的声明是Q?/p>

#define DOUBLE(x) ((x)+(x))

64. 有哪几种情况只能?/span>intialization list 而不能用assignment?

当类中含?/span>const?/span>reference 成员变量Q基cȝ构造函数都需要参敎ͼcM含有其他cȝ成员对象Q而该cȝ构造函数都需要参数?/span>

65. C++是不是类型安全的Q?/span>

不是。两个不同类型的指针之间可以强制转换?/span>C#是类型安全的?/span>

66. main 函数执行以前Q还?x)执行什么代码?

全局对象的构造函C(x)?/span>main 函数之前执行?/span>

67. 描述内存分配方式以及(qing)它们的区别?/span>

Q?/span>1Q从静态存储区域分配。内存在E序~译的时候就已经分配好,q块内存在程序的整个q行期间都存在。例如全局变量Q?/span>static 变量?/span>

Q?/span>2Q?/span> 在栈上创建。在执行函数Ӟ函数内局部变量的存储单元都可以在栈上创徏Q函数执行结束时q些存储单元自动被释放。栈内存分配q算内置于处理器的指令集?/span>用的?/span>cacheQ速度较快但容量较?yu)?/span>

Q?/span>3Q?/span> 从堆上分配,亦称动态内存分配。程序在q行的时候用malloc ?/span>new 甌L多少的内存,E序员自p责在何时?/span>free ?/span>delete 释放内存。动态内存的生存期由我们军_Q用非常灵z,但问题也最多?/span>

 Q?Q文字常量区Q?如char* p = "hello, world"是一个例子,其内存也在程序编译的时候就已经分配好?

  一个程序除了上面这些,q有一?5)E序代码Z?br />

68. 比较一?/span>C++?/span>static_cast ?/span> dynamic_cast 的区别?/span>

Static_cast可以昑ּ的做一些自动{换,如一?/span>int, char一些基cd的{换,以及(qing)指针之间的{换。但是其不保证安全性?/span>Dynamic_cast主要作用其实在于把一个基cL针{化ؓ(f)子类指针Q因个基cL针真正指向的不一定是我们惌{换的cd的对象,所以{换可能失败,dynamic_cast能够知道p|而返?/span>NULLQ?/span>static_cast没那么聪明了,原因?/span>dynamic_cast?x)利?/span>rttiL找该转换是否可行.(耗费旉多点?/span>)

69. 当一个类A 中没有生命Q何成员变量与成员函数,q时sizeof(A)的值是多少Q如果不是零Q请解释一下编译器Z么没有让它ؓ(f)零?/span>

不ؓ(f)Ӟ不同的对象应该有不同的地址Q假设我声明一?/span>A的数l?/span>A a[2]Q如果ؓ(f)Ӟ那么a[0]?/span>a[1]的地址岂不相同?/span>

70. 已知两个链表head1 ?/span>head2各自有序Q请把它们合q成一个链表依然有序,要求用递归Ҏ(gu)q行?/span>

归ƈ排序Q应该比较简单。要注意的是如果一个链表ؓ(f)I,那么可以单的把另一个直接链q去了?br />



morphis 2007-09-08 23:35 发表评论
]]>
some englishhttp://www.aygfsteel.com/morphis/archive/2007/06/14/124400.htmlmorphismorphisThu, 14 Jun 2007 15:08:00 GMThttp://www.aygfsteel.com/morphis/archive/2007/06/14/124400.htmlhttp://www.aygfsteel.com/morphis/comments/124400.htmlhttp://www.aygfsteel.com/morphis/archive/2007/06/14/124400.html#Feedback0http://www.aygfsteel.com/morphis/comments/commentRss/124400.htmlhttp://www.aygfsteel.com/morphis/services/trackbacks/124400.html   (1) I love you not because of who you are, but because of who I am when I am with you.

    我爱你,不是因ؓ(f)你是一个怎样的hQ而是因ؓ(f)我喜Ƣ与你在一h的感觉?/p>

    (2) No man or woman is worth your tears, and the one who is, won‘t make you cry.

    没有人值得你流泪,值得让你q么做的Z?x)让你哭泣?/p>

    (3) The worst way to miss someone is to be sitting right beside them knowing you can‘t have them.

    失去某hQ最p糕的莫q于Q他q在w旁Q却犹如q在天边?/p>

    (4) Never frown, even when you are sad, because you never know who is falling in love with your smile.

    U늄伤心Q也不要愁眉不展Q因Z不知是谁?x)爱上你的笑宏Vl+cvz

    (5) To the world you may be one person, but to one person you may be the world.

    对于世界而言Q你是一个hQ但是对于某个hQ但是对于某个hQ你是他的整个世界?/p>

    (6) Don‘t waste your time on a man/woman, who isn‘t willing to waste their time on you.

    不要为那些不愿在你n上花Ҏ(gu)间的浪费你的时间?/p>

    (7) Just because someone doesn’t‘t love you the way you want them to, doesn’t‘t mean they don‘t love you with all they have.

    ׃的h如果没有按你所希望的方式来׃Q那q不代表他们没有全心全意地爱你?/p>

    (8) Don‘t try so hard, the best things come when you least expect them to.f.H0

    不要着急,最好的M(x)在最不经意的时候出现?/p>

    (9) Maybe God wants us to meet a few wrong people before meeting the right one, so that when we finally meet the person, we will know how to be grateful.;

    在遇到梦中h之前Q上天也怼(x)安排我们先遇到别的hQ在我们l于遇见心A的h?数据恢复Q便应当心存感激?/p>

    (10) Don‘t cry because it is over, smile because it happened.

    不要因ؓ(f)l束而哭泣,微笑吧,Z的曾l拥有?



morphis 2007-06-14 23:08 发表评论
]]>
如何阅读别h代码 [转脓(chung)] http://www.aygfsteel.com/morphis/archive/2007/06/14/124397.htmlmorphismorphisThu, 14 Jun 2007 15:05:00 GMThttp://www.aygfsteel.com/morphis/archive/2007/06/14/124397.htmlhttp://www.aygfsteel.com/morphis/comments/124397.htmlhttp://www.aygfsteel.com/morphis/archive/2007/06/14/124397.html#Feedback0http://www.aygfsteel.com/morphis/comments/commentRss/124397.htmlhttp://www.aygfsteel.com/morphis/services/trackbacks/124397.htmlcode reading

++++++++++++

W一? D

++++++++++++



1.要养成一个习(fn)? l常花时间阅d人编写的高品质代?

2.要有选择地阅M? 同时, q要有自q目标. (zhn)是惛_?fn)新的模式|~码风格|q是满某些需求的Ҏ(gu).

3.要注意ƈ重视代码中特D的非功能性需? q些需求也怼(x)DҎ(gu)的实现风?

4.在现有的代码上工作时, 请与作者和l护人员q行必要的协? 以避免重复劳动或产生厌恶情A.

5.请将从开放源码Y件中得到的益处看作是一贷? 可能地L各种方式来回报开放源码社?

6.多数情况? 如果(zhn)想要了?别h?x)如何完成这个功能?", 除了阅读代码以外, 没有更好的方?

7.在寻找bug? 请从问题的表现Ş式到问题的根源来分析代码. 不要沿着不相关的路径(误入歧?.

8.我们要充分利用调试器|~译器给出的警告或输出的W号代码|pȝ调用跟踪器|数据库结构化查询语言的日志机制|包{储工具和W(xu)indows的消

息侦查程? 定出的bug的位|?

9.对于那些大型且组l良好的pȝ, (zhn)只需要最低限度地了解它的全部功能, p够对它做Z?

10.当向pȝ中增加新功能? 首先的Q务就是找到实现类似特性的代码, 它作ؓ(f)待实现功能的模板.

11.从特性的功能描述C码的实现, 可以按照字符串消? 或用关键词来搜索代?

12.在移植代码或修改接口? (zhn)可以通过~译器直接定位出问题涉及(qing)的范? 从而减代码阅ȝ工作?

13.q行重构? (zhn)从一个能够正常工作的pȝ开始做? 希望保l束时系l能够正常工? 一套恰当的试用例(test case)可以帮助(zhn)满

x约?

14.阅读代码L重构Z(x)? 先从pȝ的构架开? 然后逐步l化, 能够获得最大的效益.

15.代码的可重用性是一个很׃h, 但难以理解与分离, 可以试着L_度更大一些的? 甚至其他代码.

16.在复查Y件系l时, 要注? pȝ是由很多部分l成? 不仅仅只是执行语? q要注意分析以下内容: 文g和目录结构|生成和配|过E|

用户界面和系l的文档.

18.可以Y件复查作Z个学?fn)|讲授|援之以手和接受帮助的Z(x).
&<60;&<60; &<60;

++++++++++++++++++++

W二? 基本~程元素

++++++++++++++++++++



19.W一ơ分析一个程序时, main是一个好的v始点.

20.层叠if-else if-...-else序列可以看作是由互斥选择组成的选择l构.

21.有时, 要想了解E序在某一斚w的功? q行它可能比阅读源代码更为恰?

22.在分析重要的E序? 最好首先识别出重要的组成部?

23.了解局部的命名U定, 利用它们来猜变量和函数的功能用?

24.当基于猜修改代码时, (zhn)应该设计能够验证最初假讄q程. q个q程可能包括用编译器q行(g)查|引入断言|或者执行适当的测试用?

25.理解了代码的某一部分, 可能帮助你理解余下的代码.

26.解决困难的代码要从容易的部分入手.

27.要养成遇到库元素去阅读相关文档的习(fn)? q将?x)增强(zhn)阅读和编写代码的能?

28.代码阅读有许多可选择的策? 自底向上和自向下的分析|应用试探法和(g)查注释和外部文档, 应该依据问题的需要尝试所有这些方?

29.for (i=0; i<n; i++)形式的@环执行n? 其他M形式都要心.

30.涉及(qing)两项不等试(其中一包括相{条?的比较表辑ּ可以看作是区间成员测?

31.我们l常可以表辑ּ应用在样本数据上, 借以了解它的含义.

32.使用De Morgan法则化复杂的逻辑表达?

33.在阅读逻辑乘表辑ּ? 问题可以认ؓ(f)正在分析的表辑ּ以左的表辑ּ均ؓ(f)true; 在阅读逻辑和表辑ּ? cM? 可以认ؓ(f)正在分析的表

辑ּ以左的表辑ּ均ؓ(f)false.

34.重新l织(zhn)控制的代码, 使之更ؓ(f)易读.

35.用条件运行符? :的表辑ּ理解为if代码.

36.不需要ؓ(f)了效? 牺牲代码的易L?

37.高效的算法和Ҏ(gu)的优化确实有可能使得代码更ؓ(f)复杂, 从而更隄? 但这q不意味着使代码更为紧凑和不易M(x)提高它的效率.

38.创造性的代码布局可以用来提高代码的易L?

39.我们可以使用I格|临时变量和括h高表辑ּ的易L?

40.在阅L所控制的代码时, 要养成添加注释的?fn)?

41.我们可以用好的羃q以?qing)对变量名称的明智选择, 提高~写Ơ佳的程序的易读?

42.用diffE序分析E序的修订历史时, 如果q段历史跨越了整体重新羃? 常常可以通过指定-w选项, 让diff忽略I白差异, 避免׃更改?br>
~进层次而引入的噪音.

43.do循环的@环体臛_执行一?

44.执行术q算? 当b=2n-1? 可以a&b理解为a%(b+1).

45.a<<n理解为a*k, k=2n.

46.a>>n理解为a/k, k=2n.

47.每次只分析一个控制结? 它的内容看作是一个黑?

48.每个控制结构的控制表达式看作是它所包含代码的断a.

49.return, goto, break和continue语句, q有异常, 都会(x)影响l构化的执行程. ׃q些语句一般都?x)终止或重新开始正在进行的循环,

因此要单独推理它们的行ؓ(f).

50.用复杂@环的变式和不变式, 对@环进行推?

51.使用保持含义不变的变换重新安排代? 化代码的推理工作.



+++++++++++++++++++

W三? 高C数据cd

+++++++++++++++++++



52.了解特定语言构造所服务的功能之? p够更好地理解使用它们的代?

53.识别q归cM用指针的理由.

54.在CE序? 指针一般用来构造链式数据结构|动态分配的数据l构|实现引用调用|讉K和P代数据元素|传递数l参数|引用函数|作ؓ(f)其他

值的别名|代表字符串|以及(qing)直接讉Kpȝ内存.

55.以引用传递的参数可以用来q回函数的结? 或者避免参数复制带来的开销.

56.指向数组元素地址的指? 可以讉K位于特定索引位置的元?

57.指向数组元素的指针和相应的数l烦(ch)? 作用在二者上的运具有相同的语义.

58.使用全局或static局部变量的函数大多数情况都不可重入(reentrant).

59.字符指针不同于字W数l?

60.识别和归cd用结构或q体的每种理由.

61.C语言中的l构多个数据元素集合在一? 使得它们可以作ؓ(f)一个整体来使用, 用来从函Cq回多个数据元素|构造链式数据结构|映射

数据在硬件设备||络链接和存储介质上的组l方式|实现抽象数据cd|以及(qing)以面向对象的方式~程.

62.q体在CE序中主要用于优化存储空间的利用|实现多态|以及(qing)讉K数据不同的内部表达方?

63.一个指? 在初始化为指向N个元素的存储I间之后, 可以作为N个元素的数组来?

64.动态分配的内在块可以电(sh)焊工地释? 或在E序l束旉? 或由垃圾回收器来完成回收; 在栈上分配的内存块当分配它的函数退出后释放

.

65.CE序使用typedef声明促进抽象, q增Z码的易读? 从而防范可UL性问? q模拟C++和Java的类声明行ؓ(f).

66.可以typedef声明理解成变量定? 变量的名U就是类型的名称; 变量的类型就是与该名U对应的cd.
&<60;&<60;&<60;



&<60;
+++++++++++++++

W四? C数据l构

+++++++++++++++



67.Ҏ(gu)底层的抽象数据类型理解显式的数据l构操作.

68.C语言? 一般用内建的数组cd实现向量, 不再对底层实现进行抽?

69.N个元素的数组可以被序列for (i=0; i<N; i++)完全处理; 所有其他变体都应该引v警惕.

70.表达式sizeof(x)M(x)得到用memset或memcpy处理数组x(不是指针)所需的正字节数.

71.区间一般用区间内的W一个元素和区间后的W一个元素来表示.

72.不对U区间中元素的数目等于高位边界与低位边界的差.

73.当不对称区间的高位边界等于低位边界时, 区间为空.

74.不对U区间中的低位边界代表区间的W一个元? 高位边界代表区间外的W一个元?

75.l构的数l常常表C由记录和字D늻成的?

76.指向l构的指针常常表C问底层记录和字段的游?

77.动态分配的矩阵一般存储ؓ(f)指向数组列的指针或指向元素指针的指针; q两U类型都可以按照二维数组q行讉K.

78.以数lŞ式存储的动态分配矩? 用自定义讉K函数定位它们的元?

79.抽象数据cd为底层实现元素的使用(或误?方式提供一U信心的量度.

80.数组用从0开始的序整数为键, l织查找?

81.数组l常用来Ҏ(gu)制结构进行高效编? 化程序的逻辑.

82.通过在数l中每个位置存储一个数据元素和一个函数指?指向处理数据元素的函?, 可以代码与数据兌h.

83.数组可以通过存储供程序内的抽象机(abstract machine)或虚拟机(virtual machine)使用的数据或代码, 控制E序的运?

84.可以表辑ּsizeof(x) / sizeof(x[0])理解为数lx中元素的个数.

85.如果l构中含有指向结构自w|名ؓ(f)next的元? 一般说? 该结构定义的是单向链表的l点.

86.指向链表l点的持久?如全局|静态或在堆上分?指针常常表示链表的头?

87.包含指向自n的next和prev指针的结构可能是双向链表的结?

88.理解复杂数据l构的指针操作可以将数据元素Mؓ(f)Ҏ(gu)|指针Mؓ(f)头.

89.递归数据l构l常用递归法来处?

90.重要的数据结构操作算法一般用函数参数或模板参数来参数?

91.囄l点常常序地存储在数组? 链接到链表中, 或通过囄辚w接v?

92.图中的边一般不是隐式地通过指针, 是昑ּC为独立的l构来表C?

93.囄边经常存储ؓ(f)动态分配的数组或链? 在这两种情况? 辚w锚定在图的结点上.

94.在无向图? 表达数据时应该将所有的l点看作是等同的, cM? q行处理d的代码也不应该基于它们的方向来区分边.

95.在非q通图? 执行遍历代码应该能够接通孤立的子图.

96.处理包含回\的图? 遍历代码应该避免在处理图的回路进入@?

97.复杂的图l构? 可能隐藏着其他cd的独立结?



+++++++++++++++++

W五? 高控制程

+++++++++++++++++



98.采用递归定义的算法和数据l构l常用递归的函数定义来实现.

99.推理递归函数? 要从基准落伍试开? q认证每ơ递归调用如何逐渐接近非递归基准范例代码.

100.单的语言常常使用一pd遵@该语a语法l构的函数进行语法分?

101.推理互递归函数? 要基于底层概늚递归定义.

102.N归调用{同于一个回到函数开始处的@?

103.throws子句从方法的定义中移? 然后q行Java~译器对cȝ源代码进行编? 可以容易地扑ֈ那些可能隐式地生成异常的Ҏ(gu).

104.在多处理器计机上运行的代码常常围绕q程或线E进行组l?

105.工作ƈ行模型用于在多个处理器间分配工作, 或者创Z个Q务池, 然后大量需要处理标准化的工作进行分?

106.ZU程的管理?工hq行模型一般将耗时的或d的操作分配给工h子Q? 从而维护中心Q务的响应?

107.Zq程的管理?工hq行模型一般用来重用现有的E序, 或用定义良好的接口组l和分离_粒度的pȝ模块.

108.Z水U的q行处理? 每个d都接收到一些输? 对它们进行一些处? q将生成的输Z递给下一个Q? q行不同的处?

109.竞争条g很难捉摸, 相关的代码常怼(x)竞争条件扩散到多个函数或模? 因? 很难隔离׃竞争条gD的问?

110.对于出现在信号处理器中的数据l构操作代码和库调用要保持高度警?

111.在阅d含宏的代码时, 要注? 宏既非函? 也非语句.

112.do…while(0)块中的宏{同于控制块中的语句.

113.宏可以访问在它的使用点可见的所有局部变?

114.宏调用可改变参数的?br>
115.Z宏的标记拼接能够创徏新的标记W?
&<60;&<60;&<60;


+++++++++++++++++

W六? 应对大型目

+++++++++++++++++



116.我们可以通过览目的源代码?wi)—包含项目源代码的层ơ目录结? 来分析一个项目的l织方式. 源码?wi)常常能够反映出目在构架?br>
软gq程上的l构.

117.应用E序的源代码?wi)经常是该应用程序的部vl构的镜?

118.不要被庞大的源代码集合吓? 它们一般比型的专门项目组l得更出?

119.当?zhn)首次接触一个大型项目时, 要花一些时间来熟?zhn)目的目录?wi)l构.

120.目的源代码q不只是~译后可以获得可执行E序的计机语言指o(h); 一个项目的源码?wi)一般还包括规格说明|最l用户和开发h员文档|

试脚本|多媒体资源|~译工具|例子|本地化文件|修订历史|安装q程和许可信?

121.大型目的编译过E一般声明性地借助依赖关系来说? 依赖关系由工L(fng)? 如make?qing)其zE序, 转换成具体的~译行动.

122.大型目? 制作文g常常由配|步骤动态地生成; 在分析制作文件之? 需要先执行目特定的配|?

123.(g)查大型编译过E的各个步骤? 可以使用makeE序?n开兌行预?

124.修订控制pȝ提供从储存库中获取源代码最新版本的方式.

125.可以使用相关的命? 昄可执行文件中的修订标识关键字, 从而将可执行文件与它的源代码匹配v?

126.使用修订日志中出现的bug跟踪pȝ内的~号, 可以在bug跟踪pȝ的数据库中找到有关的问题的说?

127.可以使用修订控制pȝ的版本储存库, 扑և特定的变更是如何实现?

128.定制~译工具用在软g开发过E的许多斚w, 包括配置|~译q程理|代码的生成|试和文档编?

129.E序的调试输出可以帮助我们理解程序控制流E和数据元素的关键部?

130.跟踪语句所在的地点一般也是算法运行的重要部分.

131.可以用断a来检验算法运作的步骤|函数接收的参数|E序的控制流E|底层g的属性和试用例的结?

132.可以使用对算法进行检验的断言来证实?zhn)对算法运作的理? 或将它作为推理的L(fng).

133.对函数参数和l果的断al常记录了函数的前置条g和后|条?

134.我们可以测试整个函数的断言作ؓ(f)每个l定函数的规D?

135.试用例可以部分C替函数规D?

136.可以使用试用例的输入数据对源代码序列进行预?



+++++++++++++++++++

W七? ~码规范和约?br>
+++++++++++++++++++



137.了解了给定代码库所遵@的文件组l方式后, p更有效率地浏览它的源代码.

138.阅读代码? 首先要确保?zhn)的编辑器或优打印程序的tab讄, 与代码遵循的风格规范一?

139.可以使用代码块的~进, 快速地掌握代码的Ml构.

140.对编排不一致的代码, 应该立即l予_的警?

141.分析代码? Ҏ(gu)Cؓ(f)XXX, FIXME和TODO的代码序列要格外注意: 错误可能潜伏在其中.

142.帔R使用大写字母命名, 单词用下划线分隔.

143.在遵循Java~码规范的程序中, 包名(package name)L从一个顶U的域名开?例如, org, com), cd和接口名由大写字母开? Ҏ(gu)

和变量名由小写字母开?

144.用户界面控g名称之前的匈牙利记法的前~cd标记可以帮助我们定它的作用.

145.不同的编E规范对可移植构造的构成有不同的d.

146.在审查代码的可移植? 或以某种l定的编码规范作为指南时, 要注意了解规范对可移植性需求的界定与限?

147.如果GUI功能都用相应的~程l构来实? 则通过代码审查可以L地验证给定用L(fng)面的规格说明是否被正地采用.

148.了解目~译q程的组l方式与自动化方式之? 我们p够快速地阅读与理解对应的~译规则.

149.当检查系l的发布q程? 常常可以相应发行格式的需求作为基?

&<60;
&<60;
++++++++++++

W八章:(x) 文档

++++++++++++



150.阅读代码? 应该可能地利用M能够得到的文?

151.阅读一时代码所得到的信息只不过相当于阅M分钟文档.

152.使用pȝ的规D明文? 了解所阅读代码的运行环?

153.软g需求规D明是阅读和评C码的基准.

154.可以系l的设计规格说明作ؓ(f)认知代码l构的\U图, 阅读具体代码的指?

155.试规格说明文档为我们提供可以用来对代码q行预演的数?

156.在接触一个未知系l时, 功能性的描述和用h南可以提供重要的背景信息,从而更好地理解阅读的代码所处的上下?

157.从用户参考手册中, 我们可以快速地获取, 应用E序在外观与逻辑上的背景知识, 从管理员手册中可以得知代码的接口|文g格式和错误消

息的详细信息.

158.利用文档可以快捷地获取系l的概况, 了解提供特定Ҏ(gu)的代码.

159.文档l常能够反映和提C出pȝ的底层结?

160.文档有助于理解复杂的法和数据结?

161.法的文字描q能够不透明(晦ӆ, 难以理解)的代码变得可以理?

162.文档常常能够阐明源代码中标识W的含义.

163.文档能够提供非功能性需求背后的理论基础.

164.文档q会(x)说明内部~程接口.

165.׃文档很少像实际的E序代码那样q行试, q受人关? 所以它常常可能存在错误|不完整或q时.

166.文档也提供测试用? 以及(qing)实际应用的例?

167.文档常常q会(x)包括已知的实现问题或bug.

168.环境中已知的~点一般都?x)记录在源代码?

169.文档的变更能够标出那些故障点.

170.对同一D|代码重复或互相冲H的更改, 常常表示存在Ҏ(gu)性的设计~陷, 从而得维护h员需要用一pd的修补程序来修复.

171.怼的修复应用到源代码的不同部分, 常常表示一U易犯的错误或疏? 它们同样可能?x)在其他地方存?

172.文档常常?x)提供不恰当的信? 误导我们Ҏ(gu)代码的理?

173.要警惕那些未归档的特? 每个实例归cMؓ(f)合理|疏忽或有? 相应地决定是否应该修复代码或文档.

174.有时, 文档在描q系l时, q按照已完成的实现, 而是pȝ应该的样子或来的实?

175.在源代码文档? 单词gork的意思一般是?#8221;理解”.

176.如果未知的或Ҏ(gu)用法的单词阻了对代码的理解, 可以试着在文档的术语?如果存在的话)|New Hacker’s Dictionary[Ray96]|或在

Web搜烦(ch)引擎中查扑֮?

177.L要以批判的态度来看待文? 注意非传l的来源, 比如注释|标准|出版物|试用例|邮g列表|新闻l|修订日志|问题跟踪数据库|?br>
销材料|源代码本w?

178.L要以批判的态度来看待文? ׃文档永远不会(x)执行, Ҏ(gu)档的试和正式复查也很少辑ֈ对代码的同样水^, 所以文档常怼(x)误导

读? 或者完全错?

179.对于那些有缺L(fng)代码, 我们可以从中推断出它的真实意?

180.在阅d型系l的文档? 首先要熟(zhn)文档的Ml构和约?

181.在对付体U庞大的文档? 可以使用工具, 或将文本输出到高品质输出讑֤? 比如Ȁ光打印机, 来提高阅ȝ效率.



++++++++++++++

W九(ji)? pȝ构架

++++++++++++++



182.一个系l可?在重大的pȝ中也实如此)同时出多U不同的构架cd. 以不同的方式(g)查同一pȝ|分析pȝ的不同部分|或用不同

别的分解, 都有可能发现不同的构架类?

183.协同式的应用E序, 或者需要协同访问共享信息或资源的半自治q程, 一般会(x)采用集中式储存库构架.

184.黑板pȝ使用集中式的储存? 存储非结构化的键/值对, 作ؓ(f)大量不同代码元g之间的通信集线?

185.当处理过E可以徏模|设计和实现成一pd的数据变换时, 常常?x)用数据?或管道—过滤器)构架.

186.在批量进行自动数据处理的环境? l常?x)采用数据流构? 在对数据工具提供大量支持的^C其如此.

187.数据构架的一个明昑־兆是: E序中用(f)时文件或水U?pipeline)在不同进E间q行通信.

188.使用囄来徏模面向对象构架中cȝ关系.

189.可以源代码输入到徏模工具中, 逆向推导出系l的构架.

190.拥有大量同子系l的pȝ, 常常按照分层构架q行l织.

191.分层构架一般通过堆叠拥有标准化接口的软glg来实?

192.pȝ中每个层可以下面的层看作抽象实? q且(只要该层满它的需求说?不关心上面的层如何用它.

193.层的接口既可以是支持特定概念的互补函数族, 也可以是一pd支持同一抽象接口不同底层实现的可互换函数.

194.用C语言实现的系l? 常常用函数指针的数组, 表达层接口的多\复用操作.

195.用面向对象的语言实现的系l? 使用虚方法调用直接表辑֯层接口的多嘴复用操作.

196.pȝ可以使用不同的|独特的层ơ分解模型跨各种坐标轴进行组l?

197.使用E序切片技? 可以程序中的数据和控制之间依赖关系集中C?

198.在ƈ发系l中, 一个单独的pȝlg起到集中式管理器的作? 负责启动|停止和协调其他系l进E和d的执?

199.许多现实的系l都?x)博采众家之? 当处理此cȝl时, 不要徒劳地寻找无所不包的构架图; 应该不同构枉g为独立但相关的实?br>
来进行定位|识别q了?

200.状态变q图常常有助于理清状态机的动?

201.在处理大量的代码? 了解代码分解成单独单元的机制极为重?

202.大多数情况下, 模块的物理边界是单个文g|l织C个目录中的多个文件或拥有l一前缀的文件的集合.

203.C中的模块, 由提供模块公开接口的头文g和提供对应实现的源文件组?

204.对象的构造函数经常用来分配与对象相关的资? q初始化对象的状? 函数一般用来释攑֯象在生命期中占用的资?

205.对象Ҏ(gu)l常使用cdD|存储控制所有方法运作的数据(比如查找表或字典)或维护类q作的状态信?例如, 赋给每个对象一个标识符?br>
计数?.

206.在设计良好的cM, 所有的字段都应在声明ؓ(f)private, q用公开的访问方法提供对它们的访?

207.在遇到friend声明? 要停下来分析一? 看看l过cd装在设计上的理由.

208.可以有节制地用运符增强特定cȝ可用? 但用q算W重? 类实现为拥有内建算术类型相关的全部功能的类实体, 是不恰当?

209.泛型实现不是在编译期间通过宏替换或语言所支持的功?比如C++模板和Ada的泛型包)来实? 是在运行期间通过使用数据元素的指?br>
和函数的指针|或对象的多态性实?

210.抽象数据cdl常用来装常用的数据组l方?比如?wi)|列表或栈), 或者对用户隐藏数据cd的实现细?

211.使用库的目的多种多样: 重用源代码或目标代码, l织模块集合, l织和优化编译过E? 或是用来实现应用E序各种Ҏ(gu)的按需载入.

212.大型的|分布式的pȝl常实现多互相协作的q程.

213.对于Z文本的数据储存库, 可以通过览存储在其中的数据, 破译出它的结?

214.可以通过查询数据字典中的? 或用数据库专有的SQL命o(h), 比如show table, 来分析关pd数据库的模式.

215.识别出重用的构架元素? 可以查找其最初的描述, 了解正确C用这U构架的方式, 以及(qing)可能出现的误?

216.要详l分析徏立在某种框架之上的应用程? 行动的最佌\U就是从研究框架自n开?

217.在阅d导生成的代码? 不要期望太高, 否则(zhn)会(x)感到失望.

218.学习(fn)几个基本的设计模式之? (zhn)会(x)发现, (zhn)查看代码构架的方式?x)发生改? (zhn)的视野和词汇将?x)扩展到能够识别和描q许多通用的Ş

?

219.频繁使用的一些模? 但ƈ不显式地指出它们的名U? q是׃构架性设计的重用l常先于模式的Ş?

220.误着按照底层模式来理解构? 即代码中ƈ没有明确地提?qing)模?

221.大多数解释器都遵循类似的处理构架, 围绕一个状态机q行构徏, 状态机的操作依赖于解释器的当前状态|E序指o(h)和程序状?

222.多数情况? 参考构架只是ؓ(f)应用E序域指定一U概忉|的l构, 具体的实现ƈ非必遵照这U结?


+++++++++++++++++

W十? 代码阅读工具

+++++++++++++++++



223.词汇工具可以高效地在一个大代码文g中或者跨多个文g查找某种模式.

224.使用E序~辑器和正则表达式查扑֑? 览庞大的源代码文g.

225.以只L式浏览源代码文g.

226.使用正则表达?^function name 可以扑և函数的定?

227.使用正则表达式的字符c? 可以查找名称遵@特定模式的变?

228.使用正则表达式的否定字符c? 可以避免非积极匹?

229.使用正则表达?symbol-1. *symbol-2, 可以查找出现在同一行的W号.

230.使用~辑器的 tags 功能, 可以快速地扑և实体的定?

231.可以用特定的 tag 创徏工具, 增加~辑器的览功能.

232.使用~辑器的大纲视图, 可以获得源代码结构的鸟瞰?

233.使用(zhn)的~辑器来(g)源代码中圆括号|Ҏ(gu)号和花括L(fng)匚w.

234.使用 grep 跨多个文件查找代码模?

235.使用 grep 定位W号的声明|定义和应?

236.当?zhn)不能_地表q要查找的内Ҏ(gu), 请用关键单词的词干对程序的源代码进行查?

237.?grep qo(h)其他工具生成的输? 分离出?zhn)要查扄?

238.?grep 的输送到其他工具, 使复杂处理Q务自动化.

239.通过?grep 的输行流~辑, 重用代码查找的结?

240.通过选取与噪x式不匚w的输(grep-v), qo(h)虚假?grep 输出.

241.使用 fgrep 在源代码中查扑֭W串列表.

242.查找注释, 或标识符大小写不敏感的语a~写的代码时, 要用大写不敏感的模式匚w(grep -i).

243.使用 grep –n 命o(h)行开? 可以创徏与给定正则表辑ּ匚w的文件和行号的检查表.

244.可以使用 diff 比较文g或程序不同版本之间的差别.

245.在运?diff 命o(h)? 可以使用 diff –b, 使文件比较算法忽略结I格, ?–w 忽略所有空白区域的差异, ?–i 使文件比较对?br>
写不敏?

246.不要对创q代码阅读工具心存畏惧.

247.在构q代码阅读工具? 要充分利用现代快速原型语a所提供的能? 从简单开? Ҏ(gu)需要逐渐改进; 使用利用代码词汇l构?br>
各种试探? 要允怸些输出噪x寂静(无关输出或缺p?; 使用其他工具对输入进行预处理, 或者对输出q行后期处理.

248.要ɾ~译器成为?zhn)? 指定恰当U别的编译器警告, q小心地评估生成的结?

249.使用C预处理器理清那些滥用预处理器Ҏ(gu)的E序.

250.要彻底地了解~译器如何处理特定的代码? 需要查看生成的W号(汇编)代码.

251.通过分析相应目标文g中的W号, 可以清晰C解源文g的输入和输出.

252.使用源代码浏览器览大型的代码集合以?qing)对象类?

253.要抵制住按照(zhn)的~码规范对外部代码进行美化的诱惑; 不必要的~排更改?x)创Z同的代码, q妨工作的l织.

254.优美打印E序和编辑器语法着色可以得程序的源代码ؓ(f)易读.

255.cdecl E序可以难以理解的C和C++cd声明转换成纯p(反之亦然).

256.实际q行E序, 往往可以更深d理解E序的动?

257.pȝ调用|事g和数据包跟踪E序可以增进对程序动作的理解.

258.执行剖析器可以找出需要着重优化的代码, 验证输入数据的覆盖? 以及(qing)分析法的动?

259.通过(g)查从未执行的代码? 可以扑և试覆盖的弱? q据此修正测试数?

260.要探I程序动态动作时的每个细? 需要在调试器中q作?

261.?zhn)觉得难以理解的代码打印到U怸.

262.可以l制囄来描l代码的动作.

263.可以试着向别Zl?zhn)在阅ȝ代? q样做一般会(x)增进(zhn)对代码的理?

264.理解复杂的算法或巧妙的数据结? 要选择一个安静的环境, 然后聚精?x)神地考虑, 不要借助于Q何计机化或自动化的帮助.



+++++++++++++++++++++

W十一? 一个完整的例子

+++++++++++++++++++++



265.模仿软g的功能时, 要依照相似实体的U\(c|函数|模块). 在相似的现有实体? 为简化对源代码库的文本查? 应选取比较|见的名

U?

266.自动生成的文件常怼(x)在文件的开x一D|? 说明q种情况.

267.如果试图_地分析代? 一般会(x)陷入数量众多的类|文g和模块中, q些内容?x)很快将我们?gu); 因此, 我们必须需要理解的代码限定

在绝对必需的范围之?

268.采用一U广度优先查扄? 从多Ҏ(gu)克代码阅M存在的问? q到扑և克服它们的方法ؓ(f)?



morphis 2007-06-14 23:05 发表评论
]]>
【ZZ】永q不要因为工作不好而辞?/title><link>http://www.aygfsteel.com/morphis/archive/2007/06/10/123172.html</link><dc:creator>morphis</dc:creator><author>morphis</author><pubDate>Sun, 10 Jun 2007 04:36:00 GMT</pubDate><guid>http://www.aygfsteel.com/morphis/archive/2007/06/10/123172.html</guid><wfw:comment>http://www.aygfsteel.com/morphis/comments/123172.html</wfw:comment><comments>http://www.aygfsteel.com/morphis/archive/2007/06/10/123172.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/morphis/comments/commentRss/123172.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/morphis/services/trackbacks/123172.html</trackback:ping><description><![CDATA[<p><font color=#ffff00>永远不要因ؓ(f)q个工作不好而辞职。一定要因ؓ(f)另一个工作更好而辞职?/font> </p> <p><font color=#ffff00>    人所拥有的「最后的」(lastQ自由是Q我们可以选择我们的态度?/font> <p>    有一位老hQ独自住在家里。他的儿奌回来照他。后来觉得最好还是住到老h院去比较好,因ؓ(f)他的眼睛已经完全看不见了?nbsp;<br><br>    q入老h院的那一天,服务员牵着他的手告诉他Q房间的样子Q墙上的壁画Q窗户外面是一大片草地Q还有水池,q位老h回答_(d)真的好美Q我x在这里会(x)很开心。服务员瞪着他,一脸讶异的_(d)你什么都看不见,你怎么知道不呢Q?nbsp;<br> <br>    讲到q里Q你大概已经知道q故事想要说的是什么了Q?nbsp;<br><br>    我们比那位老h的情况好多了。我们每天早上v来的时候有没有q么振奋Q这么积极? <br><br>    办公室里的事好像永远都做不完。烦(ch)恼的事不知道Z么L那么多。房子、R子、小孩的学业Q今天的早饭该吃什么,q些事从未间断过Q就待会(x)儿出门,从R子开出去到抵辑ց车场Q至会(x)发三ơ火Q有人换车道没打信号灯;某段路塞车因为有人在路边q排停RQ再有就是ؕ按喇叭?nbsp;<br><br>    惛_q里Q怪不得我们真的要做一选择。选择今天我要扑ֈ好的事Q还是要专注于烦(ch)恼的事。我们要选择感恩、宽容,抑或是要让抱怨、愤怒来折磨我。我们甚臛_以在今天选择兛_他hQ对他h感兴的Z(x)Q而不要让h?fn)惯性的在心头?nbsp;<br><br>    30q前Q我对当时的工作非常不满Q时常抱怨,也多ơ口头叫嚯辞职。有一天一位其它部门的q长ȝ跟我_(d)永远不要因ؓ(f)q个工作不好而辞职,一定要因ؓ(f)另一个工作更好而辞职?br> <br>    q二句话Ҏ(gu)很重要。媄(jing)响也很大。卅q后的今天,回想hQ他说的真的很有道理?nbsp;<br><br>    现在的公司制度不好,下一个工作机构的体制多半也有~陷。现在的公司不公qI谁能保证新的公司一切都很合理公道。现在的公司有派p,天知道多公司有同样的权力斗争问题。跟现在的主处不好Q新工作的主就一定处得好吗? <br><br>    因而换工作不是解决办法?br> <br>    Ҏ(gu)的办法是改变态度。曾在集中营里住q,遭受qhcL(zhn)惨的折的奥地利心理学家Victor Frankelp为,人所拥有的「最后的」(lastQ自由是Q我们可以选择我们的态度。遭遇同L(fng)打击Q有的h选择的是l望Q有的h却选择了希望?nbsp;<br><br>    朋友Q你选择的是什么?你准备怎样q这一天?</p> <img src ="http://www.aygfsteel.com/morphis/aggbug/123172.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/morphis/" target="_blank">morphis</a> 2007-06-10 12:36 <a href="http://www.aygfsteel.com/morphis/archive/2007/06/10/123172.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>35岁以前需要做的十件事http://www.aygfsteel.com/morphis/archive/2007/06/10/123170.htmlmorphismorphisSun, 10 Jun 2007 04:26:00 GMThttp://www.aygfsteel.com/morphis/archive/2007/06/10/123170.htmlhttp://www.aygfsteel.com/morphis/comments/123170.htmlhttp://www.aygfsteel.com/morphis/archive/2007/06/10/123170.html#Feedback1http://www.aygfsteel.com/morphis/comments/commentRss/123170.htmlhttp://www.aygfsteel.com/morphis/services/trackbacks/123170.html35岁是青春的后期,35岁以后是收获的季节,如果你没有资Dq句话,你将?x)憎恨自己。所以在35岁以前,在烂漫蓬勃的青春q华里,你最好把下面十g事做好:(x)
  
  W一Q学?x)本行业所需要的一切知识ƈ有所发展。已故零件大王布鲁丹在他35岁时Q已l成为零件行业的领袖Qƈ且组Zq收入达千万元的v湾与襉K工业公司。每个h在年L都可能有q彻夜不眠、刻苦攻读,q在20岁甚?0岁都没有问题Q但C35岁,׃应该再ؓ(f)学习(fn)基本技能而大伤脑{了?5岁之前是一个h从事原始U篏的阶D,35岁之后就应该勃发了?
  
  W二Q养成个人风根{在35岁以前,扑և你所喜欢的,不论是衣着或是爱好Q哪怕是与众不同的小?fn)惯也好?0岁?0岁时你可以不断尝试、不断改变,但是C35岁,你便要明地建立个h风格。一位男士或奛_在事业中途改变自q形象Q就?x)让得很不可靠。你喜欢I西装吗Q好Q就把西装当作你的商标吧Q办公桌上摆些鲜׃(x)令你工作更有效率吗?那就每天都摆些鲜花吧Q?
  
  W三Q在感情生活斚wq_安定。在攀M业的高峰Ӟ如果Uh生活不愉快,陷入感情危机Q对你会(x)产生很大的干扎ͼ甚至?x)逐渐令你对别的事物失d。那些在35岁之前私人生zdl^和安定的人,一般都比生zd荡不安的人有更大的机?x)获得成功。因此,如果你想l束一D|有结果的恋情Q或者你惛_奛_l婚Q那p快行动吧Q免得把问题拖到生命的第35个春U。在35岁以后,你应该专注地看着你对事业的投资开始获利?
  
  W四Q明白自q短处。承认有些事情你的确做不好,或者不愿做。如果你讨厌数字而喜Ƣ创作,那就不要因ؓ(f)待遇高或Z别h的期望而强q自己做数字工作。在35岁之前,一定要投入你所喜爱、所擅长的那U工作。否则,35岁之后必然会(x)有一D郁郁不乐的曰子。而且Q真正的成功可能因ؓ(f)zd的消退而失?
  
  W五Q知道自q长处。你应该知道自己擅长什么,q且清楚你所喜欢做而又做得比别人好的事情。不你目前担Q什么样的角Ԍ知道自己的长处对成功都很重要?
  
  W六Q储备辞职另谋生路的钱。在q个多变的职业世界里Q你也许不会(x)永远在一个地方工作,或者永q在一个位|上淋漓致地发挥自己,当你感到无法施展Ӟ你很可能?x)想到辞职,或者开辟第二职业,如果你事先储蓄了_的钱Q你便有了一个安全的后盾?
  
  W七Q徏立h际关pȝ。如果到?5岁你仍未建立L(fng)固的人际关系|,那你有ȝ(ch)了。这个h际关pȝ包括你的朋友、亲人,最低限度包括所有可以互相帮助的人。这些h有的是你的同事,有的受过你的恩惠Q有的你們֐q他们的问题Q有的你和他有着相同的爱好。h际关pȝ不是一朝一夕就能徏立v来的Q它需要几q甚臛_几年的培充R一个h在事业上、生zM的成功其实如同一个政党的成功Q你要有许多人散布在适当的地方,你可以依赖他们,他们也可以依赖你?
  
  W八Q学?x)授权他人。许多h不肯或不能这样做Q因此始l被钉在从属的职位上。授权他人是成功的一半,一个事无巨l,不能工作授权别人的人,注定?x)遇到极大的障碍。到?5岁,你最好已成ؓ(f)q方面的专家。换a之,你懂得挑选合适的人ƈ信Q他们?
  
  W九(ji)Q学?x)在什么时候三~其口。因说话不小心而自毁前E的人,比因ZQ何其他原因失成功的人都多。要学会(x)保持沉默而且看v来机?-别h自然以ؓ(f)你知道的比实际还多。别讲别人的闲话Q别谈论你自q大计Q守口如瓶所赢得的声誉,q比讲h闲话所带来的东西更加珍c(din)你在事业上成功,q一点就重要?
  
  W十Q对忠诚。如果你C35岁仍未能建立起坚如磐石的忠诚信誉Q这一~点会(x)困扰你一生。不忠诚的恶名必然会(x)使你在事业上到处不受Ƣ迎。你不能靠暗伤人爬C业的峰Q而要靠在早期?wi)立h的真诚刚直和不可动摇的声誉?5岁以前,忠诚只是投资Q?5岁以后,你会(x)作ؓ(f)一个可以信赖的人收到忠诚的回报?



morphis 2007-06-10 12:26 发表评论
]]>
【{贴】泛型算法:(x)Tips http://www.aygfsteel.com/morphis/archive/2007/06/06/122292.htmlmorphismorphisWed, 06 Jun 2007 01:37:00 GMThttp://www.aygfsteel.com/morphis/archive/2007/06/06/122292.htmlhttp://www.aygfsteel.com/morphis/comments/122292.htmlhttp://www.aygfsteel.com/morphis/archive/2007/06/06/122292.html#Feedback0http://www.aygfsteel.com/morphis/comments/commentRss/122292.htmlhttp://www.aygfsteel.com/morphis/services/trackbacks/122292.html
?STL 出现到现在已l这么多q了Q泛型算法是它的重要l成Q也是其中最“看v来很?#8221;的东西之一。然而在真实的程序设计中Q它往往成ؓ(f)E序员的心头一痛,因ؓ(f)一旦要?for_each Qaccumulate 之类的算法做一些稍微复杂一点的事情Q你׃(x)发现自己一个头变成两个大?/p>

?STL 出现到现在已l这么多q了Q泛型算法是它的重要l成Q也是其中最“看v来很?#8221;的东西之一。然而在真实的程序设计中Q它往往成ؓ(f)E序员的心头一痛,因ؓ(f)一旦要?for_each Qaccumulate 之类的算法做一些稍微复杂一点的事情Q你׃(x)发现自己一个头变成两个大。即便是有了 boost::bind ?boost.lambda 的帮助,事情也仍然是扑朔qL(fng)Q求助于 comp.lang.c++ 虽然有用Q但是又何尝不是一U无奈。好了,现在我开始收集一些来?comp.lang.c++(.moderated) 的解{,希望日后对自己和他h有用?/p>

=================================================================================

预备问题Q算是第0个问题吧Q:(x)如何对一?STL 容器内的所有元素做某g事情Q?/p>

q取决于你要做什么,以及(qing)容器是什么。如果是 vector, list q样的容器,而你要把它们全部 cout 出来Q当前的标准 STL 解法是这L(fng)Q?/p>

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <string>

int main()
{
  std::vector<std::string> vect;
  vect.push_back("Hello");
  vect.push_back(", ");
  vect.push_back("world!");
 
  std::copy( vect.begin(), vect.end(),
    std::ostream_iterator<std::string>(std::cout) );
}

基本上,q算是一?#8220;q得?#8221;的方案,但是有点问题Q?br>1. 对于不熟(zhn)这个固定用法的人,cout 所有元素所首要考虑法?for_eachQ而不?copy Q事实上Qfor_each 也是最W合我们惯常逻辑的算法,因ؓ(f)在不使用 STL 法的时候,我们使用 for 循环来干qg事?br>2. 可读性不太良好,ostream_iterator 的用有?tricky Q而且也不能用于做其他的事情?/p>

我想熟?zhn)?boost  的h已经知道我下面要说什么了Q因为用 boost.lambda 做这件事情的非常漂亮:(x)

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;

int main()
{
  std::vector<std::string> vect;
  vect.push_back("Hello");
  vect.push_back(", ");
  vect.push_back("world!");
 
  std::for_each( vect.begin(), vect.end(), std::cout << _1 );
}

q和前面的程序一P输出我们熟?zhn)?Hello, world! 。直观、优雅而且Ҏ(gu)修改Q例如,如果你不是想要输出它们的|而是惌输出它们的长度,只需要做很少的修改:(x)

std::for_each( vect.begin(), vect.end(), std::cout << bind(&std::string::length, _1) << "\n" );

输出
5
2
6

bind 的作用是?lambda 表达式绑定到一个函数或者一个数据成员,在这里的意思,是对于每一?string Q都调用?length() Ҏ(gu)。_1 同样也可以成值的对象Q例如,先执?/p>

std::for_each( vect[0].begin(), vect[0].end(), _1 = bind(&toupper, _1) );

然后再把q些 string 输出Q你?x)得?/p>

HELLO, world!

因ؓ(f)那一句对 "Hello" 中的每一个字母调?toupper Qƈ把结果写回?/p>

=================================================================================

W一个问题:(x)如何对一?map 中所有的 key 或?value 做某件事情?

当然Q这q是取决于你要做的是什么。手?for 循环当然是万能的Q但是现在有了那么多的泛型算法,我们可以考虑其他的方案了Q这也是众多 C++ Gurus 推荐的思维方式Q如果是把所有的 value 全部 cout 出来Q用 boost.lambda 配合 for_each q是比较优雅的(虽然没有?vector ?list 那样的优雅)(j)Q?/p>

#include <iostream>
#include <algorithm>
#include <map>
#include <string>

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;

int main()
{
  std::map<int, std::string> strs;
  strs[0] = "Hello";
  strs[1] = ", ";
  strs[2] = "world";
  strs[3] = "!";
 
  std::for_each( strs.begin(), strs.end(),
    std::cout << bind(&std::map<int, std::string>::value_type::second, _1) );
}

q样的输出如我们所料,是 Hello, world! ?/p>

如果惌?key 也输出,道理是一L(fng)Q只需要这P(x)

  std::for_each( strs.begin(), strs.end(),
    std::cout << bind(&std::map<int, std::string>::value_type::second, _1) << '\t'
                    << bind(&std::map<int, std::string>::value_type::first, _1) << '\n'
  );

其结果是Q?/p>

Hello   0
,            1
world   2
!            3

因此Q对于一?map 中的 value 的操作往往可以依法炮制Q如果我们想要在其中L value ?“world" 的那一个元素,q且输出它的 key Q只需要一句话Q?/p>

  std::cout <<
    std::find_if( strs.begin(), strs.end(),
      bind(&std::map<int, std::string>::value_type::second, _1) == "world" )->first;

STL 法 find_if 接受的第三个参数是一?prediate Q而生成这U(f)时的 functor 正是 lambda 的拿手好戏。上面的q句话也可以?boost::bind 来做Q只需要更?include ?using namespace Q代码本w无需更改。而如果你不借助于它们,你只有手写@环或者自己写一?predicate ?/p>

当情况变得复杂一些的时候,lambda 的用法也变得更加有趣了:(x)

#include <iostream>
#include <algorithm>
#include <map>
#include <string>

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;

class Person
{
public:
  Person(){}
  Person(const std::string& name) : name_(name){}
 
  std::string Name()
  { return name_; }
 
private:
  std::string name_;
};

int main()
{
  std::map<int, Person> persons;
  persons[123] = Person("Amy");
  persons[234] = Person("Ralph");
  persons[345] = Person("Simon");
  persons[456] = Person("Maggie");

  std::for_each( persons.begin(), persons.end(),
    std::cout << bind(&std::map<int, Person>::value_type::first, _1) << '\t'
                    << bind(&Person::Name,
                            bind(&std::map<int, Person>::value_type::second, _1)) << '\n'
  );

  std::cout << "Ralph's Id is: " <<
    std::find_if( persons.begin(), persons.end(),
      bind(&Person::Name,
        bind(&std::map<int, Person>::value_type::second, _1)) == "Ralph" )->first;
}

q里 map ?value 元素不再是一个单U的 stringQ我们要输出的是q个 value ?Name() Q幸?lambda 的绑定可以联,所以我们仍然可以用 STL 法在一个表辑ּ之内搞定q些dQfor_each 输出 key ?value ?Name()Q?find_if 扑ֈ value ?Name() ?"Ralph" 的那一个元素,输出是这L(fng)Q?/p>

123     Amy
234     Ralph
345     Simon
456     Maggie
Ralph's Id is: 234

 

 

如果你想要把一个容器内的所有元素篏加v来,应该怎么办?

如果你想要把一个容器内的所有元素篏加v来,应该怎么办?

STL ?accumulate 可以让我们不必自己写循环Q?/p>

#include <iostream>
#include <functional>
#include <numeric>
#include <vector>
#include <string>

int main()
{
  std::vector<int> vect;
  vect.push_back(1);
  vect.push_back(2);
  vect.push_back(3);
  vect.push_back(4);
 
  std::cout << "Accumulate: " <<
    std::accumulate( vect.begin(), vect.end(), 0, std::plus<int>());
}

输出Q?/p>

Accumulate: 10

其中?std::plus<int>() 可以省略Q因是3个参数的 accumulate 的默认行为?注意 accumulate 法是定义在 numeric 里面而不?algorithm 里面的?/p>

׃ accumulate ?plus 都是泛型的,所以如果你要篏加的不是 int 而是字符Ԍ对程序的修改也ƈ不大Q?/p>

#include <iostream>
#include <functional>
#include <numeric>
#include <vector>
#include <string>

int main()
{
  std::vector<std::string> vect;
  vect.push_back("1");
  vect.push_back("2");
  vect.push_back("3");
  vect.push_back("4");
 
  std::cout << "Accumulate: " <<
    std::accumulate( vect.begin(), vect.end(), std::string(""));
}

输出Q?br>Accumulate: 1234

不过Q如果?boost.lambda Q这个问题会(x)有一些很好看又容易理解的解法Q?/p>

#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <string>

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
//#include <boost/bind.hpp>

using namespace boost::lambda;
//using namespace boost;

int main()
{
  std::vector<std::string> vect;
  vect.push_back("1");
  vect.push_back("2");
  vect.push_back("3");
  vect.push_back("4");
 
  std::string result;
 
  std::for_each( vect.begin(), vect.end(), result += _1);
 
  std::cout << result;
}

输出Q?br>1234

q里要借用变量 result Q在q个E序中显得多了几行,但是我们调用 accumulate 的目的也往往是把l果攑ֈ一个变量中Q这L(fng)话,使用 boost.lambda 反而会(x)漂亮一些?/p>

在上面的E序中,另一个丑陋的地方是 vector 的初始化Qؓ(f)了把 1, 2, 3, 4 放进 vect 里面Q我们居然要调用 push_back 4ơ!不过Q?boost.lambda 好得多了?/p>

  std::vector<int> vect(10);
  int i = 0;
  std::for_each( vect.begin(), vect.end(), _1 = ++var(i) );

q里有两个地方值得注意Q?br>1. 现在必须?vect 的声明中指出其大,否则 for_each 对一个空容器可是什么也不会(x)?br>2. 必须使用 ++var(i) Q而不?++i 。var 在这里的作用是强q?lazy evaluation Q也是让变量在被用到的时候在求|如果?++i Q你?x)得C个装?0??vect Q而不是装?-10?/p>

=================================================================================

许多问题遇到 map 都会(x)变得复杂hQ如果想要把一?map 中所有的 key 或?value 累加hQ该怎么办呢Q这个时候已l不能直接?accumulate 了,?boost.bind 可以办到Q做法是q样的:(x)

#include <iostream>
#include <algorithm>
#include <numeric>
#include <map>
#include <string>

#include <boost/bind.hpp>

using namespace boost;

int main()
{
  std::map<int, std::string> persons;
  persons[123] = "Amy";
  persons[234] = "Ralph";
  persons[345] = "Simon";
  persons[456] = "Maggie";
 
  std::cout << std::accumulate( persons.begin(), persons.end(), 0,
    bind(std::plus<int>(), _1, bind(&std::map<int, std::string>::value_type::first, _2)) )
    << std::endl;

  std::cout << std::accumulate( persons.begin(), persons.end(), std::string(),
    bind(std::plus<std::string>(), _1, bind(&std::map<int, std::string>::value_type::second, _2)) )
    << std::endl;
}

输出Q?/p>

1158
AmyRalphSimonMaggie

办是办到了,但是q_而论Q的算不上是漂亮。连l的 bind q不比自己写的@环更让h头晕。boost.lambda 也要用到 bind Q然而可以清晰许多:(x)

#include <iostream>
#include <algorithm>
#include <numeric>
#include <map>
#include <string>

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;

int main()
{
  std::map<int, std::string> persons;
  persons[123] = "Amy";
  persons[234] = "Ralph";
  persons[345] = "Simon";
  persons[456] = "Maggie";

  int iresult = 0;
  std::string sresult;
 
  std::for_each( persons.begin(), persons.end(),
    iresult += bind(&std::map<int, std::string>::value_type::first, _1)
  );
 
  std::for_each( persons.begin(), persons.end(),
    sresult += bind(&std::map<int, std::string>::value_type::second, _1)
  );
 
  std::cout << iresult << std::endl;
  std::cout << sresult << std::endl;
}

输出和上面的一P(x)

1158
AmyRalphSimonMaggie

有了它的帮助Q即侉K接层ơ再增加一层,也不?x)有太多困难Q假如你?map q不直接存储 string Q而是存储 Person 对象Q而它们的名字要通过 Name() Ҏ(gu)来取得,代码只需要稍微的修改Q?/p>


#include <iostream>
#include <algorithm>
#include <numeric>
#include <map>
#include <string>

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;

class Person
{
public:
  Person(){}
  Person(const std::string& name) : name_(name){}
 
  std::string& Name()
  { return name_; }
 
private:
  std::string name_;
};

int main()
{
  std::map<int, Person> persons;
  persons[123] = Person("Amy");
  persons[234] = Person("Ralph");
  persons[345] = Person("Simon");
  persons[456] = Person("Maggie");

  std::string result;
 
  std::for_each( persons.begin(), persons.end(),
    result += bind(&Person::Name, bind(&std::map<int, Person>::value_type::second, _1))
  );
 
  std::cout << result;
}

输出Q?/p>

AmyRalphSimonMaggie

 

 

 


上次提到qؓ(f)容器生成数据的问题,我给出的?boost.lambda 的方法是

上次提到qؓ(f)容器生成数据的问题,我给出的?boost.lambda 的方法是Q?/p>

  std::vector<int> vect(10);
  int i = 0;
  std::for_each( vect.begin(), vect.end(), _1 = ++var(i) );

不错Q这样可以生成连l的数字Q也q算比较z,因ؓ(f)代码量不?x)随着容器的大而变化,不过Q如果要在容器内填入随机数呢Q其实比上面更简单,因ؓ(f) STL ?generate 法是设计来做q个的:(x)

  std::vector<int> vect(10);
  std::generate(vect.begin(), vect.end(), rand);

rand 是我们熟(zhn)的标准 C 库函敎ͼq样我们可以生成L数量的随机数了,不过q是有点不好的地方:(x)每次生成的序列都是一L(fng)Q因?rand 生成的是伪随机数。这个容易解冻I我们必须?seed 一下:(x)

  std::vector<int> vect(10);
  srand(time(NULL));
  std::generate(vect.begin(), vect.end(), rand);

好了Q我们终于还是用了三行(其实是两行,声明 vector L必需的吧Q)(j)Q但是好Ҏ(gu)有了一个可用的Ҏ(gu)。回头看看,前面的连l整数问题也可以?generate 来做Q方法不a而喻Q?/p>

  std::vector<int> vect(10);
  int i = 0;
  std::generate(vect.begin(), vect.end(), ++var(i));

好处?generate 本n更能说明q句话的用途,当然q个可能因h而异?/p>

我知道有Z定在问:(x)一定要两行么?一定要有一个初始变量么Q答案是可以没有Q但是要用到另外的算法,再加?boost.lambda 的协助。看看下面:(x)

  std::vector<int> vect(10);
  std::partial_sum(vect.begin(), vect.end(), vect.begin(), _2 = _1 + 1);

如果你现在把 vect 输出Q你?x)得刎ͼ?x)

0 1 2 3 4 5 6 7 8 9

乍看h不太好理解,我来慢慢解释?br>partial_sum 的第4个参数是一个双参数?functor Q在q里Qlambda 表达?_2 = _1 + 1 充当了这个角Ԍ它相当于

 

f(x, y)  {  y  =  x  +  1;  }


?partial_sum 呢?它把一个序列的 partial sum 送到l果序列中去Q例如如果输入一个数l?v[10] Q而输出是 r[10] Q那么它的计就?/p>


r[0] = v[0]            
r[1] = f( r[0], r[1] )
r[2] = f( r[1], r[2] )
......
r[9] = f( r[8], r[9] )


而当我们?partial_sum 作用?vect 本nQ结果就成了


vect[0] = vect[0]                            // vect[0] = 0
vect[1] = (vect[1] = vect[0] + 1)   // vect[1] = 1
vect[2] = (vect[2] = vect[1] + 1)   // vect[2] = 2
......
vect[9] = (vect[9] = vect[8] + 1)   // vect[9] = 9


你一定发现其中的问题所在了Q首先,我们必须依赖于编译器?vect[0] 初始化ؓ(f)0Q其ơ,vect[0] = vect[0] 是不可回避的。以我当前所惛_的,也只能这样了?/p>

推广一下,如果?_2 = _1 + 1 中的常数 1 换成另外的数字,我们可以用一句话得到?0 开始的{差数列Q例?/p>

  std::partial_sum(vect.begin(), vect.end(), vect.begin(), _2 = _1 + 3);

得到的是

0 3 6 9 12 15 18 21 24 27

如果再发挥一Ҏ(gu)象力Q你可以构造出更复杂的 lambda 表达式,从而得到更复杂的数l(也许q里叫数列更好吧Q,例如

  std::partial_sum(vect.begin(), vect.end(), vect.begin(), _2 = 2 * _1 + 1);

得到的是 2 ?n ơ方 - 1 数列

0 1 3 7 15 31 63 127 255 511

?STL 法中,adjacent_difference ?partial_sum 是逆运,因此Q上面的事情也可以用 adjacent_difference 来做Q只不过要把 lambda 表达式中的参C|换一下,例如要得?0, 3, 6... 的等差数列,只需?/p>

  std::adjacent_difference(vect.begin(), vect.end(), vect.begin(), _1 = _2 + 3);

?2 ?n ơ方 - 1 数列也是同样道理

  std::adjacent_difference(vect.begin(), vect.end(), vect.begin(), _1 = 2*_2 + 1);

如果你要生成倒序的数列呢Q当?dng)STL 法 reverse 可以z上用场Q不q也不要忘了 STL q有 reverse_iterator q回事,用它?yu)无需另外调用 reverse 了:(x)

  std::partial_sum(vect.rbegin(), vect.rend(), vect.rbegin(), _2 = 2*_1 + 1);

得到

511 255 127 63 31 15 7 3 1 0

最后还要提醒大家不要忘了一个很有用?STL 法Q?random_shuffle 。它可以?Random access container 里面的值打乱,配合上面的数列生成,在很多场合是q行试 Q例如测试排序算法)(j) 的好工具。在我的机器上,下面两行

  std::partial_sum(vect.begin(), vect.end(), vect.begin(), _2 = 2*_1 + 1);
  std::random_shuffle(vect.begin(), vect.end());

得到打ؕ以后的数列:(x)

255 1 511 3 0 31 127 7 15 63

=================================================================================

有了强大的生成机制作基础Q下面的实验也更加容易了。STL ?count_if ?find_if 都接受一?predicate 作ؓ(f)比较的依据,而这?predicate 往往非常单,以至于ؓ(f)它专门写一?functor 直不可接受。在W一里面已l展CZ?boost.lambda 生成临时的无?functor 的能力,q里再多说一炏V?/p>

下面先生?2^n - 1 的数l,然后扑և其中W一个大?00的数

  std::vector<int> vect(10);
  std::partial_sum(vect.begin(), vect.end(), vect.begin(), _2 = 2*_1 + 1);
 
  std::cout << *std::find_if(vect.begin(), vect.end(), _1 > 100);

输出?127 Q如我们所料。同样道理,如果?count_if Q则?x)得到大?00的数的个?/p>

  std::cout << std::count_if(vect.begin(), vect.end(), _1 > 100);

输出?3 。注意细节:(x)find_if q回一?iterator Q所以在它之前有 * 解引用,?count_if 直接q回一个数字,无需解引用?/p>

与之cM的还?STL ?partition 法Q它Ҏ(gu)传入?predicate 对一个序列进行划分,predicate 得到 true 的将攑֜前面Q其余的攑֜后面Q返回的是那?#8220; 攑֜ 后面”的元素中的第一个,换言之就是分界点。下面的代码

  std::vector<int> vect(10);
  std::partial_sum(vect.begin(), vect.end(), vect.begin(), _2 = 2*_1 + 1);
 
  std::cout << *std::partition(vect.begin(), vect.end(), _1 > 100) << std::endl;
 
  std::for_each(vect.begin(), vect.end(), std::cout << _1 << " ");

输出?/p>

7
511 255 127 7 15 31 63 3 1 0

如果仔细观察Q还可以发现上面的输出有炚w题:(x)数列中原有的序Q?, 1, 3, 7...Q不复存在,q是因ؓ(f) partition q不是一个稳定排序的法Q它不保证排序结果保有原来的序。如果需要稳定排序,可以使用 stable_partition 。只需要更Ҏ(gu)序的那一句代码ؓ(f)

  std::cout << *std::stable_partition(vect.begin(), vect.end(), _1 > 100) << std::endl;

l果?/p>

0
127 255 511 0 1 3 7 15 31 63

当然Q如果你q记得大学里的算法理论,q道它们在效率上是有点区别的,partition 的复杂度保证?O(n) Q具体地说是保证不超q?n/2 ơ交换;?stable_partition 在最好情况下?O(n) Q最差情况则辑ֈ O(n*log(n)) ?/p>

Z说一下,上面的几件简单的事情Q用标准?STL 法都可以办刎ͼ只不q实在是……面目可憎Q?/p>

  std::cout << *std::partition(vect.begin(), vect.end(),
    std::bind2nd(std::greater<int>(), 100)) << std::endl;

q句代码做的事情和前面的 partition 一模一P但是C孰劣Q大家自有公断?/p>

 

 


L一些时候,我们不能够借助?#8220;生成?#8221;的初始化Ҏ(gu)来给容器赋|例如我们已经有了一个数l,要把它作为初Dl一个容器,常规的做法已l深入h心了

L一些时候,我们不能够借助?#8220;生成?#8221;的初始化Ҏ(gu)来给容器赋|例如我们已经有了一个数l,要把它作为初Dl一个容器,常规的做法已l深入h心了Q?/p>

  int init[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
  std::vector<int> vect(init, init + sizeof(init)/sizeof(int));

通过两个 sizeof 来得到数l的大小?C 语言里面是很常见的,然而在 C++ 里面Q这即便不能UCؓ(f)丑陋Q也l对UC上是好。首先其可读性不好,其次它要q行一ơ除法来得到一个本来在~译期间q道的数字Q最后,它ƈ不是总能用的Q例如下面的例子Q?/p>

  std::string strs[] = { "Amy", "Ralph", "Simon", "Maggie" };

现在Q你打算?"sizeof " 什么来除以 "sizeof" 什么?

其实Q经q了q么?C++ GP 的磨l,我们很容易就?x)想C个在~译期间得到静态数l大的办法Q模板偏特化是我们常用的武器Q在q里非常好用Q?/p>

template <class T>
struct ArraySize
{
    static const unsigned int value = 0;
};

template <class T, int S>
struct ArraySize<T[S]>
{
    static const unsigned int value = S;
};

p么简单!虽然它只对付一l数l,但是扩展它是很容易的。不q,模板参数只能为类型,而我们需要传入的是一个变量。好在在计算机科学里面,加一层抽象是可以解决M问题的,我们只要加一个模板函敎ͼC++ ?x)自动帮我们做类型推|(x)

template <class T>
unsigned int array_size(const T&)
{
    return ArraySize<T>::value;
}

现在我们可以轻而易丄搞定那些数组了:(x)

  int ints[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
  std::vector<int> vint(ints, ints + array_size(ints));
 
  std::string strs[] = { "Amy", "Ralph", "Simon", "Maggie" };
  std::vector<std::string> vstr(strs, strs + array_size(strs));
 
  std::for_each(vint.begin(), vint.end(), std::cout << _1 << " ");
  std::cout << std::endl;
  std::for_each(vstr.begin(), vstr.end(), std::cout << _1 << " ");

输出Q?/p>

2 3 5 7 11 13 17 19 23
Amy Ralph Simon Maggie

Z说一下,?boost.type_traits 里面有一个类g ArraySize 的工P叫做 extent Q它更加强大Q可以对付多l数l,不过是否值得Zq个而把 boost.type_traits 包含到工E里面去q读者自己抉择了?/p>

=================================================================================

容器的初始化是如此的常见Q以至于 boost 提供了一?assign 库来化这些操作。boost.assign 大量利用了重载的逗号和括h化赋值操作,提供了甚x用数l更加简z的语法Q?/p>

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

#include <boost/assign/std/vector.hpp>
#include <boost/assign/std/list.hpp>

using namespace boost::assign;

int main()
{
  std::vector<int> vint;
  vint += 2,3,5,7,11,13,17,19,23;
 
  std::vector<std::string> vstr;
  vstr += "Amy","Ralph","Simon","Maggie";
 
  std::list<std::string> lstr;
  lstr += "Amy","Ralph","Simon","Maggie";
   
  std::for_each(vint.begin(), vint.end(), std::cout << _1 << " ");
  std::cout << std::endl;
  std::for_each(vstr.begin(), vstr.end(), std::cout << _1 << " ");
  std::cout << std::endl;
  std::for_each(lstr.begin(), lstr.end(), std::cout << _1 << " ");
}

q行q个E序Q输Z前面的大致相同,但是我们注意到初始化更加z了Q而且也不需要额外的I间来存储数l,对于各种cdQ都能够以统一的方式来初始化,真是妙不可言。有的?assign 的作者在文档中还Ҏ(gu)引用?Bjarne Stroustrup 的话作ؓ(f)引子Q?/p>

There appear to be few practical uses of operator,().
Bjarne Stroustrup, The Design and Evolution of C++

q也许就?C++ 最大的力之一Q你无法预料它可以办C什么?/p>

下面关于 map 的例子也使用 boost.assign Q可以看到重载的括号l我们带来了多少方便?/p>

#include <iostream>
#include <algorithm>
#include <map>
#include <string>

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

#include <boost/assign/list_inserter.hpp>
#include <boost/assign/list_of.hpp>

using namespace std;
using namespace boost::assign;
using namespace boost::lambda;

int main()
{
  map<string,int> months; 
 
  insert( months )
    ( "january",   31 )( "february", 28 )
    ( "march",     31 )( "april",    30 )
    ( "may",       31 )( "june",     30 )
    ( "july",      31 )( "august",   31 )
    ( "september", 30 )( "october",  31 )
    ( "november",  30 )( "december", 31 );
   
  map<int,string> persons = map_list_of
    (2,"Amy")(3,"Ralph")
    (5,"Simon")(7,"Maggie");
   
  for_each( months.begin(), months.end(),
    cout << bind(&map<string,int>::value_type::second, _1) << "\t"
         << bind(&map<string,int>::value_type::first, _1) << "\n"
  );
  cout << endl;
  for_each( persons.begin(), persons.end(),
    cout << bind(&map<int,string>::value_type::first, _1) << "\t"
         << bind(&map<int,string>::value_type::second, _1) << "\n"
  ); 
}

输出Q?/p>

30      april
31      august
31      december
28      february
31      january
31      july
30      june
31      march
31      may
30      november
31      october
30      september

2       Amy
3       Ralph
5       Simon
7       Maggie



morphis 2007-06-06 09:37 发表评论
]]>
~译boost?用vc2005~译boosthttp://www.aygfsteel.com/morphis/archive/2007/06/05/122116.htmlmorphismorphisTue, 05 Jun 2007 04:45:00 GMThttp://www.aygfsteel.com/morphis/archive/2007/06/05/122116.htmlhttp://www.aygfsteel.com/morphis/comments/122116.htmlhttp://www.aygfsteel.com/morphis/archive/2007/06/05/122116.html#Feedback0http://www.aygfsteel.com/morphis/comments/commentRss/122116.htmlhttp://www.aygfsteel.com/morphis/services/trackbacks/122116.html~译boost?用vc2005~译boost1.33.1
//打开控制台窗口,请用vs2005在开始菜单中?#8220;Visual Studio Tools->Visual Studio 2005 命o(h)提示”打开控制収ͼq样vc的的~译环境?yu)p|好了?br>//假设boost安装包的解压的目录ؓ(f){BOOST_SRC}中?br>//先编译出bjam.exeQ它被用于安装boost?br>cd {BOOST_SRC}\tools\build\jam_src
build.bat
//利用~译出的bjam.exeE序~译q安装boost?br>cd {BOOST_SRC}
copy {BOOST_SRC}\tools\build\jam_src\bin.ntx86\bjam.exe
//下面的命令的各选项的说明:(x)
//prefix    boost安装到的路径Q生成的头文件和库文仉?x)放到该路径中?j)?br>//重定义以下变量(利用-s讄Q:(x)
//VC80_ROOT  vc2005的安装\径,如果未将vc2005安装到默认位|,你必L定该V?br>//TOOLS         使用的编译工Pvc2005对应的是vc-8_0
//PYTHON_ROOT        python的安装目录,如果未将BOOST安装到默认位|,你必L定该V?br>//BUILD         ~译l果选项Q默认会(x)生成可能多的版本,如调试版Q发行版Q静态库Q动态库Q单U程Q多U程?br>bjam "-sVC80_ROOT=D:\Program Files\Microsoft Visual Studio 8\VC" "-sTOOLS=vc-8_0"  "-sPYTHON_ROOT=D:\Program Files\Python24" "--prefix=E:\librarys\boost" install

boost在vc2005中的~译出现codepage警告和DEPRECATED函数的解册日下载了一个VC2005 Express EditionQ用它来~译boostQ发现有不少的warning C4819Q说代码文g中有cp936无法表示的字W,q有是vc2005Ҏ(gu)的废弃的ANSI函数的错误,虽说不媄(jing)响编译,但是看着时不时出现的warningL让h心神不安Q还Ҏ(gu)掩盖其他的错误,如果是直接用cl~译Q只要加?wd4819 /D_CRT_SECURE_NO_DEPRECATE可以不昄q两个错误,但是大家都知道boost是用其Ҏ(gu)的boost.buildq行~译的,下面我就l出如何修改boost.build来抑制这两个错误的显C?/p>

boost.build分ؓ(f)v1和v2两个版本
v1Q?br>修改$(BOOST_ROOT)/tools/build/v1/vc-8_0-tools.jam
?/p>

 flags vc - 8_0 C ++ FLAGS :  / Zc:forScope ;
改ؓ(f)


 flags vc - 8_0 C ++ FLAGS :  / Zc:forScope  / wd4819  / D_CRT_SECURE_NO_DEPRECATE ;
v2Q?br>cvs版本
修改$(BOOST_ROOT)/tools/build/v2/tools/msvc.jam
?/p>

 #  8.0  adds some more options
 
一行的下方加上

 flags msvc.compile CFLAGS $(condition) :  / wd4819  / D_CRT_SECURE_NO_DEPRECATE ;
 
boost 1.33.1版本
?/p>


    #  8.0  deprecates some of the options
     if   !  [ MATCH  ^ ([ 67 ]. * ) : $(version) ]
    {
        flags msvc.compile CFLAGS $(condition) /< optimization > speed :  / O2 ;
        flags msvc.compile CFLAGS $(condition) /< optimization > space :  / O1 ;
        flags msvc.link.dll MANIFEST :  " mt -manifest  "  ;
        flags msvc.link.dll OUTPUTRESOURCE :  " -outputresource: "  ;
    }
改ؓ(f)Q?/p>


    #  8.0  deprecates some of the options
     if   !  [ MATCH  ^ ([ 67 ]. * ) : $(version) ]
    {
        flags msvc.compile CFLAGS $(condition) :  / wd4819  / D_CRT_SECURE_NO_DEPRECATE ;
        flags msvc.compile CFLAGS $(condition) /< optimization > speed :  / O2 ;
        flags msvc.compile CFLAGS $(condition) /< optimization > space :  / O1 ;
        flags msvc.link.dll MANIFEST :  " mt -manifest  "  ;
        flags msvc.link.dll OUTPUTRESOURCE :  " -outputresource: "  ;
    }



morphis 2007-06-05 12:45 发表评论
]]>
在面试中的最x?/title><link>http://www.aygfsteel.com/morphis/archive/2007/06/01/121438.html</link><dc:creator>morphis</dc:creator><author>morphis</author><pubDate>Fri, 01 Jun 2007 14:56:00 GMT</pubDate><guid>http://www.aygfsteel.com/morphis/archive/2007/06/01/121438.html</guid><wfw:comment>http://www.aygfsteel.com/morphis/comments/121438.html</wfw:comment><comments>http://www.aygfsteel.com/morphis/archive/2007/06/01/121438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/morphis/comments/commentRss/121438.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/morphis/services/trackbacks/121438.html</trackback:ping><description><![CDATA[在面试中的最x?br><br>面试是一U双向沟通的q程。雇佣(招聘Q经理通过面试来决定你是否适合q个职位。同Ӟ你也应该相应的提q问题来判断q个公司或职位是否让自己满意?br><br>但是当正式开始面试的时候,很容易忘记准备好的提问。毕竟你在一个陌生的办公室进行面试。在听了雇䄦l理对公司背景或产品的一番介l后Q你有被问到了一堆有关于你的工作l验、学历背景、未来计划等的问题。同时也在祈L(fng)自己l出了正的回答?br><br>到雇主(或招聘经理)(j)问你有什么问题要问时Q你很容易紧张ƈl结巴巴的回{?#8220;没有”?br><br>然而,不提问题可能?x)错׃一个获得竞争的Z(x)?br><br>“q是一个很大的Z(x)可以以积极的方式Z从其他候选h手中赢得q个职位”一位在人才招聘机构的资深顾问说道。雇主认Z们对于能提出有品质问题ƈ能通过q种明智的谈话获得讯息的候选h很感兴趣?br><br>在面试前Q准备一份有关于面试公司?qing)应聘职位的一些问题列表。以下是一些话题供参?<br><br>关于公司的提?br>1.(zhn)对贵公司未?q有什么展望?<br>2.(zhn)对q个行业有什么看法?<br>3.(zhn)认公司最重要的资产是什么?<br>4.(zhn)能介绍下贵公司的新产品或是增D划吗Q?br>5.(zhn)如何看待竞争?<br><br>关于职位背景<br>询问该职位ؓ(f)什么空~,可以提供z察公司和晋升的可能.如:(x)<br>1.公司的整体架构是怎样的?<br>2.在这个部门的职场行径如何Q?br>3.在过dq里该部门的业W如何Q?br>4.(zhn)如何看待?zhn)的团队(或部门?j)Q?br><br>关于职责<br>Z避免E后的؜乱,q而取得可靠的职位理解Q可以提Z下问题来帮助自己q一步了解职位信息:(x)<br>1.(zhn)认个职位最重要的方面是什么?<br>2.(zhn)认量受雇于该职位的人所具备的技能和价值是什么?<br>3.之前从事该职位的员工是否成功升迁了?<br>4.(zhn)能描述下这个职位每天或每周需要做的工作有哪些吗?哪些客户需要维护?<br><br>关于期望<br>军_你什么时候如何被评估Q专家徏议:(x)<br>1.需要在最初的三个月中表现出来的这个职位的最大挑战是什么?<br>2.在未来一q中(zhn)对q个职位的期望是什么?<br>3.在贵公司我如何被评估或考核Q评定的周期是怎么L(fng)Q?br><br>在面试的最后,不要忘了询问Q接下来的面试步骤是什么? <img src ="http://www.aygfsteel.com/morphis/aggbug/121438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/morphis/" target="_blank">morphis</a> 2007-06-01 22:56 <a href="http://www.aygfsteel.com/morphis/archive/2007/06/01/121438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Copy Location Shell Extensionhttp://www.aygfsteel.com/morphis/archive/2007/05/30/120918.htmlmorphismorphisWed, 30 May 2007 07:06:00 GMThttp://www.aygfsteel.com/morphis/archive/2007/05/30/120918.htmlhttp://www.aygfsteel.com/morphis/comments/120918.htmlhttp://www.aygfsteel.com/morphis/archive/2007/05/30/120918.html#Feedback0http://www.aygfsteel.com/morphis/comments/commentRss/120918.htmlhttp://www.aygfsteel.com/morphis/services/trackbacks/120918.htmlhttp://www.codeproject.com/shell/copylocation.asp

morphis 2007-05-30 15:06 发表评论
]]>
վ֩ģ壺 ƽ| ʩ| | | ֶ| | | Ĭ| ؼ| ˳| | | | | | Զ| Ϫ| | | | | | | | | ʯɽ| ԰| ֣| Ϸ| | ɽ| ӻ| Ž| | | | | ۷| ̨| ԰| Ѱ|