UNICODE:它是用两个字节表示一个字符的方法。比如字符'A'在ASCII下面是一个字符,可'A'在UNICODE下面是两个字符,高字符用0填充,而且汉字'程'在ASCII下面是两个字节,而在UNICODE下仍旧是两个字节。UNICODE的用处就是定长表示世界文字,据统计,用两个字节可以编 现存的所有文字而没有二义。
MBCS,它是多字节字符集,它是不定长表示世界文字的编 。MBCS表示英文字母时就和ASCII一 (这也是我们容易把MBCS和ASCII搞混的原 ),但表示其他文字时就需要用多字节。
WINDOWS下面的程序设计可以支持MBCS和UNICODE两种编码的字符串,具体用哪种就看定义了MBCS宏还是UNICODE宏。MBCS宏对应的字符串指针是char*也就是LPSTR,UNICODE对应的指针是unsigned short*也就是LPWSTR,为了写程序方便微软定义了类型LPTSTR,在MBCS下他就是char*,在UNICODE下它是unsigned char*,这 就可以重定义一个宏进行不同字符集的转换了。
LPTSTR、LPCSTR、LPCTSTR、LPSTR的意义:
LPSTR: 32bit指针指向一个字符串,每个字符占1字节
LPCSTR: 32-bit指针指向一个常字符串,每个字符占1字节
LPCTSTR: 32-bit指针指向一个常字符串,每字符可能占1字节或2字节,取决于Unicode是否定义
LPTSTR: 32-bit指针每字符可能占1字节或2字节,取决于Unicode是否定义
Windows使用两种字符集ANSI和UNICODE,前者就是通常使用的单字节方式,但这种方式处理象中文这样的双字节字符不方便,容易出现半个汉字的情况。而后者是双字节方式,方便处理双字节字符。WindowsNT的所有与字符有关的函数都提供两种方式的版本,而Windows9x只支持ANSI方式。_T一般同字常数相关,如_T("Hello"。如果你编译一个程序为ANSI方式,_T实际不起任何作用。而如果编译一个程序为UNICODE方式,则编译器会把"Hello"字符串以UNICODE方式保存。_T和_L的区别在于,_L不管你是以什么方式编译,一律以UNICODE方式保存.
Windows核心编程的第一章。
L是表示字符串资源为Unicode的。
比如
wchar_t Str[] = L"Hello World!";
这个就是双子节存储字符了。
_T是一个适配的宏~
当
#ifdef _UNICODE的时候
_T就是L
没有#ifdef _UNICODE的时候
_T就是ANSI的。
比如
LPTSTR lpStr = new TCHAR[32];
TCHAR* szBuf = _T("Hello");
以上两句使得无论是在UNICODE编译条件下都是正确编译的。
而且MS推荐你使用相匹配的字符串函数。
比如处理LPTSTR或者LPCTSTR 的时候,不要用strlen ,而是要用_tcslen
否则在UNICODE的编译条件下,strlen不能处理 wchar_t*的字符串。
T是非常有意思的一个符号(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一种中间类型,既不明确表示使用 MBCS,也不明确表示使用 UNICODE。那到底使用哪种字符集?编译的时候才决定
本文转自:
http://littlecity.blog.163.com/blog/static/3577802620093895941438/
posted @
2012-09-04 17:38 王海光 阅读(634) |
评论 (0) |
编辑 收藏
摘要: 最近有些人在问MFC编程一些要点,有一些句柄的获取、指针的获取是常见的问题,本文将对这些问题做以解释,参考了前人的笔录(见reference),希望能够帮助大家更方便地进行MFC程序开发。
一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架,无论是多文档还是单文档,都存在指针和句柄获取和操作...
阅读全文
posted @
2012-09-03 17:41 王海光 阅读(1151) |
评论 (0) |
编辑 收藏
摘要: Node.js Manual & DocumentationTable Of Contents
Synopsis 概要Global Objects 全局对象
globalprocessrequire()require.resolve()require.paths__filename__dirnamemoduleTimers 定时器
setTimeout(callback, ...
阅读全文
posted @
2012-08-30 12:31 王海光 阅读(12912) |
评论 (0) |
编辑 收藏
笔者现在了解一种比较简单的方法,即:
修改CXXAPP中的InitInstance函数,将原来的模态对话框改为非模态对话框,及修改
view plaincopy to clipboardprint?
INT_PTR nResponse = dlg.DoModal();
INT_PTR nResponse = dlg.DoModal();
为
view plaincopy to clipboardprint?
dlg.Create(CModalHideDlg::IDD); //创建为非模态对话框
dlg.ShowWindow(SW_HIDE); //创建完毕后,可以设置对话框的显示方式,正常为“SW_SHOW”,
//在此,我们使用“SW_HIDE”将对话框隐藏,但是在进程列表中仍然可以看到
dlg.RunModalLoop(); //消息循环
dlg.Create(CModalHideDlg::IDD); //创建为非模态对话框
dlg.ShowWindow(SW_HIDE); //创建完毕后,可以设置对话框的显示方式,正常为“SW_SHOW”,
//在此,我们使用“SW_HIDE”将对话框隐藏,但是在进程列表中仍然可以看到
dlg.RunModalLoop(); //消息循环
还有其他一些朋友的方法:
有很多应用程序要求一起动就隐藏起来,这些程序多作为后台程序运行,希望不影响其他窗口,
往往只在托盘区显示一个图标。这些程序通常都是对话框程序,而对话框在初始化的过程上与SDI
、MDI的初始化是不同的,对话框只需要DoModule或者是CreateDialog等等对话框函数调用一次便
可,SDI、MDI则要好几步才行。这样看来,对话框在使用方法上面是隐藏了不少细节的,其中就
没有SDI、MDI所要求的ShowWindow(nCmdShow)这一步。因此对话框要想一运行就隐藏,并不是很
直接的。有一些方法可以做到这一点,下面我们就来看看几种方案。
1.定时器
最直观,又是最无奈的一个方法就是使用定时器。既然我们在对话框开始显示之前不能用ShowWin
dow(SW_HIDE)将其隐藏,那就给一个时间让它显示,完了我们在隐藏它。
方法:
1.在OnInitDialog()函数里设置定时器:(WINDOWS API里面响应消息WM_INITDIALOG)
SetTimer(1, 1, NULL);
2.添加处理WM_TIMER的消息处理函数OnTimer,添加代码:
if(nIDEvent == 1)
{
DeleteTimer(1);
ShowWindow(SW_HIDE);
}
这种方法的缺点是显而易见的,使用定时器,使得程序的稳定性似乎打一个折扣;窗口是要先显
示出来的,那么效果就是窗口闪了一下消失。
2.改变对话框显示状况
在对话框初始化时改变其显示属性可以让它隐藏起来。方法是调用SetWindowPlacement函数:
BOOL CDialogExDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//DO something
WINDOWPLACEMENT wp;
wp.length=sizeof(WINDOWPLACEMENT);
wp.flags=WPF_RESTORETOMAXIMIZED;
wp.showCmd=SW_HIDE;
SetWindowPlacement(&wp);
return TRUE;
}
在需要显示时(通常是响应热键或者托盘图标的鼠标消息):
WINDOWPLACEMENT wp;
wp.length=sizeof(WINDOWPLACEMENT);
wp.flags=WPF_RESTORETOMAXIMIZED;
wp.showCmd=SW_SHOW;
SetWindowPlacement(&wp);
这样的效果很不理想:窗口显示在屏幕的左上角,并且是只有标题栏,要正常显示,还需加上如
下代码:
定义一个成员变量CRect rect;
在OnInitDialog()里面:
GetWindowRect(&rect);
在需要显示的地方:
SetWindowPos(&wndNoTopMost, wndRc.left, wndRc.top, wndRc.right, wndRc.bottom,
SWP_SHOWWINDOW);
CenterWindow();
即使这样,效果还是很差。
这种方法还有一个弊端是当程序开始运行并且隐藏起来后,原来激活的窗口变成了非激活状态了
,而当对话框显示出来后,对话框自身也是非激活状态的。
3.不绘制窗口
当对话框显示时将要响应消息WM_PAINT绘制客户区,相应消息WM_NCPAINT绘制窗口边框。我们在
窗口第一次自绘自身时隐藏窗口,可以收到比较良好的效果。由于窗口是先画窗口边框,所以我
们仅需处理WM_NCPAINT即可。代码如下:
添加WM_NCPAINT处理函数。
void CMyDialog::OnNcPaint()
{
static int i = 2;
if(i > 0)
{
i --;
ShowWindow(SW_HIDE);
}
else
CDialog::OnNcPaint();
}
这里有个问题:为什么要定义静态变量i而且设其值为2呢?
我们只要窗口隐藏第一次,所以定义这个变量可以判断是否时首次显示窗口。当程序开始运行时
,系统发送(SendMessage)WM_NCPAINT消息,此时程序的窗口边框应该被显示,但是此时我们没
有作任何显示的操作,而是将窗口隐藏,ShowWindow(SW_HIDE)将把窗口的WS_VISIBLE属性去掉,
继续执行,程序将检查WS_VISIBLE属性,如果没有则显示窗口,所以又发送了一个WM_NCPAINT消
息。所以我们要处理两次WM_NCPAINT消息。
在需要窗口显示时,调用ShowWindow(SW_SHOW)即可。
程序执行的结果是,原来处于激活状态的窗口可能会闪动两下,然后仍然处于激活状态。这种处
理方式比上面的方式要优越得多。
4.将对话框作为子窗口
这种方法是采用SDI框架,主窗口始终隐藏,对话框作为主窗口的成员变量,在CMainFrame::OnCr
eate()里面加入下代码:
if(!dlg.Create(IDD_MYDIALOG, this))
{
return –1;
}
dlg.ShowWindow(SW_HIDE);
在要显示对话框的地方用dlg.ShowWindow(SW_SHOW);即可。注意,主窗口一定要隐藏,否则对话
框可能会闪现一下。
隐藏状态栏窗口
上面介绍了几种检查对话框的方法,大家如果试过的话可能已经注意到系统状态栏里在程序启动
时会有程序的图标闪过,在隐藏对话框的时候这个也是要隐藏的,方法很简单:
在OnInitDialog()函数里面加上ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);即可。在
要显示窗口的地方加上代码ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);即将窗口的扩
展样式改回来。
以上是我的一点经验总结,有错误或不完善的地方还望大家提出指正。欢迎大家与我联系。
本文来自CSDN博客,转载请标明出处:http://www.cppblog.com/humanchao
posted @
2012-08-28 11:09 王海光 阅读(707) |
评论 (0) |
编辑 收藏
1、主程序
1 m_bStopMsg = TRUE;
2 HANDLE hPromptThread = StartPromptThread();
3 if (!hPromptThread)
4 {
5 LOG("启动导入数据提示框线程失败");
6 }
7
8 while (m_bStopMsg)
9 {
10 MSG msg;
11 ::GetMessage( &msg, this->m_hWnd, NULL, NULL );
12 ::TranslateMessage( &msg );
13 ::DispatchMessage( &msg );
14 }
2、启动线程
1 HANDLE CBarView::StartPromptThread()
2 {
3 LOG("启动导入数据提示线程");
4 CWinThread* hThread = AfxBeginThread((AFX_THREADPROC)CBarView::RunPromptDialog,(LPVOID)this);
5
6 return (m_hPromptThread = hThread->m_hThread);
7 }
3、线程函数
1 DWORD WINAPI CBarView::RunPromptDialog(LPVOID Param)
2 {
3 CBarView* barObj = (CBarView*)Param;
4 barObj->waitObj = new CImportDataPromptDialog();
5 barObj->waitObj->Create(IDD_DIALOGPROMPT, NULL);
6
7 barObj->waitObj->ShowWindow(SW_SHOW);
8
9 barObj->m_bStopMsg = FALSE;
10 return 0;
11 }
4、结束线程函数
1 void CBarView::StopThread()
2 {
3 if (NULL != waitObj)
4 {
5 delete waitObj;
6 }
7
8 if (m_hPromptThread != NULL)
9 {
10 ::TerminateThread(m_hPromptThread, 0 );
11 m_hPromptThread = NULL;
12 LOG("结束导入数据提示线程");
13 }
14 }
以下转自:
http://blog.csdn.net/hellothere/article/details/1788310
Windows多线程与对话框
Windows的对话框是获取信息输入的主要手段,增加线程则是获得更好UI响应的重要方式。由于Windows在处理对话框时进行线程调度的特殊性,如果不对此加以特别注意,增加线程可能不能带来UI响应的改善。
1 跨线程创建对话框
1.1 需求
有这样的应用场景:创建非模态对话框后需要马上做些耗时的工作,而同时又希望能够立刻在对话框上操作,所以,希望让非模态对话框工作在单独的线程上。
1.2 方案
主线程启动一个UI线程,并且,让这个线程创建非模态对话框。
想法是:既然用单独的线程创建了对话框,所以,主线程在创建UI线程后,就可以继续自己其他耗时的工作了。
1.3 实现
用一个简单的例子程序来试验这个方案:在VC++中创建一个基于SDI的MFC应用程序,在其CView派生类中处理“Call”菜单命令,创建派生自CWinThread的UI线程,在这个UI线程初始化过程中创建一个对话框。
1.3.1 单独的UI线程创建对话框
实现一个派生自CWinThread的UI线程类,其中最关键的是CreateMyDlg和DestroyMyDlg函数。
类如下
class UIWorker : public CWinThread
{
DECLARE_DYNCREATE(UIWorker)
protected:
UIWorker(); // protected constructor used by dynamic creation
// Attributes
public:
// Operations
public:
bool CreateMyDlg( void );
void SetOwnerWnd( HWND hWnd );
void DestroyMyDlg( void );
……
private:
CDlgUserTest* m_pDlgTest;
HWND m_hOwnerWnd;
};
CreateMyDlg和DestroyMyDlg的实现都非常简单
bool UIWorker::CreateMyDlg( void )
{
m_pDlgTest = new CDlgUserTest;
if ( NULL == m_pDlgTest )
{
return false;
}
CWnd* pWnd = NULL;
if ( NULL != m_hOwnerWnd )
{
pWnd = reinterpret_cast<CWnd*>( CWnd::FromHandle( m_hOwnerWnd ));
if ( NULL == pWnd )
{
return false;
}
}
BOOL bSuccess = m_pDlgTest->Create( IDD_DIALOG_TEST, pWnd );
if ( bSuccess )
{
bSuccess = m_pDlgTest->ShowWindow( SW_SHOW );
}
return bSuccess?true:false;
}
void UIWorker::DestroyMyDlg( void )
{
if ( NULL != m_pDlgTest )
{
delete m_pDlgTest;
m_pDlgTest = NULL;
}
}
1.3.2 主线程创建UI线程
主线程就更加简单了。在菜单的对应操作中,创建线程,为了表示主线程继续工作,提供一个循环。
bool CUserView::Call(void)
{
m_pUIWorker = static_cast<UIWorker*>( AfxBeginThread(
RUNTIME_CLASS( UIWorker )));
for ( int i = 0; i < 100000; ++i )
for ( int j = 0; j < 10000; ++j )
;
return true;
}
1.4 结果:奇怪的延迟
希望达到的效果是:
主程序启动后,显示一个单文档视界面,有一个Work菜单
点击Call菜单后,对话框应该马上弹出,显示为:
执行中,对话框不会马上弹出,而会等待一定的时间,直到循环结束,CUserView的Call函数返回,对话框才会弹出。等待的时间和循环的长短成正比。
2 问题分析
2.1 不单纯的对话框:要求Windows作特殊处理
对话框是一种很不单纯的窗口。无论是创建、消息分发还是销毁,Windows都会对对话框做一些特殊的处理。如果用SDK进行对话框编程,就会发现创建对话框需要专门的Win32 API。而且,我们查阅平台SDK的讲述时,也会发现对话框需要Windows进行若干额外的“照顾”。事实上,之所以会出现前述的“延迟”情况,就是Windows进行额外协调的结果。
2.2 窗口协调导致等待
2.2.1 Windows协调对话框弹出过程
使用SPY++研究窗口消息,会发现非模态对话框创建时,原来拥有焦点的窗口会收到WM_KILLFOCUS消息,而且获得焦点的窗口是创建的对话框。
2.2.2 线程需要分发消息,不能堵塞
根据例子来看,这个窗口焦点的协调过程被上升到了线程协调的层次。现象就是:如果被去激活的窗口的线程被阻塞,不能立刻处理WM_KILLFOCUS消息的话,创建对话框的线程也会被阻塞,对话框一直不能被显示出来,直到线程不再阻塞,WM_KILLFOCUS被分发和处理。
2.3 解决方案
这个问题产生的原因是:在主线程繁忙的时候有主线程必须要处理的消息,也就是主线程消息循环因为窗口处理函数占用时间过长而被阻塞。因此,这个问题更多是一个设计问题而非技术难点。也许,我们该问的是:
n 我真的要用一个冗长的工作来阻塞主线程这样长的时间吗?
n 我是否可以在单独的一个工作者线程中来处理这个长的工作?
考虑了其他的可能性后,如果对上述问题的答案仍然为“是”的话,可以采取以下解决方案:因为我们缺少的是消息循环,所以,加上消息循环,让对话框能够显示出来之后,再去进行其他工作的处理。
bool CUserView::Call(void)
{
m_pUIWorker = static_cast<UIWorker*>( AfxBeginThread(
RUNTIME_CLASS( UIWorker )));
while ( !m_pUIWorker->GetDoneFlag())
{
MSG msg;
::GetMessage( &msg, this->m_hWnd, NULL, NULL );
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
for ( int i = 0; i < 100000; ++i )
for ( int j = 0; j < 10000; ++j )
;
return true;
}
红色的代码就是加上消息循环。要注意的是,相应的线程类里面应该在显示出对话框后设置一个标志,并且让主线程可以查询到这个标志,从而终止这个临时的消息循环。
3 启示
3.1 Windows线程调度
Windows的线程调度原则对于程序员来说非常简单。这条原则是:程序员无法决定线程调度过程。
只是因为“程序员无法决定线程调度过程”,并不意味着程序员不应该去了解一些特别的线程调度过程。在某些场合下,正如上面在和对话框相关的某些时机,也许,Windows的线程调度是有明确规则的。所以,大多数情况下,程序员可以认为Windows的线程调度对于自己来说是一个黑盒。但是,某些时候,这个盒子中间发生的事情也需要了解和掌握。
3.2 对话框
对话框是一个古老的话题,很多的人仔细讨论了对话框的方方面面。对话框一直是Windows里面非常特殊的一种窗口。它的消息循环,与其他窗口的协调要求,都和普通的窗口有不同之处。因此,为了配合这些不同之处,Windows在线程协调上也做了一些手脚。
3.3 多线程编程更多是一种设计
更重要的启示是:多线程需要更多的考虑设计。
毫无疑问,多线程可以使多种工作并行进行,提高工作效率,改善界面响应。然而,多线程应用中一个麻烦的问题是:决定对哪些工作使用单独的线程。这个决定过程其实就是设计过程。如果设计方案不合理,比如,如本例子中反映出来的问题——在主线程被长时间的工作阻塞的情况下,增加的线程并不会给我们带来明显的响应改善。而且,如果设计方案不合理,会带来更多的“临时机制”的采用,如本例中必须增加一个单独的消息循环,并且需要在两个线程中就对话框是否创建出来进行通讯。这样的实现在很大程度上削减了希望用多线程带来的好处。
posted @
2012-08-20 12:45 王海光 阅读(2955) |
评论 (0) |
编辑 收藏
SQLite查询空值
1、当插入数据位空时(如:Second= “”),数据中显示内容为(null)。如图所示。
查询显示为空的列表:
1 select * from Test where Second is null
显示结果:
查询显示不为空的列表:
1 select * from Test where Second not null
2、当插入数据的字段不存在时,数据库中显示为空。如图所示。
查询显示为空的列表:
1 select * from Test where Second is ''
显示结果
查询显示不为空的列表:
1 select * from Test where Second <> ''
posted @
2012-08-10 14:15 王海光 阅读(2488) |
评论 (0) |
编辑 收藏
摘要: SQLite库可以解析大部分标准SQL语言。但它也省去了一些特性并且加入了一些自己的新特性。这篇文档就是试图描述那些SQLite支持/不支持的SQL语法的。查看关键字列表。
如下语法表格中,纯文本用蓝色粗体显示。非终极符号为斜体红色。作为语法一部分的运算符用黑色Roman字体表示。
这篇文档只是对SQLite实现的SQL语法的综述,有所忽略。想要得到更详细的信息,参考源代码和语法文件̶...
阅读全文
posted @
2012-08-10 13:23 王海光 阅读(982) |
评论 (0) |
编辑 收藏
为了在Ubuntu下安装那令人悲催的GCC,小弟可是绞尽脑汁,连干三天。。。当我搞清楚那些破软件m4,gmp mpfr,mpc等之间的依赖关系,依照强大的度娘提示下,安装了一遍又一边一边又一边·····它就是不成!shit!就当俺不得不做出抛弃GCC的念头之时,又是度娘! <!--[if !vml]--><!--[endif]--> 原来Ubuntu11.04自带GCC的!!! 在此建议各位大虾,在安装GCC之前,先check一下你的Linux中是否自带了GCC。 <!--[if !vml]-->
<!--[endif]-->
下面是小弟,在这悲催的三天所学到如何在Ubuntu下安装GCC的过程:
安装过程
第一步,从网站http://gcc.gnu.org 上下载文件gcc-4.6.0.tar.bz2
第二步,将该文件拖至tmp目录下。然后解压缩,在命令行tar vxjf gcc-4.1.1.tar.bz2,
解压后你可以看到在tmp目录下有gcc-4.6.0文件
第三步,对源文件进行配置,用命令
mkdir gcc-build
cd gcc-build
../gcc-4.6.0/configure --prefix=/usr/local/gcc-4.6.0 --enable-threads=posix --disable-checking --disable-multilib --enable-languages=c,c++
编译错误提醒:
<!--[if !vml]--><!--[endif]-->
提醒信息:configure: error: Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0+.
说明要安装gcc需要GMP、MPFR、MPC这三个库,于是又从网上下了三个库的压缩包。由于MPFR依赖GMP,而MPC依赖GMP和MPFR,所以要先安装GMP,其次MPFR,最后才是MPC。这里三个库我用的版本分别是gmp5.0.1,mpfr2.4.2和mpc0.8.1。
先开始安装GMP。解压GMP的压缩包后,得到源代码目录gmp-5.0.1。在该目录的同级目录下建立一个临时的编译目录,这里命名为gmp-build。然后开始配置安装选项,进入gmp-build目录,输入以下命令进行配置:
../gmp-5.0.1/configure --prefix=/usr/local/gmp-5.0.1
这里--prefix选项代表要将该库安装在哪里,我是装在/usr/local/gmp-5.0.1目录下,后面的安装都会用到这个选项。不过这里又出现问题了,系统提示缺少m4: gmp configure: error: No usable m4 in $PATH or /usr/5bin。m4是一个宏处理器。
在网上查了一下这个问题的解决办法,输入以下命令进行安装:
sudo aptitude install build-essential m4
或在系统自带的软件中心寻m4
<!--[if !vml]--><!--[endif]-->
再经历这一切之后在度娘的帮助下,终于明白其实正确的安装过程如下:
linux下软件的“安装”一般是需要3个步骤:
即configure,make和make install这三个命令编译,而安装的任何一个命令有疑问或者想查看命令相关的参数,都可以在命令后加” --help”参数来查看安装命令需要的参数。
其次需要说明的是,由于可能存在任何可能的情况,configure,make和make install这三个命令都有可能报错,如果出错,终端会给出错误的信息,也就是error的提示,你需要针对错误的类型去解决安装中存在的问题,有问题的话可以在baidu或者google上搜搜出错信息看看,应该有你要的答案,但是建议在google上搜。Linux是开源的,全世界的客户多不胜数。遇到和你同样的问题的人一定存在。所以,有什么error有什么问题,尽管找度娘,股沟。上面的资料十分的多。也可以到相关的Ubuntu论坛上去找,例如:http://forum.ubuntu.org.cn/index.php?sid=c9ccb2d7adcf8fdb78ac99d75581a332 好了,继续话题。。。。。
1,安装GCC需要四个相关的软件:
m4(即an implementation of the traditional Unix macro processor)、
gmp(即GNU Multiple Precision Arithmetic Library)、
mpfr(即multiple-precision floating-point computations with correct rounding)
mpc(即C library for the arithmetic of complex numbers with arbitrarily high precision and correct rounding
下载3个软件包及安装参考http://www.comdyn.cn/from-web/68-server-setup/164-centos-48-gcc450.html
他们的依赖关系如右图-----------
按照从内圈到外圈的顺序安装(gmp的安装需要m4,而mpfr依赖gmp,而mpc依赖gmp和mpfr,所以要先安装m4,其次装gmp,再其次mpfr,最后是mpc)
我安装的后三个库的版本分别是 <!--[if !vml]--><!--[endif]-->
<!--[if !supportLists]-->(I) <!--[endif]-->m4的安装,首先需要说明的是,如果不安装m4,在安装gmp的时候系统会提示“m4: gmp configure: error: No usable m4 in $PATH or /usr/5bin”的错误。因此首先需要安装m4,命令如下
tar –zxvf m4.tar.gz 先解压缩,然后进入到m4目录
./configure CC=”cc”
make
make install
由于没有指定安装目录,因此安装好后,可以查看默认的/usr/local/bin目录下,有一个m4的可执行文件,网上资料说这是一个宏处理器。
<!--[if !supportLists]-->(II) <!--[endif]-->gmp的安装,后面的安装都是装到了指定目录下,所以我都是用root超级用户操作的,用su命令切换到超级用户。由于我是将gmp,mpfr和mpc分别安装到了/usr/local/gmp432,/usr/local/mpfr242和/usr/local/mpc082目录下,因此需要先进入/usr/local/目录下,以超级用户运行
mkdir gmp432 mkdir是创建目录命令,即先创建安装目录,你也可以在任意目录下建
mkdir mpfr242
mkdir mpc081
完成以后,进入到gmp-4.3.2.tar.gz所在的目录下,开始安装gmp,
tar –vxzf gmp-4.3.2.tar.bz2 再压缩,然后进入到gmp-4.3.2目录
cd gmp-4.3.2 (不知道怎么安装的可以看一下解压缩后该目录下的INSTALL文件)
./configure --prefix=/usr/local/gmp432
make
make check
make install
安装好后,可以查看/usr/local/gmp432目录下有三个文件夹
<!--[if !supportLists]-->(III) <!--[endif]-->mpfr的安装,
tar –vxzf mpfr-2.4.2.tar.bz2 先解压缩,然后进入到mpfr-2.4.2目录
cd mpfr-2.4.2
./configure --prefix=/usr/local/mpfr432 --with-gmp=/usr/local/gmp432
make
make check
make install
mpc的安装,(仍然在超级用户下操作),同样,不知道怎么安装的可以看一下解压缩后的INSTALL文件,
tar –zxvf mpc-0.8.1.tar.gz 先解压缩,然后进入到mpc-0.8.2目录
cd mpc-0.8.1
./configure --prefix=/usr/local/mpc-0.8.1 --with-gmp=/usr/local/gmp432 --with-mpfr=/usr/local/mpfr242
make
make check
make install
安装好这三个库之后,就可以正式开始安装gcc了。
与此前一样,在gcc解压后的文件夹的同级目录下,建一个编译gcc的临时目录:gcc-build。
mkdir gcc-build
cd gcc-build
<!--[if !vml]--><!--[endif]-->
进入该目录后配置安装选项:
../gcc-4.6.0/configure --prefix=/usr/local/gcc-4.6.0 --enable-threads=posix --disable-checking --disable-multilib --enable-languages=c,c++
--with-gmp=/usr/local/gmp-5.0.1 --with-mpfr=/usr/local/mpfr-2.4.2 --with-mpc=/usr/local/mpc-0.8.1
gcc的配置选项有很多,具体可以参考gcc源文件目录下的安装说明。这里只安装了c和c++的编译器。然后开始make编译。本来以为就可以大功告成了,结果在编译途中又出现了错误:error while loading shared libraries: libmpc.so.2: cannot open shared object file: No such file or directory
在网上找到了解决方法,需要添加环境变量LD_LIBRARY_PATH以指出前面三个库的位置,键入以下命令:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/mpc-0.8.1/lib:/usr/local/gmp-5.0.1/lib:/usr/local/mpfr-2.4.2/lib
然后运行
make
然后就耐心等待。。。。。。。。。
在经过漫长的2小时等待后,终于编译完成。在安装说明里面还有测试这一步,不过那是可选的,我也没耐心去测试了。直接make install安装,至此gcc就全部安装完成了。不过目前还不能使用新版本的gcc,因为新版的可执行文件还没加到命令的搜索路径中。在这里我为新版的gcc和g++命令分别建立了一个软链接。进入/usr/bin目录后,键入如下命令建立软链接。
sudo ln -s /usr/local/gcc-4.5.0/bin/gcc gcc45
sudo ln -s /usr/local/gcc-4.5.0/bin/g++ g++45
这样我使用新版本gcc的时候就可以用gcc45和g++45命令,同时也可使用原来的gcc编译程序。当然这里也可以直接将/usr/bin目录下gcc,g++命令重新链接到新版本的gcc可执行文件。在正式使用之前还有最后一个工作要做,就是将前面安装的三个库的路径加进环境变量LD_LIBRARY_PATH中,不然在编译程序的时候会出错。由于我不想每次编译程序都生成环境变量,所以需要编辑/etc目录下的bash.bashrc文件配置shell环境。在这个文件中添加以下语句:
LD_LIBRARY_PATH=:/usr/local/mpc-0.8.1/lib:/usr/local/gmp-5.0.1/lib:/usr/local/mpfr-2.4.2/lib:/usr/local/gcc-4.5.0/lib
export LD_LIBRARY_PATH
保存重启系统后,就可以使用新装的gcc了。
需要说明的是,gcc的配置选项有很多,具体可以参考gcc源文件目录下的安装说明。这里只安装了c和c++的编译器。然后开始make编译。
在正式使用之前还有最后一个工作要做,就是将前面安装的三个库的路径加进环境变量LD_LIBRARY_PATH中,不然在编译程序的时候会出错。由于我不想每次编译程序都生成环境变量,所以需要编辑/etc目录下的bash.bashrc文件配置shell环境。在这个文件中添加以下语句:
LD_LIBRARY_PATH=:/usr/local/mpc-0.8.1/lib:/usr/local/gmp-5.0.1/lib:/usr/local/mpfr-2.4.2/lib:/usr/local/gcc-4.5.0/lib
export LD_LIBRARY_PATH
保存重启系统后,就可以使用新装的gcc了。
需要说明的是,如果make出错,需要重新configure的话,先运行一下make distclean来清除make的信息,再重新configure。
解压缩*.tar.gz的命令是tar –zxvf *.tar.gz
解压缩*.tar.bz2的命令是tar -jxvf *.tar.bz2
安装完成好以后可以用 which gcc查看是否安装好,命令运行后终端显示出安装gcc的路径。
<!--[if !vml]--><!--[endif]-->
打完,收工·······
本文转自:http://ohyeahbbs.blog.51cto.com/1775490/568462
posted @
2012-07-28 22:56 王海光 阅读(1648) |
评论 (1) |
编辑 收藏
获取本机IP地址
1 CString sLoginUser;
2 CString sLocalIP;
3 WORD wVersionRequested;
4 WSADATA wsaData;
5 wVersionRequested = MAKEWORD( 2, 0 );
6
7 if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
8 {
9 sLoginUser.TrimLeft();
10 sLoginUser.TrimRight();
11 sLocalIP = CCommonFun::ConvertHostNameToIP(sLoginUser);
12
13 WSACleanup( );
14 }
在CCommonFun类中:
1 CString CCommonFun::ConvertHostNameToIP( const CString &sHostName )
2 {
3 CString sIP;
4
5 HOSTENT *host_entry = gethostbyname(sHostName);
6 if( host_entry != 0 )
7 {
8 sIP.Format("%d.%d.%d.%d",
9 (host_entry->h_addr_list[0][0]&0x00ff),
10 (host_entry->h_addr_list[0][1]&0x00ff),
11 (host_entry->h_addr_list[0][2]&0x00ff),
12 (host_entry->h_addr_list[0][3]&0x00ff));
13 }
14
15 return sIP;
16 }
直接获取:
1 #include "winsock.h"
2
3 WORD wVersionRequested;
4 WSADATA wsaData;
5 char name[255];
6 CString ip;
7 PHOSTENT hostinfo;
8 wVersionRequested = MAKEWORD( 2, 0 );
9
10 if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
11 {
12 if( gethostname ( name, sizeof(name)) == 0)
13 {
14 if((hostinfo = gethostbyname(name)) != NULL)
15 {
16 ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
17 }
18 }
19
20 WSACleanup( );
21 }
posted @
2012-07-18 18:13 王海光 阅读(4303) |
评论 (0) |
编辑 收藏
什么样的程序员称得上优秀,根据我所看到,有如下体会:
1、不愿意将就的人
程序设计工作是一项地地道道的脑力劳动,把工作做得很好和做的很差往往只在工作中的一个小小的细节,我发现我身边优秀的程序员都不太喜欢将就,始终把自己的计算机和自己的开发环境调整到最佳状态,原来带我的老员工甚至会自己写一些小工具,来提高工作效率。
2、不喜欢蛮干
脑力劳动与体力劳动不同,很多时候很难通过简单的量的积累达到目的,尤其是处理一些难题的时候。一味的强调蛮干,加班几乎天生与高手无缘。没有思路的时候,换个环境,也许答案就在明天上班的路上想起。
3、愿意思考、专注改进
程序员与其他劳动者相似,熟练了以后都会形成惯性思维,会不自觉的用自己习惯的方式解决问题,但问题的形式与本质总会变化,只有不断的改进才能使工作效率不断提高。而把脑力劳动变成体力劳动的现象在实际工作中比比皆是。
4、良好的基础和不断的学习
良好的基础与不断的学习是天生的一对孪生兄弟,因为基础好所以学的快,因为学得快,所以基本功好。良好学习习惯不是不停的简单追踪新技术,一方面是了解新技术,另一方面需要不断的弥补思维盲区,学习可以有很多种状态,有一种是闻一而知一,技也,有一种是闻一而知三,术也,有一种是闻一而知十,道也。
5、直接切入问题的能力
在解决一个问题的时候,有些人总是能够直接切入问题核心,而有些人总是喜欢关注边缘问题。直入主题是一种核心能力,需要思考,实践,改进,积累,提高,周而复使,螺旋上升。另外我觉得这与思维方式与知识面关系很大,多涉猎一些领域没有坏处。
***英语***:呵呵,对,还是英语,流利的听说读写。
本文来自CSDN博客,转载请标明出处:http://www.cppblog.com/humanchao
posted @
2012-07-17 08:13 王海光 阅读(440) |
评论 (1) |
编辑 收藏