我的朋友经过一晚的学习,继续和我讨论。
B:问你几个问题吧!
WinMain()函数的调用约定是PASCAL。什么是约定啊?不算很理解,PASCAL不是一种语言吗?和c有什么关系啊?
A:在这里PASCAL是一个调用约定,由于这种方式最早由PASCAL采用,所以这么叫。
在MSDN中的C++ Language Reference中,Calling Conventions这一章都是讲调用约定的。
约定:微软重定义了许多约定类型,为的是可以让代码更容易跨平台或者跨编译器。
其实,调用约定要解决两个问题,都是针对堆栈操作:
1。参数传递的顺序(本质是压栈的顺序)
2。谁负责平栈(调用者还是调用对象)
目前你只要搞清楚一个函数的声明、定义和实现中的调用方式必须一致!
(高手不要和我较汁,这是给新手看的,fastcall以后再说)
B:我在看你写的,我要慢慢琢磨啦,哈哈
“目前你只要搞清楚一个函数的声明、定义和实现中的调用方式必须一致!”我现在明白,你说的什么堆栈,压栈,平栈什么玩意不明白了:(
A:所以我说你只要搞清。。。
其他不着急
B:?
whie(GetMessage(&msg,Null,0,0))
{
...
}
是循环得到win98发给他的消息是吧?&msg这个引用是什么玩意?啊
A:msg是一个结构,内部包含消息的各种必要参数。GetMessage得到msg的地址以后,回填这些内容。
B:那 等于是给了一个msg这个结构的引用,哦
A:是的,不过对于c程序员来说,你看问题的角度最好调整一下。
所有的东西你要理解到底是什么!特别是各种指针和引用。
B:怎么调整呢?往哪个方向啊
A:也就是说你尽量搞明白任何东西最终在内存中是什么样的。
比如引用,就是传递了被引用对象的起始地址。
B:内存?还真不明白,我会好好看的。
引用也是地址吗?
指针不是地址吗?引用不就是一个复制的对象吗?
A:在c++中,引用就是传递该对象的起始地址,所有类型都可以引用。
在c++中,引用其实可以用取地址代替。
例如,我们要实现在函数中将变量加1:
//传递引用
void Inc(int &nValue)
{
nValue++;
}
//传递指针
void Inc2(int* pValue)
{
(*pValue)++;
}
//调用
int n = 0;
Inc(n);
Inc2(&n);
这两种方法效果是一样的,你要体会一下。其实在c++中,引用和取地址用的是同一个符号"&".
B:Inc的参数是引用类型啊,为什么不Inc(&n)啊?
Inc2的参数是指针,为什么不Inc2(*n);
B:Inc2(&n);我明白了
是把n用&取地址,也就是指针的了是吧?
Inc的使用不明白
A:
void Inc(int &nValue);
声明的是传递引用,所以直接把东西给函数就行了,编译器知道函数中使用的都是原来那个对象,所以你直接改那个对象,外面的值就变了。这其实是把取地址的问题交给编译器完成了。
而
void Inc2(int* pValue);
声明传递地址,那么你当然要取出地址传递过去。
B:现在有几个难明白的:
约定,宏,还有win怎么和别的程序基本的数据类型不一样?
A:约定我们讲过了
宏:直接找的宏的实现看看就可以了。
装一个VisualAssist,光标放在宏上面以后就可以看到宏的定义,还可以go过去。
B:知道了
A:
基本数据类型:这个是由语言决定的,微软不能随便改。
但是目前的c/c++标准中,各种数据类型的宽度是会随平台改变的,而没有定义绝对的数据类型,所以微软用宏定义扩展了许多绝对数据类型。
例如我们需要一个4字节宽度的绝对数据类型DWORD,那么在目前32位平台下,微软就typedef unsigned long DWORD,到了64位平台上可能就是typedef unsigned int DWORD
这样,只要换一份定义文件,所有源代码就可以直接移植。
B:懂的那么透彻了,明白了,真佩服你!!!
A:我要写程序去了,白白。