?? 金山問題.txt
字號:
#define FALSE 0
BOOL jiba(int *p1, int *p2, int**pt)
{
if ((p1 == NULL) || (p2 == NULL) ||
(p1[0] > p1[1]) || (p2[0] > p2[1]))
{
printf("輸入有誤\n");
return FALSE;
}
if (p2[0] <= p1[0])
{
if (p2[1] < p1[0])
return FALSE;
else
{
*pt = new int[2];
(*pt)[0] = p1[0];
(*pt)[1] = (p2[1]<=p1[1] ? p2[1]:p1[1]);
return TRUE;
}
}
else
{
if (p2[0] > p1[1])
return FALSE;
else
{
*pt = new int[2];
(*pt)[0] = (p1[0] >= p2[0] ? p1[0]:p2[0]);
(*pt)[1] = p1[1];
return TRUE;
}
}
return TRUE;
}
//test!
int rt[2] ={1,5};
int rt1[2]={3,9};
int main()
{
int *p = NULL;
BOOL b = jiba(rt,rt1,&p);
if (b)
{
printf("[%d,%d]與[%d,%d]的交集為[%d,%d]\n",rt[0],rt[1],rt1[0],rt1[1], p[0],p[1]);
delete p;
}
else
{
printf("[%d,%d]與[%d,%d]的交集為空\n",rt[0],rt[1],rt1[0],rt1[1]);
}
getchar();
return 0;
}
第一道:
兩個數 int a, int b,不用中間變量交換兩個值的C++代碼.
第二道,分析程序輸出.代碼如下:
#include <iostream.h>
class B {
public:
int i, j;
B(int x = 999) :j(x), i(j)
{
cout << "B::B() invoked\n" << endl;
}
~B()
{
cout << "B::~B() invoked\n" << endl;
}
};
class D : public B {
public:
D()
{
cout << "D::D() invoked\n" <<endl;
}
~D()
{
cout << "D::~D() invoked\n" << endl;
}
};
void main()
{
D d;
cout << "d.i" << d.i << endl;
cout << "d.j=" << d.j << endl;
}
結果:
B::B() invoked
D::D() invoked
d.i-858993460
d.j=999
D::~D() invoked
B::~B() invoked
_cdecl
按從右至左的順序壓參數入棧,由調用者把參數彈出棧。對于“C”函數或者變量,修飾名是在函數名前加下劃線。對于“C++”函數,有所不同。
如函數void test(void)的修飾名是_test;對于不屬于一個類的“C++”全局函數,修飾名是?test@@ZAXXZ。
這是缺省調用約定。由于是調用者負責把參數彈出棧,所以可以給函數定義個數不定的參數,如printf函數。
_stdcall
按從右至左的順序壓參數入棧,由被調用者把參數彈出棧。對于“C”函數或者變量,修飾名以下劃線為前綴,然后是函數名,然后是符號“@”及參數的字節數,如函數int func(int a, double b)的修飾名是_func@12。對于“C++”函數,則有所不同。
所有的Win32 API函數都遵循該約定。
_pascal
按從左至右的順序壓參數入棧 ...其它的與_stdcall相同;
_fastcall
頭兩個DWORD類型或者占更少字節的參數被放入ECX和EDX寄存器,其他剩下的參數按從右到左的順序壓入棧。 由被調用者把參數彈出棧,對于“C”函數或者變量,修飾名以“@”為前綴,然后是函數名,接著是符號“@”及參數的字節數,如函數int func(int a, double b)的修飾名是@func@12。對于“C++”函數,有所不同。
未來的編譯器可能使用不同的寄存器來存放參數。
thiscall
僅僅應用于“C++”成員函數。this指針存放于CX寄存器,參數從右到左壓棧。thiscall不是關鍵詞,因此不能被程序員指定。
naked call
采用1-4的調用約定時,如果必要的話,進入函數時編譯器會產生代碼來保存ESI,EDI,EBX,EBP寄存器,退出函數時則產生代碼恢復這些寄存器的內容。naked call不產生這樣的代碼。
naked call不是類型修飾符,故必須和_declspec共同使用,如下:
__declspec( naked ) int func( formal_parameters )
{
// Function body
}
便于更好理解, 看下面例子(函數調用的過程以匯編代碼表示):
void cdecl fun1(int x,int y);
void stdcall fun2(int x,int y);
void pascal fun3(int x,int y);
****************************************
void cdecl fun1(int x,int y);
fun1(x,y);
調用 fun1 的匯編代碼
push y
push x
call fun1
add sp,sizeof(x)+sizeof(y) ;跳過參數區(x,y)
fun1 的匯編代碼:
fun1 proc
push bp
mov bp,sp
……
…
pop bp
ret ;返回,但不跳過參數區
fun1 endp
****************************************
void stdcall fun2(int x,int y);
fun2(x,y);
調用 fun2 的匯編代碼
push y
push x
call fun2
fun2 的匯編代碼:
fun2 proc
push bp
mov bp,sp
……
…
pop bp
ret sizeof(x)+sizeof(y) ;返回并跳過參數區(x,y)
fun2 endp
*****************************************
void pascal fun3(int x,int y);
fun3(x,y);
調用 fun3 的匯編代碼
push x
push y
call fun3
fun3 的匯編代碼:
fun3 proc
push bp
mov bp,sp
……
…
pop bp
ret sizeof(x)+sizeof(y) ;返回并跳過參數區(x,y)
fun3 endp
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -