博文
work thread和UI thread的区别(包括产生以及终结)(2010-03-23 18:55:00)
摘要:一、线程产生篇:
它们都需要呼叫AfxBeginThread 以产生一个 CWinThread 对象,并在创建对象的时候定义其消息响应函数,下面代码是work thread所呼叫的AfxBeginThread函数:
CWinThread* pThread = AfxBeginThread(ThreadFunc, &Param);
函数原型是:
CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
但如果要产生一个UI thread,你还必须先定义一个 CWinThread 衍生类别,因为现在需要一个消息回路,CWinThread::Run里头就有一个消息回路,然后再呼叫AfxBeginThread产生一个CWinThread对象。下面代码是UI thread所呼叫的AfxBeginThread()函数:
CWinThread *pThread = AfxBeginThread(RUNTIME_CLASS(CMyThread));
函数原型是:
CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
注意:UI thread的消息响应函数原型和work thread的消息响应函数是两个不同的重载函数。
二、线程结束篇
既然 worker thread 的生命就是线程函数本身,函数一旦 return,线程也就结束了,自然得很。或者线程函数也可以呼叫 AfxEndThread,结束一个线程。UI 线程因为有消息回路的关系,必须在消息队列中放一个 WM......
用函数指针变量调用函数(2009-10-28 10:33:00)
摘要:可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。一个函数在编译时被分配给一个入口地址。这个入口地址就称为函数的指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。先通过一个简单的例子来回顾一下函数的调用情况。例 求a和b中的大者。先列出按一般方法的程序。main(){ int max(int,int); int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); printf("a=%d,b=%d,max=%d",a,b,c);}max(int x,int y){ int z; if(x>y) z=x; else z=y; return(z);} main 函数中的“c=max(a,b);”包括了一次函数调用(调用 max 函数)。每一个函数都占用一段内存单元,它们有一个起始地址。因此,可以用一个指针变量指向一个函数,通过指针变量来访问它指向的函数。 将 main 函数改写为main(){ int max(int,int); int (*p)(); int a,b,c; p=max; scanf("%d,%d",&a,&b); c=(*p)(a,b); printf("a=%d,b=%d,max=%d",a,b,c);} 其中“int (*p)();”定义 p 是一个指向函数的指针变量,此函数带回整型的返回值。注意 *p 两侧的括弧不可省略,表示 p 先与 * 结合,是指针变量,然后再与后面的()结合,表示此指针变量指向函数,这个函数值(即函数返回的值)是整型的。如果写成“int *p();”,则由于()优先级高于*,它就成了声明一个......
assert() 函数用法(2009-10-22 10:12:00)
摘要:assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:
#include <assert.h>
void assert( int expression );
assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,
然后通过调用 abort 来终止程序运行。
请看下面的程序清单badptr.c:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main( void )
{
FILE *fp;
fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件
assert( fp ); //所以这里不会出错
fclose( fp );
fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开文件失败
assert( fp ); &n......
C++为什么不支持类模板的声明与实现的分离?(2009-09-28 15:35:00)
摘要:【转】http://www.pexwin.cn/Topic.aspx?BoardID=2&TopicID=291
C++不支持类模板的声明与实现分离: 普通的实例: \***********THead.h*********\ class TA { int a; public: TA(); } \*********THead.cpp*********\ TA::TA() { } \*********tmain.cpp********\ #include "THead.h" #include <iostream> using namespace std; int main() { TA ta; } \************************\ 分析: 编译main.cpp时,要调用TA的构造函数,但main.cpp没有,所以去"THead.h"找;找到THead.h时也没有找到,所以去所在的目录里找,结果找到了THead.cpp,编译了THead.cpp产生THead.obj,至此已完成了ta的构造. 过程为: 编译:main.cpp生成main.obj,THead.obj 运行连接: 首先加载main.obj,发现没有TA的构造函数模块,于是连接THead.obj找到并继续运行。 模板的实例: \**********Test.h**********\ template<typename T> class A { int a; public: A(); }; \*********Test.cpp********\ template<typename T> A<T>::A() { } \********main.cpp*********\ #include "Test.h" #include <iosteram> using namespace std; int main() { &nb......
ASCII表(2009-09-20 21:33:00)
摘要:
ASCII表
ASCII值
控制字符
ASCII值
控制字符
ASCII值
控制字符
ASCII值
控制字符
0
NUT
32
(space)
64
@
96
、
1
SOH
33
!
65
A
97
a
2
STX
34
”
66
B
98
b
3
ETX
35
#
67
C
99
c
4
EOT
36
$
68
D
100
d
5
ENQ
37
%
69
E
101
e
6
ACK
38
&
70
F
102
f
7
BEL
39
,
71
G
103
g
8
BS
40
(
72
H
104
h
9
HT
41
)
73
I
105
i
10
LF
42
*
74
J
106
j
11
VT
43
+
75
K
107
k
12
FF
44
,
76
L
108
l
13
CR
45
-
77
M
109
m
14
SO
46
.
78
N
110
n
15
SI
47
/
79
O
111
o
16
DLE
48
0
80
P
112
p
17
DCI
49
1
81
Q
113
q
18
DC2
50
2
82
R
114
r
19
DC3
51
3
83
X
115
s
20
DC4
52
4
84
T
116
t
21
NAK
53
5
85
U
117
u
22
SYN
54
6
86
V
118
v
23
TB
55
7
87
W
119
w
24
CAN
56
8
88
X
120
x
25
EM
57
9
89
Y
121
y
26
SUB
58
:
90
Z
122
z
27
ESC
59
;
91
[
123
{
28
FS
60
<......
C++文件读写函数介绍(2009-09-16 20:56:00)
摘要:1.fopen() fopen的原型是:FILE *fopen(const char *filename,const char *mode),fopen实现三个功能:为使用而打开一个流,把一个文件和此流相连接,给此流返回一个FILR指针。 参数filename指向要打开的文件名,mode表示打开状态的字符串,其取值如下: 字符串 含义 "r" 以只读方式打开文件 "w" 以只写方式打开文件 "a" 以追加方式打开文件 "r+" 以读/写方式打开文件,如无文件出错 "w+" 以读/写方式打开文件,如无文件生成新文件 一个文件可以以文本模式或二进制模式打开,这两种的区别是:在文本模式中回车被当成一个字符’\n’,而二进制模式认为它是两个字符0x0D,0x0A;如果在文件中读到0x1B,文本模式会认为这是文件结束符,也就是二进制模型不会对文件进行处理,而文本方式会按一定的方式对数据作相应的转换。 系统默认的是以文本模式打开,可以修改全部变量_fmode的值来修改这个设置,例如_fmode=O_TEXT;就设置默认打开方式为文本模式;而_fmode=O_BINARY;则设置默认打开方式是二进制模式。 我们也可以在模式字符串中指定打开的模式,如"rb"表示以二进制模式打开只读文件,"w+t"或"wt+"表示以文本模式打开读/写文件。 此函数返回一个FILE指针,所以申明一个FILE指针后不用初始化,而是用fopen()来返回一个指针并与一个特定的文件相连,如果成败,返回NULL. 例: 以下是引用片段: FILE *fp; if(fp=fopen("123.456","wb")) puts("打开文件成功"); else puts("打开文件成败"); 2.fclose() fclose()的功能就是关闭用fopen()打开的文件,其原型是:int fclose(FILE *fp);如果成功,返回0,失败返回EOF。 在程序结束时一定要记得关闭打开的文件,不然可能会造成数据丢失的情况,我以前就经常犯这......
linux下用gcc生成静态库和动态库(2009-09-15 10:11:00)
摘要:
蛮清楚的。
我们通常把一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。本文主要通过举例来说明在Linux中如何创建静态库和动态库,以及使用它们。
在创建函数库前,我们先来准备举例用的源程序,并将函数库的源程序编译成.o文件。
第1步:编辑得到举例的程序--hello.h、hello.c和main.c;
hello.c(见程序2)是函数库的源程序,其中包含公用函数hello,该函数将在屏幕上输出"Hello XXX!"。hello.h(见程序1)为该函数库的头文件。main.c(见程序3)为测试库文件的主程序,在主程序中调用了公用函数hello。
#ifndef HELLO_H#define HELLO_H
void hello(const char *name);
#endif //HELLO_H程序1: hello.h
#include <stdio.h>
void hello(const char *name){printf("Hello %s!\n", name);}程序2: hello.c
#include "hello.h"
int main(){hello("everyone");return 0;}程序3: main.c
第2步:将hello.c编译成.o文件;
无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过gcc先编译成.o文件。
在系统提示符下键入以下命令得到hello.o文件。
# gcc -c hello.c
#
我们运行ls命令看看是否生存了hello.o文件。
# ls
hello.c hello.h hello.o main.c
#
在ls命令结果中,我们看到了hello.o文件,本步操作完成。
下面我们先来看看如何创建静态库,以及使用它。
第3步:由.o文件创建静态库;
静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将创建的静态库名为myhello,则静态库文件名就是libmyhello.a。在创建和......
linux下用gcc生成静态库和动态库(2009-09-15 10:11:00)
摘要:
蛮清楚的。
我们通常把一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。本文主要通过举例来说明在Linux中如何创建静态库和动态库,以及使用它们。
在创建函数库前,我们先来准备举例用的源程序,并将函数库的源程序编译成.o文件。
第1步:编辑得到举例的程序--hello.h、hello.c和main.c;
hello.c(见程序2)是函数库的源程序,其中包含公用函数hello,该函数将在屏幕上输出"Hello XXX!"。hello.h(见程序1)为该函数库的头文件。main.c(见程序3)为测试库文件的主程序,在主程序中调用了公用函数hello。
#ifndef HELLO_H#define HELLO_H
void hello(const char *name);
#endif //HELLO_H程序1: hello.h
#include <stdio.h>
void hello(const char *name){printf("Hello %s!\n", name);}程序2: hello.c
#include "hello.h"
int main(){hello("everyone");return 0;}程序3: main.c
第2步:将hello.c编译成.o文件;
无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过gcc先编译成.o文件。
在系统提示符下键入以下命令得到hello.o文件。
# gcc -c hello.c
#
我们运行ls命令看看是否生存了hello.o文件。
# ls
hello.c hello.h hello.o main.c
#
在ls命令结果中,我们看到了hello.o文件,本步操作完成。
下面我们先来看看如何创建静态库,以及使用它。
第3步:由.o文件创建静态库;
静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将创建的静态库名为myhello,则静态库文件名就是libmyhello.a。在创建和......
Linux下静态库.a文件生成方法(转)(2009-09-14 16:53:00)
摘要:Linux下静态库.a生成1.将各函数代码所在的源文件编译成目录文件。例如,对于myfunc.c,可以用如下命令 将其编译成目标文件: gcc -c myfunc.c 当然在有多个源文件时,只需在gcc 命令行中将其分别列上就可以了。经此一步,将能够得到各源文件的目标文件。对上例,将得到myfunc.o
2.将各目标文件收集起来放到一个静态库文件中。这主要借助于ar命令完成,如: ar r ~/lib/libtest.a myfunc.o
注:建立动态链接库、并不需要用到其他的工具,借助于gcc命令即可完成。此时需在命令 行中加上-K PIC和-G这两个选项,如下我们可以建立libtest的动态版本:gcc -K PIC -G -o $HOME/lib/libtest.so myfunc.c
1、用gcc的-c选项生成.o文件,如gcc -c test1.c test2.c test3.c编译后会生成test1.o test2.o test3.o三个目标文件。2、然后用ar命令生成.a文件,如ar crv test.a test1.o test2.o test3.o
本文来自CSDN博客,http://blog.csdn.net/zhangbiao1981/archive/2009/04/27/4128209.aspx......
bind1st bind2nd的使用(转)(2009-09-11 20:45:00)
摘要: 作者Blog:http://blog.csdn.net/simahao/
本篇适合不熟悉这两个函数的读者
以前在使用stl的过程中发现bind1st和bind2nd这两个函数,当时不太理解什么意思,今天在网上查了一下相关资料发现竟然很简单,下面我就具体解释一下他们的用法。
bind1st和bind2nd函数用于将一个二元算子(binary functor,bf)转换成一元算子(unary functor,uf)。为了达到这个目的,它们需要两个参数:要转换的bf和一个值(v)。
可能这么解释以后大家还不是很清楚,那么就说点白话吧。我们在做比较的时候所写的表达式像 x > k ,x < k,这里的k是一个参数表示你程序里面的表达式要和k值去比较。上面这两个表达式对应的应该是bind2nd ,简单的理解就是把k作为比较表达式的第二个参数。如果使用bind1st则对应的表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。大家可能会注意到这里面没有=的比较,先别着急,后面将会说道如何实现=的比较。先举两个例子看看bind1st和bind2nd的用法。
int a[] = {1, 2, 100, 200};
std::vector< int> arr(a, a + 4);// 移除所有小于100的元素arr.erase( std::remove_if( arr.begin(), arr.end(), std::bind2nd( std::less< int>(), 100)), arr.end());
这里的比较表达式相当于arr.value < 100
如果用bind1st则表达的意思就恰恰相反
// 移除所有大于100的元素arr.erase( std::remove_if( arr.begin(), ar......
