📄 subject_67092.htm
字号:
<p>
序号:67092 发表者:badboy 发表日期:2003-12-29 12:32:45
<br>主题:函数里的形参里有“, ...”你见过吗?
<br>内容:下面有个程序的源代码,其中有个函数void AddStr (LPCTSTR szFmt, ...) ,您<BR><BR>见过这种形式的参数定义吗? 后面那三个点想干什么?在下面的代码中还真有那<BR><BR>么多调用这个函数AddStr()时,还真要这么用,源代码的作者想干什么?AddStr<BR><BR>(__TEXT("%04lu: Leaving checkout counter."),nShopperNum);<BR>AddStr(__TEXT("%04lu: Checking out (%lu)."),nShopperNum, nDuration); <BR><BR> <BR><BR><BR><BR><BR>/***********************************************************<BR>Module name: SprMrkt.C<BR>Notices: Copyright (c) 1995-1997 Jeffrey Richter<BR>***********************************************************/<BR><BR><BR>#include "..\CmnHdr.H" /* See Appendix C. */<BR>#include <windows.h><BR>#include <windowsx.h><BR>#include <tchar.h><BR>#include <stdio.h><BR>#include <stdlib.h> // For random number stuff<BR>#include <string.h><BR>#include <stdarg.h><BR>#include <process.h> // For _beginthreadex<BR>#include "Resource.H"<BR><BR><BR>///////////////////////////////////////////////////////////<BR><BR><BR>// This is the correction to a bug in windowsx.h:<BR>#undef FORWARD_WM_HSCROLL<BR>#define FORWARD_WM_HSCROLL(hwnd, hwndCtl, code, pos, fn) \<BR> (void)(fn)((hwnd), WM_HSCROLL, \<BR> MAKEWPARAM((UINT)(code),(UINT)(pos)), \<BR> (LPARAM)(UINT)(hwndCtl))<BR><BR><BR>///////////////////////////////////////////////////////////<BR><BR><BR>// Forward references to the supermarket<BR>// and shopper thread functions.<BR>DWORD WINAPI ThreadSuperMarket (LPVOID lpvParam);<BR>DWORD WINAPI ThreadShopper (LPVOID lpvParam);<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>// Global variables<BR>HWND g_hwndLB = NULL; // List box for shopper events<BR><BR>// User-settable simulation parameters.<BR>int g_nMaxOccupancy;<BR>int g_nTimeOpen;<BR>int g_nCheckoutCounters;<BR>int g_nMaxDelayBetweenShopperCreation;<BR>int g_nMaxWaitToGetInMarket;<BR>int g_nMaxTimeShopping;<BR>int g_nMaxWaitForDeliCntr;<BR>int g_nMaxTimeSpentAtDeli;<BR>int g_nMaxTimeAtCheckout;<BR><BR>// Synchronization objects used to control the simulation<BR>HANDLE g_hSemEntrance;<BR>HANDLE g_hMtxDeliCntr;<BR>HANDLE g_hSemCheckout;<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>// This function constructs a string using the format string<BR>// passed and the variable number of arguments and adds the<BR>// string to the shopper events list box identified by the<BR>// global g_hwndLB variable.<BR>void AddStr (LPCTSTR szFmt, ...) <BR>{<BR> TCHAR szBuf[150];<BR> int nIndex;<BR> va_list va_params;<BR><BR> // Make va_params point to the first argument after szFmt.<BR> va_start(va_params, szFmt);<BR><BR> // Build the string to be displayed.<BR> _vstprintf(szBuf, szFmt, va_params);<BR> do {<BR> // Add the string to the end of the list box.<BR> nIndex = ListBox_AddString(g_hwndLB, szBuf);<BR><BR> // If the list box is full, delete the first item in it.<BR> if (nIndex == LB_ERR)<BR> ListBox_DeleteString(g_hwndLB, 0);<BR><BR> } while (nIndex == LB_ERR);<BR><BR> // Select the newly added item.<BR> ListBox_SetCurSel(g_hwndLB, nIndex);<BR><BR> // Indicate that we are done referencing<BR> // the variable arguments.<BR> va_end(va_params);<BR>}<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>// This function returns a random number<BR>// between 0 and nMaxValue, inclusive.<BR>int Random (int nMaxValue) {<BR> return(rand() / (RAND_MAX / (nMaxValue + 1)));<BR>}<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus,<BR> LPARAM lParam) {<BR><BR> HWND hwndSB;<BR><BR> // Associate an icon with the dialog box.<BR> chSETDLGICONS(hwnd, IDI_SPRMRKT, IDI_SPRMRKT);<BR><BR> // Save the window handle to the shopper events list box<BR> // in a global variable so that the AddStr function has<BR> // access to it.<BR> g_hwndLB = GetDlgItem(hwnd, IDC_SHOPPEREVENTS);<BR><BR> // Set the scroll bar range and default positions for all of<BR> // the simulation parameters.<BR> hwndSB = GetDlgItem(hwnd, IDC_MAXOCCUPANCY);<BR> ScrollBar_SetRange(hwndSB, 0, 500, TRUE);<BR><BR> // Set the initial value of the scroll bar.<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 30, SendMessage);<BR><BR><BR> hwndSB = GetDlgItem(hwnd, IDC_TIMEOPEN);<BR> ScrollBar_SetRange(hwndSB, 0, 5000, TRUE);<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 5000, SendMessage);<BR><BR> hwndSB = GetDlgItem(hwnd, IDC_NUMCOUNTERS);<BR> ScrollBar_SetRange(hwndSB, 0, 30, TRUE);<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 5, SendMessage);<BR><BR> hwndSB = GetDlgItem(hwnd, IDC_SHOPPERCREATIONDELAY);<BR> ScrollBar_SetRange(hwndSB, 0, 1000, TRUE);<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 300, SendMessage);<BR><BR> hwndSB = GetDlgItem(hwnd, IDC_DELAYTOGETIN);<BR> ScrollBar_SetRange(hwndSB, 0, 100, TRUE);<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 20, SendMessage);<BR><BR> hwndSB = GetDlgItem(hwnd, IDC_TIMETOSHOP);<BR> ScrollBar_SetRange(hwndSB, 0, 100, TRUE);<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 80, SendMessage);<BR><BR> hwndSB = GetDlgItem(hwnd, IDC_WAITDELICNTR);<BR> ScrollBar_SetRange(hwndSB, 0, 100, TRUE);<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 20, SendMessage);<BR><BR> hwndSB = GetDlgItem(hwnd, IDC_TIMEATDELICNTR);<BR> ScrollBar_SetRange(hwndSB, 0, 100, TRUE);<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 70, SendMessage);<BR><BR> hwndSB = GetDlgItem(hwnd, IDC_TIMEATCHECKOUT);<BR> ScrollBar_SetRange(hwndSB, 0, 100, TRUE);<BR> FORWARD_WM_HSCROLL(hwnd, hwndSB, SB_THUMBTRACK,<BR> 60, SendMessage);<BR><BR> return(TRUE);<BR>}<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>void Dlg_OnHScroll(HWND hwnd, HWND hwndCtl,<BR> UINT code, int pos) {<BR><BR> TCHAR szBuf[10];<BR> int nPosCrnt, nPosMin, nPosMax;<BR><BR> // Get the current position and the legal range for the<BR> // scroll bar that the user is changing.<BR> nPosCrnt = ScrollBar_GetPos(hwndCtl);<BR> ScrollBar_GetRange(hwndCtl, &nPosMin, &nPosMax);<BR><BR> switch (code) {<BR> case SB_LINELEFT:<BR> nPosCrnt--;<BR> break;<BR><BR> case SB_LINERIGHT:<BR> nPosCrnt++;<BR> break;<BR><BR> case SB_PAGELEFT:<BR> nPosCrnt -= (nPosMax - nPosMin + 1) / 10;<BR> break;<BR><BR> case SB_PAGERIGHT:<BR> nPosCrnt += (nPosMax - nPosMin + 1) / 10;<BR> break;<BR><BR> case SB_THUMBTRACK:<BR> nPosCrnt = pos;<BR> break;<BR><BR> case SB_LEFT:<BR> nPosCrnt = nPosMin;<BR> break;<BR><BR> case SB_RIGHT:<BR> nPosCrnt = nPosMax;<BR> break;<BR> }<BR><BR> // Make sure that the new scroll bar position<BR> // is within the legal range.<BR> if (nPosCrnt < nPosMin)<BR> nPosCrnt = nPosMin;<BR><BR> if (nPosCrnt > nPosMax)<BR> nPosCrnt = nPosMax;<BR><BR> // Set the new scroll bar position.<BR> ScrollBar_SetPos(hwndCtl, nPosCrnt, TRUE);<BR><BR> // Change the value displayed in the text box to<BR> // reflect the value in the scroll bar.<BR> _stprintf(szBuf, __TEXT("%d"), nPosCrnt);<BR> SetWindowText(GetPrevSibling(hwndCtl), szBuf);<BR>}<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>void Dlg_OnCommand (HWND hwnd, int id, HWND hwndCtl,<BR> UINT codeNotify) {<BR><BR> DWORD dwThreadId;<BR> HANDLE hThread;<BR><BR> switch (id) {<BR> case IDOK:<BR> // Load the scroll bar settings into the global<BR> // variables so that they can be used<BR> // by the simulation.<BR> g_nMaxOccupancy = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_MAXOCCUPANCY));<BR><BR> g_nTimeOpen = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_TIMEOPEN));<BR><BR> g_nCheckoutCounters = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_NUMCOUNTERS));<BR><BR> g_nMaxDelayBetweenShopperCreation = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_SHOPPERCREATIONDELAY));<BR><BR> g_nMaxWaitToGetInMarket = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_DELAYTOGETIN));<BR><BR> g_nMaxTimeShopping = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_TIMETOSHOP));<BR><BR> g_nMaxWaitForDeliCntr = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_WAITDELICNTR));<BR><BR> g_nMaxTimeSpentAtDeli = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_TIMEATDELICNTR));<BR><BR> g_nMaxTimeAtCheckout = ScrollBar_GetPos(<BR> GetDlgItem(hwnd, IDC_TIMEATCHECKOUT));<BR><BR><BR> // Clear out everything in the list box.<BR> ListBox_ResetContent(GetDlgItem(hwnd, IDC_SHOPPEREVENTS));<BR><BR> // Disable the Open For Business button<BR> // while simulation is in progress.<BR><BR> EnableWindow(hwndCtl, FALSE);<BR><BR> if (NULL == GetFocus()) {<BR> SetFocus(GetDlgItem(hwnd, IDC_MAXOCCUPANCY));<BR> }<BR><BR><BR> // The system overhead will cause the results<BR> // of the simulation to be skewed. To help<BR> // minimize this effect, we boost the priority class<BR> // of this process.<BR> SetPriorityClass(GetCurrentProcess(),<BR> HIGH_PRIORITY_CLASS);<BR><BR> // Create the thread representing the supermarket.<BR> hThread = chBEGINTHREADEX(<BR> NULL, // Security attributes<BR> 0, // Stack<BR> ThreadSuperMarket, // Thread function<BR> (LPVOID) hwnd, // Thread function parameter<BR> 0, // Flags<BR> &dwThreadId); // Thread ID <BR> <BR> // Since we are not interested in manipulating the<BR> // thread object from this function, we can close<BR> // our handle to it.<BR> CloseHandle(hThread);<BR> break;<BR><BR> case IDCANCEL:<BR> EndDialog(hwnd, id);<BR> break;<BR> }<BR>}<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg,<BR> WPARAM wParam, LPARAM lParam) {<BR><BR> switch (uMsg) {<BR> chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);<BR> chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);<BR> chHANDLE_DLGMSG(hwnd, WM_HSCROLL, Dlg_OnHScroll);<BR> <BR><BR> case WM_USER:<BR> // This message is sent by the SuperMarketThread <BR> // function to notify us that the simulation <BR> // has completed.<BR><BR> // Return the priority class of the simulation<BR> // back to normal.<BR> SetPriorityClass(GetCurrentProcess(),<BR> NORMAL_PRIORITY_CLASS);<BR><BR> // Enable the Open For Business button so that<BR> // the user can run the simulation again with<BR> // new parameters.<BR> EnableWindow(GetDlgItem(hwnd, IDOK), TRUE);<BR> break;<BR> }<BR> return(FALSE);<BR>}<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>int WINAPI _tWinMain (HINSTANCE hinstExe,<BR> HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) {<BR><BR> chWARNIFUNICODEUNDERWIN95();<BR> DialogBox(hinstExe, MAKEINTRESOURCE(IDD_SPRMRKT),<BR> NULL, Dlg_Proc);<BR><BR> return(0);<BR>}<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>DWORD WINAPI ThreadSuperMarket (LPVOID lpvParam) {<BR> DWORD dwCloseTime;<BR> HANDLE hThread;<BR> DWORD dwThreadId;<BR> int nShopperNum = 0, nMaxOccupancy;<BR><BR> g_hSemEntrance = CreateSemaphore(<BR> NULL, // Security attributes<BR> 0, // Initial lock count<BR> g_nMaxOccupancy, // Maximum people allowed in store<BR> NULL); // Do not name the semaphore.<BR><BR> g_hMtxDeliCntr = CreateMutex(<BR> NULL, // Security attributes<BR> FALSE, // Initially no one is at the deli.<BR> NULL); // Do not name the mutex.<BR><BR> g_hSemCheckout = CreateSemaphore(<BR> NULL, // Security attributes<BR> g_nCheckoutCounters, // All counters are free.<BR> g_nCheckoutCounters, // The number of counters at the store<BR> NULL); // No name for the semaphore<BR><BR><BR> // Open the store to the shoppers.<BR> AddStr(__TEXT("---> Opening the supermarket to shoppers."));<BR> ReleaseSemaphore(g_hSemEntrance, g_nMaxOccupancy, NULL);<BR><BR> // Get the time at which the store should<BR> // stop creating shoppers.<BR> dwCloseTime = GetTickCount() + g_nTimeOpen;<BR><BR> // Continue loop until the store closes.<BR> while (GetTickCount() < dwCloseTime) {<BR><BR> // Create the thread representing a shopper.<BR> hThread = chBEGINTHREADEX(<BR> NULL, // Security attributes<BR> 0, // Stack<BR> ThreadShopper, // Thread function<BR> (LPVOID) ++nShopperNum, // Shopper number as lpvParam<BR> 0, // Flags<BR> &dwThreadId); // Thread ID<BR><BR> // Since we are not interested in manipulating the<BR> // thread object from this function, we can close<BR> // our handle to it.<BR> CloseHandle(hThread);<BR><BR> // Wait until another shopper comes to the supermarket.<BR> Sleep(Random(g_nMaxDelayBetweenShopperCreation));<BR> }<BR><BR> // The supermarket wants to close;<BR> // wait for all of the shoppers to leave.<BR> AddStr(__TEXT("---> Waiting for shoppers to check out ")<BR> __TEXT("so store can close."));<BR><BR> nMaxOccupancy = 1;<BR> for (; nMaxOccupancy <= g_nMaxOccupancy; nMaxOccupancy++) {<BR> WaitForSingleObject(g_hSemEntrance, INFINITE);<BR> AddStr(__TEXT("---> %d shoppers NOT in store."),<BR> nMaxOccupancy);<BR> }<BR><BR> AddStr(__TEXT("---> Store closed--end of simulation."));<BR><BR> // Everybody has left the market--end of simulation.<BR> CloseHandle(g_hSemCheckout);<BR> CloseHandle(g_hMtxDeliCntr);<BR> CloseHandle(g_hSemEntrance);<BR><BR> // Notify the GUI thread that the simulation has completed.<BR> // The window handle of the GUI thread's dialog box was<BR> // passed in the lpvParam parameter to this thread when<BR> // it was created.<BR> SendMessage((HWND) lpvParam, WM_USER, 0, 0);<BR><BR> return(0);<BR>}<BR><BR><BR>//////////////////////////////////////////////////////////////<BR><BR><BR>DWORD WINAPI ThreadShopper (LPVOID lpvParam) {<BR> int nShopperNum = (int) lpvParam;<BR> DWORD dwResult;<BR> int nDuration;<BR><BR> // Seed the random number generator for this thread<BR> // or every shopper thread will use the same seed and<BR> // generate the same set of random numbers.<BR> srand(GetTickCount() * nShopperNum);<BR><BR> // Wait till the shopper can enter the supermarket.<BR> nDuration = Random(g_nMaxWaitToGetInMarket);<BR> AddStr(__TEXT("%04lu: Waiting to get in store (%lu)."),<BR> nShopperNum, nDuration);<BR><BR> dwResult = WaitForSingleObject(g_hSemEntrance, nDuration);<BR> if (dwResult == WAIT_TIMEOUT) {<BR> // The shopper got tired of<BR> // waiting to be let in and left.<BR> AddStr(__TEXT("%04lu: Tired of waiting; went home."),<BR> nShopperNum);<BR> return(0);<BR> }<BR><BR><BR> // Shopper entered the supermarket. Time to go shopping.<BR> nDuration = Random(g_nMaxTimeShopping);<BR> AddStr(__TEXT("%04lu: In supermarket, shopping for %lu."),<BR> nShopperNum, nDuration);<BR> Sleep(nDuration);<BR><BR><BR> // Done with initial shopping. Shopper has a one-in-three<BR> // chance of going to the deli counter.<BR> if (Random(2) == 0) {<BR><BR> // Shopper going to deli counter.<BR> nDuration = Random(g_nMaxWaitForDeliCntr);<BR> AddStr(<BR> __TEXT("%04lu: Waiting for service at ")<BR> __TEXT("Deli Counter (%lu)."),<BR> nShopperNum, nDuration);<BR> dwResult =<BR> WaitForSingleObject(g_hMtxDeliCntr, nDuration);<BR><BR> if (dwResult == 0) {<BR> // Got attention at deli; order stuff.<BR> nDuration = Random(g_nMaxTimeSpentAtDeli);<BR><BR> AddStr(__TEXT("%04lu: Being served at Deli (%lu)."),<BR> nShopperNum, nDuration);<BR> Sleep(nDuration);<BR><BR> // Leave the deli counter.<BR> ReleaseMutex(g_hMtxDeliCntr);<BR><BR> } else {<BR> // Tired of waiting at deli counter,<BR> // leave and continue shopping.<BR> AddStr(__TEXT("%04lu: Tired of waiting at Deli."),<BR> nShopperNum);<BR> }<BR><BR> } else {<BR> AddStr(__TEXT("%04lu: Not going to the Deli counter."),<BR> nShopperNum);<BR> }<BR><BR><BR> // Waiting for a checkout counter.<BR> AddStr(<BR> __TEXT("%04lu: Waiting for an empty checkout counter."),<BR> nShopperNum);<BR> WaitForSingleObject(g_hSemCheckout, INFINITE);<BR><BR> // Checking out.<BR> nDuration = Random(g_nMaxTimeAtCheckout);<BR> AddStr(__TEXT("%04lu: Checking out (%lu)."),<BR> nShopperNum, nDuration);<BR> Sleep(nDuration);<BR><BR> // Leaving the checkout counter.<BR> AddStr(__TEXT("%04lu: Leaving checkout counter."),<BR> nShopperNum);<BR> ReleaseSemaphore(g_hSemCheckout, 1, NULL);<BR><BR> // Leaving the store.<BR> AddStr(__TEXT("%04lu: Left the supermarket."),<BR> nShopperNum);<BR> ReleaseSemaphore(g_hSemEntrance, 1, NULL);<BR><BR> // Shopper shopped till he/she dropped. Shopper dead.<BR> return(0);<BR>}<BR><BR><BR>//////////////////////// End Of File /////////////////////////<BR>
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:ljl 回复日期:2003-12-29 12:36:35
<br>内容:见过,就是表示后面的参数类型和个数不定
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:ljl 回复日期:2003-12-29 12:38:51
<br>内容:<BR>#include <iostream><BR>#include <string><BR><BR>using namespace std;<BR><BR>void fun(int i, ... )<BR>{<BR> cout << "Fun... ... " << endl;<BR>}<BR><BR>void main()<BR>{<BR> fun(1);<BR> fun(1, "abc");<BR> fun(1, 2);<BR> fun(1, 'a', 'b', 2, 2);<BR><BR>}<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -