C++学习记录(5)
extern
extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。另外,extern也可用来进行链接指定。
如果文件a.c需要引用b.c中变量int v,就可以在a.c中声明extern int v,然后就可以引用变量v。
这里需要注意的是,被引用的变量v的链接属性必须是外链接(external)的,也就是说a.c要引用到v,不只是取决于在a.c中声明extern int v,还取决于变量v本身是能够被引用到的。
这涉及到c语言的另外一个话题--变量的作用域。能够被其他模块以extern修饰符引用到的变量通常是全局变量。
线程
在C++中一个项目要同时进行多个子程序进行运行,就要用到线程,在项目中是使用CWinThread,查了其使用方法:
第一 创建线程
函数原型:
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
返回值:
指向新创建的线程对象。
参数:
pfnThreadProc:工作线程的函数指针,不可以为空。并且工作线程的函数必须如此声明:
UINT MyControllingFunction( LPVOID pParam );
pThreadClass: 从CWinThread类继承来的对象的RUNTIME_CLASS指针。
pParam: 传递给工作线程函数pfnThreadProc的参数。
nPriority: 线程的优先级。如果为0,则与创建它的线程优先级相同。可以通过参考Win32 Programmer’s
Reference中的SetThreadPriority得到所有可用的优先级列表和描述。
nStackSize: 以字节为单位指定新线程的堆栈大小。如果为0,则与创建它的线程的堆栈大小相同。
dwCreateFlags:指定一个额外的标志控制线程的产生。它可以包括下面两个值中的一个:
CREATE_SUSPENDED:以挂起模式开始线程,并且指定挂起次数.当调用ResumeThread时,这个线程才会被执行。
DWORD dwCreateFlags = 0;//创建后立即执行。
lpSecurityAttrs:指向SECURITY_ATTRIBUTES结构的指针,结构中指定了线程的安全属性。如果为NULL,则与创建它的线程的安全属性相同。如果希望得到更多的有关SECURITY_ATTRIBUTES结构的信息,
请参考Win32 Programmer’s Reference。
注释:
调用这个函数创建一个新的线程。第一种形式的AfxBeginThread创建一个工作线程;第二种形式创建一个用户
接口线程。
AfxBeginThread创建一个新CWinThread对象,调用它的CreateThread函数开始执行线程并且返回指向线程的指
针。Checks are made throughout the procedure to make sure all objects are deallocated properly
should any part of the creation fail. 终止线程,可以在线程函数中调用AfxEndThread, 或者从工作线程
的函数中返回。
示例:
创建一个工作线程:
UINT WorkForce(LPVOID lpParameter);//线程函数声明 CWinThread *pMyFirstWorker,*pMySecondWorker; LPVOID pParam = NULL; int nPriority = THREAD_PRIORITY_ABOVE_NORMAL;//默认为THREAD_PRIORITY_NORMAL UINT nStackSize = 0;//与创建它的线程堆栈大小相同 DWORD dwCreateFlags = 0;//创建后立即执行 LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ;//与创建它的线程安全属性相同 pMyFirstWorker=AfxBeginThread(WorkForce, pParam, nPriority , nStackSize, dwCreateFlags , lpSecurityAttrs); pMySecondWorker=AfxBeginThread( WorkForce, (LPVOID)&port);//如果采用默认值 UINT WorkForce( LPVOID lpParameter // 线程所需参数,可以通过它传递数据) { int nPort=*((int*)pParam); //这里获得的nPort就是输入时候传递进来的. return 0;//什么不做 }
第二 销毁线程
首先需要说明的是销毁线程函数AfxEndThread,只能运用于线程内销毁.不同线程之间应建立通信渠道.下面是段具体代码:
UINT WorkForce( LPVOID lpParameter // 线程所需参数,可以通过它传递数据) { int nPort=*((int*)pParam); //这里获得的nPort就是输入时候传递进来的. if( bExitCode )//满足销毁的条件 { DWORD ExitCode=0; GetExitCodeThread( p->m_hThread,&ExitCode); //p为需要销毁的CWindThreadZ指针,其在创建线程时可以拿到. if(ExitCode>0 ) AfxEndThread(ExitCode,true); } return 0;//什么不做 }
C/C++ code
.h 文件
#define WM_TEST WM_USER + 1 class CTestThread : public CWinThread { DECLARE_DYNCREATE(CTestThread) protected: CTestThread (); virtual ~CTestThread (); public: virtual BOOL InitInstance(); virtual int ExitInstance(); protected: afx_msg void OnTest(WPARAM wParam,LPARAM lParam); DECLARE_MESSAGE_MAP() };
.Cpp 文件
#include "stdafx.h" #include "TestThread.h" IMPLEMENT_DYNCREATE(CTestThread, CWinThread) CTestThread::CTestThread() { } CTestThread::~CTestThread() { } BEGIN_MESSAGE_MAP(CTestThread, CWinThread) ON_THREAD_MESSAGE(WM_TEST,OnTest) END_MESSAGE_MAP() BOOL CTestThread::InitInstance() { return TRUE; } int CTestThread::ExitInstance() { return CWinThread::ExitInstance(); } void CTestThread::OnTest(WPARAM wParam,LPARAM lParam) { AfxMessageBox("test"); }
调用的地方
CWinThread* m_pThrd;
//启动
m_pThrd = AfxBeginThread(RUNTIME_CLASS(CTestThread));
// 需要执行线程中的操作时
m_pThrd->PostThreadMessage(WM_TEST,NULL,NULL);
// 结束线程
HANDLE hp=m_pThrd->m_hThread; if (hp) { if (WaitForSingleObject(hp, 1) != WAIT_OBJECT_0) { TerminateThread(hp,0); } CloseHandle(hp); }
goto语句
goto语句也称为无条件转移语句,其一般格式如下: goto 语句标号; 其中语句标号是按标识符规定书写的符号, 放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto 语句配合使用。
如: label: i++;
loop: while(x<7);
goto:loop
C语言不限制程序中使用标号的次数,但各标号不得重名。goto语句的语义是改变程序流向, 转去执行语句标号所标识的语句。
goto语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
- 【记录】Accelerated C++:Practical Programming by Example第0章:开始学习C++
- 20101229学习记录C++ STL
- C++中指针学习记录
- C++ 记录学习过程中一些值得多次阅读的博客文章
- 2018/1/28 C++学习记录(一)
- 算法学习记录八(C++)--->一句代码搞定变态跳台阶
- Effective C++ 学习记录
- Lua和C++交互 学习记录之二:栈操作
- C++学习记录(20180212)
- 学习C++的心得记录
- C++ 学习记录,小技巧
- Lua和C++交互 学习记录之八:C++类注册为Lua模块
- c++学习记录:operator = 重载
- 算法学习记录三(C++)--->从尾到头打印链表每个节点的值
- C++学习记录一
- C++学习记录20--endl,'\n',"\n"
- C++ 学习记录之静态变量static
- C++文本文件读写|学习记录
- 记录一个新人的C++之路,以供后来的新人学习
- 扫地僧C++视频学习记录