关注 ASM/C/C++
提示:
访客留言
佛学佳句
室内装潢
《IT公司速查手册》
有C/C++问题去『vckbase』
看美女去『千帆论坛』
VCKBASE网友照片集
专门保存代码片断
bruceteen的方法(使用一个如此设置的local):#include <iostream>#include <locale>
int main( void ){ using namespace std;
cout << 1389992 << endl; // 1389992
locale chs( "chs" ); // chs在我这里行,不知道你那里怎么样 cout.imbue( chs ); cout << 1389992 << endl; // 1,389,992}
特别推荐 namtso的方法(自己订制local):#include <iostream>#include <string>#include <locale>using namespace std;
class thousands_sep_facet:public std::numpunct<char>{public: explicit thousands_sep_facet( size_t r=0 ) : std::numpunct<char>(r) { }protected: string do_grouping() const { return "\003"; }};
int main( void ){ cout << 1389992 << endl; // 1389992
locale loc( locale(), new thousands_sep_facet ); std::cout.imbue( loc ); cout << 1389992 << endl; // 1,389,992
return 0;}
#include <iostream>using namespace std;
static void* funaddr_;static void* retaddr_;static int retvalue_;__declspec(naked) int a( const char* _Format, ... ){ cout << "[Begin]" << endl;
funaddr_ = &printf; __asm { pop retaddr_ call funaddr_ mov retvalue_, eax push retaddr_ }
cout << "[End]" << endl;
__asm { mov eax, retvalue_; ret }}
int main( void ){ int n = a( "%d\n", 123 ); cout << n << endl;
http://www.vckbase.com/bbs/viewtopic.asp?id=3137365&pg=1回复:vckbase的消息有时不会弹出来,今天才看到你发的消息
1。inline只是一个“建议”,到底是否内联,是否不内联,完全取决于编译器。2。inline在绝大部分情况下会提高运行时效率,但这不是绝对的,这取决于CPU。
3。为了测试,首先要解决第1个问题,VC++2005中使用__forceinline来强迫内联,使用__declspec(noinline)来强迫不内联
4。内联产生的效率提升是很小的,必须使用高精密的计时器,clock肯定不行^_^
5。还需要考虑编译器的代码优化,检验方法就是查看生成的汇编代码,看看是否真的内联了,是否真的未内联
6。现在的CPU运行时预测会影响到运行效率,所以待测试的代码必须先进行一次试运行,而后才能分辨运行效率
-------------------------以下是我的测试代码,在我的CPU上能够明显看得出效率差别:测试环境:VC++2005(SP1)、CPU PM 2.00Ghz
#include <windows.h>#include <stdio.h>class showtime_{public: showtime_() { QueryPerformanceFrequency( (LARGE_INTEGER*)&frequency_ ); QueryPerformanceCounter( (LARGE_INTEGER*)&time1_ ); GetThreadTimes( GetCurrentThread(), (LPFILETIME)&ftCreationTime1_, (LPFILETIME)&ftExitTime1_, (LPFILETIME)&ftKernelTime1_, (LPFILETIME)&ftUserTime1_ ); } ~showtime_() { QueryPerformanceCounter( (LARGE_INTEGER*)&time2_ ); GetThreadTimes( GetCurrentThread(), (LPFILETIME)&ftCreationTime2_, (LPFILETIME)&ftExitTime2_, (LPFILETIME)&ftKernelTime2_, (LPFILETIME)&ftUserTime2_ ); printf( "PerformanceCounter: %lf\n", (time2_-time1_)*1.0/frequency_ ); printf( "Kernel: %llu.%07llu; User: %llu.%07llu; Total: %llu.%07llu\n\n" , (ftKernelTime2_-ftKernelTime1_)/10000000, (ftKernelTime2_-ftKernelTime1_)%10000000 , (ftUserTime2_-ftUserTime1_)/10000000, (ftUserTime2_-ftUserTime1_)%10000000 , (ftKernelTime2_-ftKernelTime1_+ftUserTime2_-ftUserTime1_)/10000000, (ftKernelTime2_-ftKernelTime1_+ftUserTime2_-ftUserTime1_)%10000000 ); }private: unsigned long long frequency_, time1_, time2_; unsigned long long ftCreationTime1_,ftExitTime1_,ftCreationTime2_,ftExitTime2_; unsigned long long ftKernelTime1_,ftUserTime1_,ftKernelTime2_,ftUserTime2_;};#define showfollowtime showtime_ _;
struct foo1{ foo1() : value(0) {}
__forceinline void bar() // 强制内联 { ++value; } int value;};
struct foo2{ foo2() : value(0) {}
void bar(); int value;};__declspec(noinline) void foo2::bar() // 强制不内联{ ++value;}
int main( void ){ // 试运行,见6 { foo1 a; for(int i = 0; i < 10000000; i++) { a.bar(); } printf( "%d\n", a.value ); // 防止编译器优化直接给出a.value的数值,而不是运行时计算。下同 } { foo2 a; for(int i = 0; i < 10000000; i++) { a.bar(); } printf( "%d\n\n", a.value ); }
printf( "%s\n", "inline" ); Sleep(0); // 消除剩余时间片,使得结果更准确。下同 { showfollowtime
foo1 a; for(int i = 0; i < 10000000; i++) { a.bar(); } printf( "%d\n", a.value ); }
printf( "%s\n", "non-inline" ); Sleep(0); { showfollowtime
foo2 a; for(int i = 0; i < 10000000; i++) { a.bar(); } printf( "%d\n", a.value ); }
printf( "%s\n", "inline" ); Sleep(0); { showfollowtime
foo1 a; for(int i = 0; i < 10000000; i++) { a.bar(); } printf( "%d\n", a.value ); }}
#include <time.h>#include <math.h>
bool lotus2time( double dtSrc, struct tm& tmDest ){ const long MIN_DATE = -657434L; const long MAX_DATE = 2958465L; const double HALF_SECOND = 1.0/172800.0; const long month_days[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
if( dtSrc>MAX_DATE || dtSrc<MIN_DATE ) return false;
bool bLeap4 = true; double dblDate = dtSrc + ((dtSrc > 0.0) ? HALF_SECOND : -HALF_SECOND); long nDays = (long)dblDate; long nDaysAbsolute = (long)dblDate + 693959L; dblDate = fabs(dblDate); long nSecsInDay = (long)((dblDate - floor(dblDate)) * 86400.); tmDest.tm_wday = (int)((nDaysAbsolute - 1) % 7L); long n400Years = (long)(nDaysAbsolute / 146097L); nDaysAbsolute %= 146097L; long n400Century = (long)((nDaysAbsolute - 1) / 36524L);
long n4Years; long n4Day; if (n400Century != 0) { nDaysAbsolute = (nDaysAbsolute - 1) % 36524L; n4Years = (long)((nDaysAbsolute + 1) / 1461L); if (n4Years != 0) n4Day = (long)((nDaysAbsolute + 1) % 1461L); else { bLeap4 = false; n4Day = (long)nDaysAbsolute; } } else { n4Years = (long)(nDaysAbsolute / 1461L); n4Day = (long)(nDaysAbsolute % 1461L); }
long n4Yr; if (bLeap4) { n4Yr = (n4Day - 1) / 365;
if (n4Yr != 0) n4Day = (n4Day - 1) % 365; } else { n4Yr = n4Day / 365; n4Day %= 365; }
tmDest.tm_yday = (int)n4Day + 1; tmDest.tm_year = n400Years * 400 + n400Century * 100 + n4Years * 4 + n4Yr;
if (n4Yr == 0 && bLeap4) { if (n4Day == 59) { tmDest.tm_mon = 2; tmDest.tm_mday = 29; goto DoTime; }
if (n4Day >= 60) --n4Day; }
++n4Day;
for (tmDest.tm_mon = (n4Day >> 5) + 1; n4Day > month_days[tmDest.tm_mon]; tmDest.tm_mon++);
tmDest.tm_mday = (int)(n4Day - month_days[tmDest.tm_mon-1]);
DoTime: if (nSecsInDay == 0) tmDest.tm_hour = tmDest.tm_min = tmDest.tm_sec = 0; else { tmDest.tm_sec = (int)nSecsInDay % 60L; long nMinutesInDay = nSecsInDay / 60L; tmDest.tm_min = (int)nMinutesInDay % 60; tmDest.tm_hour = (int)nMinutesInDay / 60; }
tmDest.tm_mon -= 1; tmDest.tm_year -= 1900; tmDest.tm_yday -= 1; tmDest.tm_isdst = 0; return true;}
#include <stdio.h>int main(){ struct tm t; lotus2time( 39354.849004629628, t ); printf( "%04d-%02d-%02d %02d:%02d:%02d\n", t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec ); printf( "星期%d, 本年第%d天\n", t.tm_wday, t.tm_yday+1 );
//#include <stdio.h>//#include <conio.h>////int main( )//{// for( ; ; )// {// int n = _getch();// switch( n )// {// case 0x00:// case 0xE0:// printf( "%02X %02X\n", n, _getch() );// break;// default:// printf( "%02X\n", n );// }// }//// return 0;//}
#include <windows.h>#include <stdio.h>
BOOL WINAPI csl_handler_routine( DWORD CtrlType ){ switch( CtrlType ) { case CTRL_C_EVENT: case CTRL_BREAK_EVENT: case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: // release resource SetConsoleCtrlHandler( &csl_handler_routine, FALSE ); break; } return FALSE;}
HANDLE hOutput_ = ::GetStdHandle(STD_OUTPUT_HANDLE);HANDLE hInput_ = ::GetStdHandle(STD_INPUT_HANDLE);COORD dwSize = { 60, 16 };SHORT baselinenum = 0;
BOOL SetCursorPosition( SHORT x, SHORT y ){ COORD cd = { x, y+baselinenum }; return ::SetConsoleCursorPosition( hOutput_, cd );}
BOOL EarseTail( void ){ CONSOLE_SCREEN_BUFFER_INFO info; BOOL f = ::GetConsoleScreenBufferInfo( hOutput_, &info ); printf( "%*s", dwSize.X-info.dwCursorPosition.X, "" ); return f;}
BOOL SetTextAttrib( WORD wAttributes ){ return ::SetConsoleTextAttribute( hOutput_, wAttributes );}
void ShowControlKeyState( DWORD dwControlKeyState ){ SetTextAttrib( FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED ); printf( "" ); EarseTail(); printf( "CAPS LOCK : %s", (dwControlKeyState&CAPSLOCK_ON )?"ON":"OFF" ); EarseTail(); printf( "Enhanced : %s", (dwControlKeyState&ENHANCED_KEY )?"ON":"OFF" ); EarseTail(); printf( "ALT Left : %s", (dwControlKeyState&LEFT_ALT_PRESSED )?"ON":"OFF" ); EarseTail(); printf( "CTL Left : %s", (dwControlKeyState&LEFT_CTRL_PRESSED )?"ON":"OFF" ); EarseTail(); printf( "NUM LOCK : %s", (dwControlKeyState&NUMLOCK_ON )?"ON":"OFF" ); EarseTail(); printf( "ALT Right : %s", (dwControlKeyState&RIGHT_ALT_PRESSED )?"ON":"OFF" ); EarseTail(); printf( "CTL Right : %s", (dwControlKeyState&RIGHT_CTRL_PRESSED)?"ON":"OFF" ); EarseTail(); printf( "SCROLL LOCK: %s", (dwControlKeyState&SCROLLLOCK_ON )?"ON":"OFF" ); EarseTail(); printf( "Shift : %s", (dwControlKeyState&SHIFT_PRESSED )?"ON":"OFF" ); EarseTail();}void ShowMouseInfo( MOUSE_EVENT_RECORD& mer ){ SetTextAttrib( FOREGROUND_BLUE|FOREGROUND_GREEN/*|FOREGROUND_RED*/ | FOREGROUND_INTENSITY ); printf( "MousePosition: %03hd, %03hd", mer.dwMousePosition.X, mer.dwMousePosition.Y ); EarseTail(); printf( "ButtonState: Left=%c Right=%c", (mer.dwButtonState&FROM_LEFT_1ST_BUTTON_PRESSED)?'T':'F', (mer.dwButtonState&RIGHTMOST_BUTTON_PRESSED)?'T':'F' ); EarseTail(); printf( "EventFlags: " ); switch( mer.dwEventFlags ) { case 0 : printf( "Pressed or Released" ); EarseTail(); break; case DOUBLE_CLICK : printf( "double click " ); EarseTail(); break; case MOUSE_MOVED : printf( "mouse moved " ); EarseTail(); break; case MOUSE_WHEELED: printf( "mouse wheeled " ); EarseTail(); break; }
ShowControlKeyState( mer.dwControlKeyState );}
void ShowKeyInfo( KEY_EVENT_RECORD& ker ){ SetTextAttrib( FOREGROUND_BLUE/*|FOREGROUND_GREEN*/|FOREGROUND_RED | FOREGROUND_INTENSITY ); printf( "KeyDown: %c , Repeat Count: %d", ker.bKeyDown?'T':'F', ker.wRepeatCount ); EarseTail(); printf( "VirtualKeyCode: %02X, wVirtualScanCode: %02X", ker.wVirtualKeyCode, ker.wVirtualScanCode ); EarseTail(); printf( "AsciiChar: %c", ker.uChar.AsciiChar ); EarseTail();
ShowControlKeyState( ker.dwControlKeyState );}
int main( ){ // quit ctrl SetConsoleCtrlHandler( &csl_handler_routine, TRUE );
// set window title ::SetConsoleTitle( TEXT("Test") );
// get begin line number CONSOLE_SCREEN_BUFFER_INFO sinfo; ::GetConsoleScreenBufferInfo( hOutput_, &sinfo ); baselinenum = sinfo.dwCursorPosition.Y;
// hide cursor CONSOLE_CURSOR_INFO cinfo; ::GetConsoleCursorInfo( hOutput_, &cinfo ); cinfo.bVisible = FALSE; ::SetConsoleCursorInfo( hOutput_, &cinfo );
// set window size SMALL_RECT winsize = { 0, 0, dwSize.X-1, dwSize.Y-1 }; ::SetConsoleWindowInfo( hOutput_, TRUE, &winsize ); ::SetConsoleScreenBufferSize( hOutput_, dwSize );
// enable mouse & window DWORD mode; ::GetConsoleMode( hInput_, &mode ); mode |= ( ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT ); ::SetConsoleMode( hInput_, mode );
// get mouse & key INPUT_RECORD ir; DWORD index = 1; for( DWORD n; ReadConsoleInput(hInput_,&ir,1,&n); ++index ) { SetCursorPosition( 0, 0); printf( "%d", index ); EarseTail();
switch( ir.EventType ) { case MOUSE_EVENT: ShowMouseInfo( ir.Event.MouseEvent ); break; case KEY_EVENT: ShowKeyInfo( ir.Event.KeyEvent ); break; } }
// release resource // restore console setting
// 非类成员形式的operator new的伪代码:void* operator new( size_t size ) // 包括其他形式{ if( 0 == size ) size = 1;
while(1) { 分配size字节内存; if(分配成功) return 指向内存的指针;
new_handler globalhandler = set_new_handler(0); set_new_handler(globalhandler);
if( globalhandler ) (*globalhandler)(); else throw std::bad_alloc(); }}void operator delete( void* raw ){ if( 0 == raw ) return;
...}
// 特定类的operator new的伪代码struct base{ ... static void* operator new( size_t size );};void* base::operator new( size_t size ){ if( sizeof(base) != size ) return ::operator new(size);
同上}void base::operator delete( void* raw ){ if( 0 == raw ) return; if( sizeof(base) != size ) { ::operator delete(raw); return; }
#include <stdio.h>#include <assert.h>#include <windows.h>
HANDLE hInput;HANDLE hOutput;CONSOLE_CURSOR_INFO cursor_info;CONSOLE_SCREEN_BUFFER_INFO screen_info;DWORD mode;
// 设置控制台void Init( void ){ // 得到控制台输入输出句柄 hInput = ::GetStdHandle(STD_INPUT_HANDLE); hOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); assert( hInput != INVALID_HANDLE_VALUE ); assert( hOutput != INVALID_HANDLE_VALUE );
// 隐藏光标 BOOL f = ::GetConsoleCursorInfo( hOutput, &cursor_info ); assert( f ); CONSOLE_CURSOR_INFO cursor_info_new = cursor_info; cursor_info_new.bVisible = FALSE; f = ::SetConsoleCursorInfo( hOutput, &cursor_info_new ); assert( f );
// 得到控制台输出银屏缓冲信息 ::GetConsoleScreenBufferInfo( hOutput, &screen_info );
// 允许鼠标输入 f = ::GetConsoleMode( hInput, &mode ); assert( f ); f = ::SetConsoleMode( hInput, mode|ENABLE_MOUSE_INPUT ); assert( f );}
// 复原控制台void restore( void ){ ::SetConsoleMode( hInput, mode ); ::SetConsoleCursorInfo( hOutput, &cursor_info ); COORD cd = { 0, screen_info.dwCursorPosition.Y+2 }; ::SetConsoleCursorPosition( hOutput, cd );}
// 用于处理ctrl+c方式的退出BOOL WINAPI CTRL_C_Routine( DWORD dwCtrlType ){ if( dwCtrlType == CTRL_C_EVENT ) { // 复原控制台各项属性 restore(); // 卸载CTRL+C处理函数 ::SetConsoleCtrlHandler( &CTRL_C_Routine, FALSE ); }
return FALSE;}
// 获取鼠标所在位置的点颜色int main( void ){ // 初始化控制台各项属性 Init();
// 安装CTRL+C处理函数 BOOL f = ::SetConsoleCtrlHandler( &CTRL_C_Routine, TRUE ); assert( f );
// 得到桌面DC HWND hwnd = ::GetDesktopWindow(); HDC hdc = ::GetWindowDC( hwnd ); assert( hdc != 0 );
// 提示信息 puts( "press ESC key to quit." ); puts( "press mouse left key and move ..." );
// 获得键盘及鼠标输入 INPUT_RECORD ir; for( DWORD n; ReadConsoleInput(hInput,&ir,1,&n) && n==1; ) { // 跳到第1行第0列 COORD cd = { 0, screen_info.dwCursorPosition.Y+1 }; f = ::SetConsoleCursorPosition( hOutput, cd ); assert( f );
if( ir.EventType == MOUSE_EVENT ) // 鼠标信息 { if( ir.Event.MouseEvent.dwEventFlags == MOUSE_MOVED ) // 鼠标移动 { if( ir.Event.MouseEvent.dwButtonState&FROM_LEFT_1ST_BUTTON_PRESSED ) // 鼠标左键按下 { // 得到鼠标位置(非控制台) POINT pt; f = ::GetCursorPos( &pt ); assert( f ); // 得到鼠标颜色 COLORREF rgb = ::GetPixel( hdc, pt.x, pt.y ); assert( rgb != CLR_INVALID ); // 输出信息 int num = printf( "POINT(%ld,%ld): RGB(%u,%u,%u)", pt.x, pt.y, GetRValue(rgb), GetGValue(rgb), GetBValue(rgb) ); // 擦除尾部残余 printf( "%*s", screen_info.dwSize.X-num, "" ); } else { // 提示信息 int num = printf( "%s", "press mouse left key and move ..." ); // 擦除尾部残余 printf( "%*s", screen_info.dwSize.X-num, "" ); } } } else if( ir.EventType == KEY_EVENT ) // 键盘信息 { if( ir.Event.KeyEvent.wVirtualKeyCode == 0x1B ) break; } }
// 复原控制台各项属性 restore();}
建一个win32 dll空的工程,加入如下两个文件//a.cppextern "C" __declspec(dllexport) int __stdcall test( int a, int b ){ return a+b;}
//a.defLIBRARY aEXPORTS test @1
然后编译联结就得到 a.dll。附:a. 用 depends.exe 可以查看其导出函数。b. 如果是vc8,需要打开工程属性页 configuration properties->Linker->Input->Module Definition File输入a.defc. 如果需要进程线程控制,加入如下函数BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}
#include <windows.h>#include <tlhelp32.h>#include <iostream>#include <iomanip>#include <list>#pragma comment(lib, "psapi")
bool GetProcessList( std::list<PROCESSENTRY32>& pcslst ){ pcslst.clear();
HANDLE hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if( hProcessSnap != INVALID_HANDLE_VALUE ) { PROCESSENTRY32 pe32 = {0}; pe32.dwSize = sizeof(PROCESSENTRY32); if( Process32First(hProcessSnap,&pe32) ) { do { pcslst.push_back( pe32 ); } while( Process32Next(hProcessSnap,&pe32) ); CloseHandle( hProcessSnap ); return true; } CloseHandle( hProcessSnap ); } return false;}void ShowProcessList( void ){ std::list<PROCESSENTRY32> pcslst; if( GetProcessList(pcslst) ) { for( std::list<PROCESSENTRY32>::iterator itor=pcslst.begin(); itor!=pcslst.end(); ++itor ) { std::cout << itor->th32ParentProcessID << " " << itor->th32ProcessID << " " << itor->szExeFile << '\n'; } }}void ShowProcessTree( void ){ using namespace std;
struct ShowSubProcessTree { void operator()( std::list<PROCESSENTRY32>& pcslst, PROCESSENTRY32& pe32, std::streamsize spacenum ) { cout << setw(spacenum) << setfill(' ') << ""; cout << pe32.th32ProcessID << ": " << pe32.szExeFile << '\n';
for( std::list<PROCESSENTRY32>::iterator itor=pcslst.begin(); itor!=pcslst.end(); ++itor ) { if( itor->th32ProcessID!=itor->th32ParentProcessID && itor->th32ParentProcessID==pe32.th32ProcessID ) { ShowSubProcessTree()( pcslst, *itor, spacenum+4 ); } &nbs