??xml version="1.0" encoding="utf-8" standalone="yes"?>
To set all the bytes in a block of memory to a particular value, use memset(). The function prototype is
void * memset(void *dest, int c, size_t count);
The argument dest points to the block of memory. c is the value to set, and count is the number of bytes, starting at dest, to be set. Note that while c is a type int, it is treated as a type char. In other words, only the low-order byte is used, and you can specify values of c only in the range 0 through 255.
Use memset() to initialize a block of memory to a specified value. Because this function can use only a type char as the initialization value, it is not useful for working with blocks of data types other than type char, except when you want to initialize to 0. In other words, it wouldn't be efficient to use memset() to initialize an array of type int to the value 99, but you could initialize all array elements to the value 0. memset() will be demonstrated in program below.
memcpy() copies bytes of data between memory blocks, sometimes called buffers. This function doesn't care about the type of data being copied--it simply makes an exact byte-for-byte copy. The function prototype is
void *memcpy(void *dest, void *src, size_t count);
The arguments dest and src point to the destination and source memory blocks, respectively. count specifies the number of bytes to be copied. The return value is dest. If the two blocks of memory overlap, the function might not operate properly--some of the data in src might be overwritten before being copied. Use the memmove() function, discussed next, to handle overlapping memory blocks. memcpy() will be demonstrated in program below.
memmove() is very much like memcpy(), copying a specified number of bytes from one memory block to another. It's more flexible, however, because it can handle overlapping memory blocks properly. Because memmove() can do everything memcpy() can do with the added flexibility of dealing with overlapping blocks, you rarely, if ever, should have a reason to use memcpy(). The prototype is
void *memmove(void *dest, void *src, size_t count);
dest and src point to the destination and source memory blocks, and count specifies the number of bytes to be copied. The return value is dest. If the blocks overlap, this function ensures that the source data in the overlapped region is copied before being overwritten. Sample program below demonstrates memset(), memcpy(), and memmove().
1: /* Demonstrating memset(), memcpy(), and memmove(). */ 2: 3: #include <stdio.h> 4: #include <string.h> 4: 5: char message1[60] = "Four score and seven years ago ..."; 6: char message2[60] = "abcdefghijklmnopqrstuvwxyz"; 7: char temp[60]; 8: 9: main() 10: { 11: printf("\nmessage1[] before memset():\t%s", message1); 12: memset(message1 + 5, `@', 10); 13: printf("\nmessage1[] after memset():\t%s", message1); 14: 15: strcpy(temp, message2); 16: printf("\n\nOriginal message: %s", temp); 17: memcpy(temp + 4, temp + 16, 10); 18: printf("\nAfter memcpy() without overlap:\t%s", temp); 19: strcpy(temp, message2); 20: memcpy(temp + 6, temp + 4, 10); 21: printf("\nAfter memcpy() with overlap:\t%s", temp); 22: 23: strcpy(temp, message2); 24: printf("\n\nOriginal message: %s", temp); 25: memmove(temp + 4, temp + 16, 10); 26: printf("\nAfter memmove() without overlap:\t%s", temp); 27: strcpy(temp, message2); 28: memmove(temp + 6, temp + 4, 10); 29: printf("\nAfter memmove() with overlap:\t%s\n", temp); 30: 31: } message1[] before memset(): Four score and seven years ago ... message1[] after memset(): Four @@@@@@@@@@seven years ago ... Original message: abcdefghijklmnopqrstuvwxyz After memcpy() without overlap: abcdqrstuvwxyzopqrstuvwxyz After memcpy() with overlap: abcdefefefefefefqrstuvwxyz Original message: abcdefghijklmnopqrstuvwxyz After memmove() without overlap: abcdqrstuvwxyzopqrstuvwxyz After memmove() with overlap: abcdefefghijklmnqrstuvwxyz
ANALYSIS: The operation of memset() is straightforward. Note how the pointer notation message1 + 5 is used to specify that memset() is to start setting characters at the sixth character in message1[] (remember, arrays are zero-based). As a result, the 6th through 15th characters in message1[] have been changed to @.
When source and destination do not overlap, memcpy() works fine. The 10 characters of temp[] starting at position 17 (the letters q through z) have been copied to positions 5 though 14, where the letters e though n were originally located. If, however, the source and destination overlap, things are different. When the function tries to copy 10 characters starting at position 4 to position 6, an overlap of 8 positions occurs. You might expect the letters e through n to be copied over the letters g through p. Instead, the letters e and f are repeated five times.
If there's no overlap, memmove() works just like memcpy(). With overlap, however, memmove() copies the original source characters to the destination.
2.pow(2,10) 要改?nbsp; pow((double)2,10)或pow(2.0,10)
说明Q?.0中用到math.h pow()函數時,有這個原?double pow(int _X,int _Y) 但如果用VC++ 2005的話Qpow()的第一個參數就不能再用int型態Q只能用float、double、long doubleQVC++ 2005在編譯時會做type checkingQ然後就過不了,报error C2668
3.ItoaҎ名要Ҏ _Itoa_s
4.error C2440Q?#8220;static_cast” 无法?#8220;void (__thiscall CChatManagerDlg::* )(WPARAM,LPARAM)”转换?#8220;LRESULT (__thiscall CWnd::* )Q出错处在ON_MESSAGE(WM_SETPLAY,OnSetPlay)
解答Q将void CVideoBaseView::OnSetPlay(WPARAM wp,LPARAM lp) ҎLRESULT CVideoBaseView::OnSetPlay(WPARAM wp,LPARAM lp){
LRESULT result = Default();
//你原来的代码
return result;}
5.找不到MFC80D.DLL
解决Q?#8220;工程属?#8221;->“link”->“manifesto file”->“$(IntDir)\$(TargetFileName).intermediate.manifest” ?nbsp; Ҏ $(IntDir)\$(TargetFileName).manifest
文章出处Q飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/vc/vc_js/200879/132413.html
view plaincopy to clipboardprint?
LRESULT CPreventShutdownDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (WM_QUERYENDSESSION == message)
{
AfxMessageBox(_T("呵呵Q不许关机!"));
return FALSE; // ҎMSDNQWM_QUERYENDSESSION q回FALSE则取消关?nbsp;
}
return CDialog::WindowProc(message, wParam, lParam);
}
LRESULT CPreventShutdownDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (WM_QUERYENDSESSION == message)
{
AfxMessageBox(_T("呵呵Q不许关机!"));
return FALSE; // ҎMSDNQWM_QUERYENDSESSION q回FALSE则取消关?br> }
return CDialog::WindowProc(message, wParam, lParam);
}
是什么原因在某些机器上无法阻止关机呢Q?/p>
回忆x时经帔R到的场景Q?/p>
1. 如果某个q程失去响应Q关机的时候会提示"...没有响应Q是否结?
2. 使用C本修改了文Q在没有保存的情况下q行xQ普通情况会提示是否q行保存?/p>
1q种情况不好模拟Q但?是很好模拟的。于是在不能Lx的机器上q样q行试Q发现虽然也弹出了是否保存的对话框,但是q是马上关Z?/p>
果然Q和E序无关Q应该是机器讄的问题。于是想C一个很行的词Q?快速关?
到网上google了一下,发现快速关机是通过如下的方式实现的Q?/p>
HKEY-CURRENT-USER\Control Panel\Desktop\AutoEndTasks gؓ1表示快速关?/p>
普通情况gؓ0或这个键g存在
C能阻止快速关机的机器上一看,果然q个键gؓ1.
改ؓ0后再q行E序Q就都能Lx了?/p>
【结论】阻止关机需要两步才能完的实现Q而不仅仅是MSDN中描q的2)
1) 在程序中先删除这个键?HKEY-CURRENT-USER\Control Panel\Desktop\AutoEndTasks)
2) 处理 WM_QUERYENDSESSION 时返回FALSE
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/skyxie/archive/2009/06/09/4255767.aspx
那如何获取这个窗口的句柄呢?很自然我们可以想到这么一个函敎ͼ函数形式如下Q?/p>
HWND FindWindowEx(
HWND hwndParent,
HWND hwndChildAfter,
LPCTSTR lpszClass,
LPCTSTR lpszWindow
);
hwndParentQ指向一个待搜烦H口的父H?/p>
hwndChildAfterQ子H口的句柄?/p>
lpszClassQ窗口的cd?/p>
lpszWindowQ窗口的标题名?/p>
例如Q本CZ工程要找C个对话框里的~辑框,q对q个~辑框进行注入。查找过E如下:
HWND hWndChild = NULL;
while(1)
{
// 查找对话框窗口,且这个对话框H口的标题名?#8220;TestDlg”
HWND hDlg = FindWindowEx(0, NULL, "#32770", "TestDlg");
if(hDlg == NULL)
{
printf("没有扑ֈ该对话框H口!\n");
exit(1);
}
else
{
// 查找q个对话框窗口中的edit控g
hWndChild = FindWindowEx(hDlg, NULL, "Edit",NULL);
if(hWndChild != NULL)
{
break; // 扑ֈq个~辑框,现在要对q个~辑框进行注?
}
}
}
// Ҏ查找出的H口Q查询进E?
DWORD dwQQGameId;
HANDLE hProcessQQGame;
if(!GetWindowThreadProcessId(hWndChild,&dwQQGameId))
{
printf("Error in GetWindowThreadProcessId():%d\n",GetLastError());
exit(1);
}
扑ֈq个q程后,然后p对这个进E进行注入。但是,你别忘记了,当你在其他进E中获取另外q程的窗口句柄,你是没有办法操作q个句柄的。ؓ什么呢Q每个进E都被赋予它自己的虚拟地址I间。对? 2位进E来_q个地址I间? G BQ因
? 2位指针可以拥有从0 x 0 0 0 0 0 0 0 0? x F F F F F F F F之间的Q何一个倹{这使得一个指针能够拥? 294 967 296个g的一个|它覆盖了一个进E的4 G B虚拟I间的范围。对? 4位进E来_q个地址I间? 6 E BQ? 01 8字节Q,因ؓ6 4位指针可以拥有从0 x 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0? x F F F F F F F F F F F F F F F F之间的Q何倹{这使得一个指针可以拥?8 446 744 073 709 551 616个g的一个|它覆盖了一个进E的1 6 E B虚拟I间的范围。这是相当大的一个范围。由于每个进E可以接收它自己的私有的地址I间Q因此当q程中的一个线E正在运行时Q该U程可以讉K只属于它的进E的内存。属于所有其他进E的内存则隐藏着Qƈ且不能被正在q行的线E访问。注意在Windows 2000中,属于操作pȝ本n的内存也是隐藏的Q正在运行的U程无法讉K。这意味着U程常常不能讉K操作pȝ的数据。Windows 98中,属于操作pȝ的内存是不隐藏的Q正在运行的U程可以讉K。因此,正在q行的线E常常可以访问操作系l的数据Q也可以破坏操作pȝQ从而有可能D操作pȝ崩溃Q。在Windows 98中,一个进E的U程不可能访问属于另一个进E的内存。前面说q,每个q程有它自己的私有地址I间。进EA可能有一个存攑֜它的地址I间中的数据l构Q地址? x 1 2 3 4 5 6 7 8Q而进EB则有一个完全不同的数据l构存放在它的地址I间中,地址? x 1 2 3 4 5 6 7 8。当q程A中运行的U程讉K地址? x 1 2 3 4 5 6 7 8的内存时Q这些线E访问的是进EA的数据结构。当q程B中运行的U程讉K地址? x 1 2 3 4 5 6 7 8的内存时Q这些线E访问的是进EB的数据结构。进EA中运行的U程不能讉Kq程B的地址I间中的数据l构Q反之亦然?/p>
q样看来Q若惛_q个H口句柄q行操作Q得x设法使我们能够进入到原宿主进E中Q然后执行我们的操作。这个就好象一个寄生虫惌破坏Z的机能,必须得进入我们的体内Q寄生在我们的组l上才能够生作用。现在关键是如何寄生到宿M呢?
通常QQ何进E都可以通过LoadLibrary动态地加蝲DLLQ但是我们如何强制一个外部进E调用该函数呢?{案是CreateRemoteThread?br>让我们先来看看LoadLibrary和FreeLibrary的函数声明:
HINSTANCE LoadLibrary(
LPCTSTR lpLibFileName // address of filename of library module
);
BOOL FreeLibrary(
HMODULE hLibModule // handle to loaded library module
);
再和CreateRemoteThread的线E过E(thread procedureQThreadProc比较一下:
DWORD WINAPI ThreadProc(
LPVOID lpParameter // thread data
);
你会发现所有的函数都有同样的调用约定(calling conventionQ、都接受一?2位的参数q且q回值类型的大小也一栗也是_我们可以把LoadLibrary/FreeLibrary的指针作为参C递给CrateRemoteThread?/p>
然而,q有两个问题Q参考下面对CreateRemoteThread的说明)
1Q?传递给ThreadProc的lpStartAddress 参数必须E进E中的线E过E的起始地址?br> 2Q?如果把ThreadProc的lpParameter参数当做一个普通的32位整敎ͼFreeLibrary把它当做HMODULEQ那么没有如何问题,但是如果把它当做一个指针(LoadLibrary把它当做一个char*Q,它就必须指向q程q程中的内存数据?/p>
W一个问题其实已l迎刃而解了,因ؓLoadLibrary和FreeLibrary都是存在于kernel32.dll中的函数Q而kernel32可以保证M“正常”q程中都存在Q且其加载地址都是一L。(参看附录AQ于是LoadLibrary/FreeLibrary在Q何进E中的地址都是一LQ这׃证了传递给q程q程的指针是个有效的指针?/p>
W二个问题也很简单:把DLL的文件名QLodLibrary的参敎ͼ用WriteProcessMemory复制到远E进E?/p>
所以,使用CreateRemoteThread和LoadLibrary技术的步骤如下Q?br> 1Q?得到q程q程的HANDLEQ用OpenProcessQ?br> 2Q?在远E进E中为DLL文g名分配内存(VirtualAllocExQ?br> 3Q?把DLL的文件名Q全路径Q写到分配的内存中(WriteProcessMemoryQ?br> 4Q?使用CreateRemoteThread和LoadLibrary把你的DLL映射q远E进E?br> 5Q?{待q程U程l束QWaitForSingleObjectQ,即等待LoadLibraryq回。也是说当我们的DllMainQ是以DLL_PROCESS_ATTACH为参数调用的Q返回时q程U程也就立即l束了?br> 6Q?取回q程U程的结束码QGetExitCodeThtreadQ,即LoadLibrary的返回值――我们DLL加蝲后的基地址QHMODULEQ?br> 7Q?释放W?步分配的内存QVirtualFreeExQ?br> 8Q?用CreateRemoteThread和FreeLibrary把DLL从远E进E中卸蝲。调用时传递第6步取得的HMODULElFreeLibraryQ通过CreateRemoteThread的lpParameter参数Q?br> 9Q?{待U程的结束(WaitSingleObjectQ?/p>
主要代码如下Q?/p>
#include<stdio.h>
#include<conio.h>
#include<windows.h>
void main()
{
HWND hWndChild = NULL;
while(1)
{
// 查找对话框窗口,且这个对话框H口的标题名?#8220;TestDlg”
HWND hDlg = FindWindowEx(0, NULL, "#32770", "TestDlg");
if(hDlg == NULL)
{
printf("没有扑ֈ该对话框H口!\n");
exit(1);
}
else
{
// 查找q个对话框窗口中的edit控g
hWndChild = FindWindowEx(hDlg, NULL, "Edit",NULL);
if(hWndChild != NULL)
{
break; // 扑ֈq个~辑框,现在要对q个~辑框进行注?
}
}
}
// Ҏ查找出的H口Q查询进E?
DWORD dwQQGameId;
HANDLE hProcessQQGame;
if(!GetWindowThreadProcessId(hWndChild,&dwQQGameId))
{
printf("Error in GetWindowThreadProcessId():%d\n",GetLastError());
exit(1);
}
HINSTANCE hDll = NULL;
typedef void(*LP_SET_HEDIT_FUN)(HWND);
LP_SET_HEDIT_FUN m_SethEdit = NULL;
char DllPath[MAX_PATH] = "D:\\q程注入试工程\\Bin\\automessagedll.dll";
hDll = LoadLibrary(DllPath);
if(hDll)
{
m_SethEdit = (LP_SET_HEDIT_FUN)GetProcAddress(hDll,"SethEdit");
}
if(m_SethEdit)
{
m_SethEdit(hWndChild);
}
else
{
printf("Can not load SethEdit in the dll(%d).\n",GetLastError());
}
if( (hProcessQQGame = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwQQGameId)) == NULL)
{
printf("Error in OpenProcess():%d\n",GetLastError());
getch();
exit(1);
}
int cb = (1+lstrlen(DllPath))* sizeof(char);
char* RemoteLibFile = (char*)VirtualAllocEx(hProcessQQGame,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
if(RemoteLibFile == NULL)
{
printf("Error in VirtualAllocEx():%d\n",GetLastError());
getch();
exit(1);
}
if( (WriteProcessMemory(hProcessQQGame,RemoteLibFile,(LPVOID)DllPath,cb,NULL)) == 0)
{
printf("Error in WriteProcessMemory():%d\n",GetLastError());
getch();
exit(1);
}
PTHREAD_START_ROUTINE pfnStartAddr;
pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"),"LoadLibraryA");
HANDLE hThread = CreateRemoteThread(hProcessQQGame,NULL,0,pfnStartAddr,RemoteLibFile,0,NULL);
if(hThread == NULL)
{
printf("Error in CreateRemoteThread():%d",GetLastError());
getch();
exit(1);
}
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
VirtualFreeEx(hProcessQQGame,RemoteLibFile,0,MEM_RELEASE);
CloseHandle(hProcessQQGame);
}
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/kissyfish/archive/2008/12/07/3462055.aspx
//---------------------------------------------------------------------------
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#define MAXBLOCKSIZE 1024
#pragma comment( lib, "wininet.lib" ) ;
void download(const char *Url,const char *save_as)/*Url指向的地址的文件下载到save_as指向的本地文?/
{
byte Temp[MAXBLOCKSIZE];
ULONG Number = 1;
FILE *stream;
HINTERNET hSession = InternetOpen(_T("RookIE/1.0"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hSession != NULL)
{
HINTERNET handle2 = InternetOpenUrl(hSession,_T(Url), NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);
if (handle2 != NULL)
{
if( (stream = fopen( save_as, "wb" )) != NULL )
{
while (Number > 0)
{
InternetReadFile(handle2, Temp, MAXBLOCKSIZE - 1, &Number);
fwrite(Temp, sizeof (char), Number , stream);
}
fclose( stream );
}
InternetCloseHandle(handle2);
handle2 = NULL;
}
InternetCloseHandle(hSession);
hSession = NULL;
}
}
int main(int argc, char* argv[]){
download("*调用CZQ下载百度的首页到c:\index.html文g*/
return 0;
}
VOID CALLBACK Timer2Proc(
HWND hWnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
)
{
return;
}
Ҏ二:
// DLL中的U程函数可以象这样用Timer
UINT ThreadProc(LPVOID)
{
SetTimer(NULL, 1, 5000, NULL);
MSG msg;
// PeekMessage 强制pȝU程建立消息?br> PeekMessage(&msg, NULL, NULL, NULL, FALSE);
while (GetMessage(&msg, NULL, NULL, NULL))
{
switch (msg.message)
{
case WM_TIMER:
{
// q里?U钟执行一?br> }
break;
}
//TranslateMessage(&msg);
//DispatchMessage(&msg);
}
KillTimer(NULL, 1);
return 0;
}
Ҏ三:
创徏一个线E? 反复ȝl时间不可以了? 如果定时要求不严,用Sleep可以了
UINT TimerThread(LPVOID pama)
{
UINT oldTickCount, newTickCount;
oldTickCount = GetTickCount();
while(TRUE)
{
while(TRUE)
{
newTickCount = GetTickCount();
if(newTickCount - oldTickCount >= 100)
{
oldTickCount = newTickCount;
break;
}
}
TimeProc();
}
return 0;
}
大约?00ms 调用一ơTimeProc();
User Rating: 1019 | Rate This User | ![]() ![]() |
Report this Post to a Moderator | Link |
![]() |
![]() ![]() |
|||
![]() |
||||
The difference between Win32 and MFC are pretty straightforward: The Windows API (Win32) uses a C interface to access windows functionality. It requires that you write all of your own code to manage windows and message handling. It is quite straightforward but you will need a good reference, like MSDN, and some good tutorials or samples to get started. In contrast, MFC, which stands for Microsoft Foundation Classes, are a collection of C++ classes which encapsulate the Win32 API. MFC has some wizards which make the initial creation of a program quick and easy, but I have to admit the learning curve of MFC can sometimes be frustrating as Microsoft seems to have done everything in a way that can at times seem counter-intuitive. Whenever I write an application I write it in MFC but I have been writing applications in MFC for a long time. If all you want is a message loop and a window handle for a game, use Win32. If you want to write a larger application like an editor, maybe MFC is the right tool. Ideally, I would suggest skipping both Win32 and MFC and writing tools in .NET. I do not have any personal experience in it but people I work with sure can get a lot done using it. It may well be worth investigation. Best of luck, - S |
||||
|
![]() |
![]() ![]() |
|||
![]() |
||||
Quote: I am planning to write an interactive 3D environment does that mean using WIN32 application is a better tool for it? also is it possible to use openGL for oject creation and DirectXinput for the interactive control? please give me some suggestion millions of thanks |
||||
|
![]() |
![]() ![]() |
|||
![]() |
||||
Quote: For a game Win32 is usually better. I think I have also heard that MFC doesn't work well in fullscreen. Quote: You can render with opengl and use directinput for input. ____________________________________________________________ Programmers Resource Central |
||||
|
![]() |
![]() ![]() |
|||
![]() |
||||
what about mouse movement like shooting games? how can i do that, please give me some direction |
||||
|
![]() |
![]() ![]() |
|||
![]() |
||||
You can use directinput for mouse movement. Or you can use GetCursorPos(POINT *p); ____________________________________________________________ Programmers Resource Central |
||||
|
![]() |
![]() ![]() |
|||
![]() |
||||
How do i use that? can you give me some example and much clearer direction millions of thanks |
||||
|
![]() |
![]() ![]() |
![]() |
|
msdn Though if you want a camera class look here and here. |
#include <stdio.h>
main()
{
int a,b; /* 定义a,b两个整Ş变量用于输入两个整数 */
int *point_1,*point_2,*temp_point; /* 定义三个指针变量 */
scanf("%d,%d",&a,&b); /* 格式化输入a,b的?*/
point_1=&a; /* 把指针变量point_1的值指向变量a的地址 */
point_2=&b; /* 把指针变量point_2的值指向变量b的地址 */
if (a<b)
{
temp_point=point_1; /* q里的temp_point是用于时存储point_1的g是变量a的地址?*/
point_1=point_2; /* 把point_2的D予point_1 */
point_2=temp_point;
/* ׃point_1的值已l改变无法找?利用前面临时存储的也是temp_point扑֛原point_1的D予point_2,打到把point_1和point_2值对换的目的*/
}
printf("%d,%d",*point_1,*point_2); /* 利用*point_1?point_2也就是分辨指向b和a的方法把值显C爱屏q上 */
}
/* 此题需要注意和了解是的此法q没有改变变量a,b的值只是利用指针变量分别存储a和b的地址,然后再把那两个指针变量的值对换一下其实就是存储在
指针变量里面a与b的地址Ҏ,在利?point_1?point_2的方式把调换后的值显C出来这里的*point_1实际是a,此中法q真的改变a,b的?而是
利用指针q行地址交换辑ֈ大小排序的目?
*/
#include <stdio.h>
main()
{
int a,b; /* 定义a,b两个整Ş变量用于输入两个整数 */
int *point_1,*point_2; /* 定义三个指针变量 */
scanf("%d,%d",&a,&b); /* 格式化输入a,b的?*/
point_1 = &a; /* 把指针变量point_1的值指向变量a的地址 */
point_2 = &b; /* 把指针变量point_2的值指向变量b的地址 */
compositor(point_1,point_2); /* 调用自定义的排序涉|,把a,b的地址传递给point_1和point_2 */
printf("%d,%d",a,b); /* 打印出a,b的?*/
}
static compositor(p1,p2)
int *p1,*p2; /* 定义形式参数p1,p2为指针变?*/
{
int temp; /* 建立临时存储变量 */
if (*p1<*p2) /* 如果*p1<p2,注意q里?p1?p2其实是a和b */
{
temp = *p1; /* 利用变量temp用于临时存储*p1和就是a的?*/
*p1 = *p2; /* ?p1的g是a的值换?p2的g是b的?{h于a=b */
*p2 = temp; /* ?p2的g是temp的值等价于b=temp */
}
}
/* 注意:此题与上题不同的?直接改变了a于b的D到真实改变的目的 */