当前位置:编程学习 > VB >>

Any和Void*是不是一回事?

Any和Void*是不是一回事?如果不是,有何区别? --------------------编程问答-------------------- 呵呵,西西又在捣鼓啥? --------------------编程问答-------------------- 看这段话:

“VB支持三种在函数声明中没有进行类型定义的变量。第一种类型即Any,仅仅在VB 的声明陈述中被允许,它承认任何非数组类型的变量。并且数据被传递到任何类型的参数 中并自动的经过UNICODE/ANSI/UNICODE转换。而且,VB还能够识别出在类型库中声 明了的void*类型。除了在参数被传递到这种类型时不会进行字符串转换之外,void*类型 都可以等同于Any—样来看待。从VB5开始,void*支持能够作用于任何类型的VarPtr声 明。关于Any和void*,它们存在着同样一个缺点,即编译器并不支持传递一个数组到这 两种类型上。”

问题:
(1)VB里也能用Void*?怎么个用法
(2)“VB支持三种在函数声明中没有进行类型定义的变量。”哪3种?看来看去只有Any这一种啊? --------------------编程问答-------------------- 这是我搜的

关于ANY的问题 

   如果以一个老师的身份来说话,我会说:最好永远也不要用Any!是的,我没说错,是永远!所以我没有把它放在程咬金的三板斧里。当然,这个问题和是不是应该使用指针这个问题一样会引发一场没有结果的讨论,我告诉你的只是一个观点,因为有时我们会为了效率上的一点点提高或想偷一点点懒而去用Any,但这样做需要要承担风险。 

   Any不是一个真正的类型,它只是告诉VB编译器放弃对参数类型的检查,这样,理论上,我们可以将任何类型传递给API。 

   Any在什么地方用呢?让我们来看看,在VB文档里的是怎么说的,现在就请打开MSDN(Visual Studio 6自带的版本),翻到"Visual Basic文档"->"使用Visual Basic"->"部件工具指南"->"访问DLL和Windows API"部分,再看看"将 C 语言声明转换为 Visual Basic 声明"这一节。文档里告诉我们,只有C的声明为LPVOID和NULL时,我们才用Any。实际上如果你愿意承担风险,所有的类型你都可以用Any。当然,也可以如我所说,永远不要用Any。 

   为什么要这样?那为什么VB官方还要提供Any?是信我的,还是信VB官方的?有什么道理不用Any? 

   如前面所说,VB官方不鼓励我们使用指针。因为VB所标榜的优点之一,就是没有危险的指针操作,所以的内存访问都是受VB运行时库控制的。在这一点上,JAVA语言也有着同样的标榜。但是,同JAVA一样,VB要避免使用指针而得到更高的安全性,就必须要克服没有指针而带来的问题。VB已经尽最大的努力来使我们远离指针的同时拥有强类型检查带来的安全性。但是操作系统是C写的,里面到处都需要指针,有些指针是没有类型的,就是C程序员常说的可怕的void*无类型指针。它没有类型,因此它可以表示所有类型。如CopyMemory所对应的是C语言的memcpy,它的声明如下: 

void *memcpy( void *dest, const void *src, size_t count ); 

   因memcpy前两个参数用的是void*,因此任何类型的参数都可以传递给他。 

   一个用C的程序员,应该知道在C函数库里这样的void*并不少见,也应该知道它有多危险。无论传递什么类型的变量指针给上面memcpy的void*,C编译器都不会报错或给任何警告。 

   在VB里大多数时候,我们使用Any就是为了使用void*,和在C里一样,VB也不对Any进行类型检查,我们也可以传递任何类型给Any,VB编译器也都不会报错或给任何警告。 

   但程序运行时会不会出错,就要看使用它时是不是小心了。正因为在C里很多错误是和void*相关的,所以,C++鼓励我们使用satic_cast<void*>来明确指出这种不安全的类型的转换,已利于发现错误。 

   说了这么多C/C++,其实我是想告诉所有VB的程序员,在使用Any时,我们必须和C/C++程序员使用void*一样要高度小心。 --------------------编程问答-------------------- Public Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

鄙视一下西西 --------------------编程问答--------------------
引用 4 楼 qingye2008 的回复:
Public Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName AsString, ByVal lpKeyName AsAny, ByVal lpDefault AsString, ByVal lpReturnedString AsString, ByVal nSize AsLong, ByVal lpFileName AsString) AsLong

鄙视一下西西


怎么个意思?没看懂你的BS --------------------编程问答--------------------
引用 2 楼 slowgrace 的回复:
看这段话:

“VB支持三种在函数声明中没有进行类型定义的变量。第一种类型即Any,仅仅在VB 的声明陈述中被允许,它承认任何非数组类型的变量。并且数据被传递到任何类型的参数 中并自动的经过UNICODE/ANSI/UNICODE转换。而且,VB还能够识别出在类型库中声 明了的void*类型。除了在参数被传递到这种类型时不会进行字符串转换之外,void*类型 都可以等同于Any—样来看待。从VB5开始,void*支持能够作用于任何类型的VarPtr声 明。关于Any和void*,它们存在着同样一个缺点,即编译器并不支持传递一个数组到这 两种类型上。”

问题:
(1)VB里也能用Void*?怎么个用法
(2)“VB支持三种在函数声明中没有进行类型定义的变量。”哪3种?看来看去只有Any这一种啊?

你这都是哪上面的语句? --------------------编程问答-------------------- 不是 --------------------编程问答-------------------- void* 是无类型指针,它至少应该是一个指针。
Any 是对应 API 声明的无类型参数,比 void* 的适用范围更广:

int MapWindowPoints(
  HWND hWndFrom,     // handle of window to be mapped from
  HWND hWndTo,       // handle to window to be mapped to
  LPPOINT lpPoints,  // pointer to array with points to map
  UINT cPoints       // number of structures in array
);

参数 lpPoints 除了可以传递 POINT*,还可以传递 RECT*,当然需要指针类型转换。

Public Declare Function MapWindowPoints Lib "user32.dll" ( _ 
 ByVal hwndFrom As Long, _ 
 ByVal hwndTo As Long, _ 
 ByRef lppt As Any, _ 
 ByVal cPoints As Long) As Long

相对与定义为指针自己取结构地址、或者声明为两个不同参数的版本,Any 参数就可以直接使用 POINT 或 RECT 结构作为变量调用了。
补充:VB ,  非技术类
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,