送分100分:NULL,Empty和空字符串的区别

ershiniwo 2010-03-02 06:22:21
看到有关资料上有如下说明:
Null 值指出变量不包含有效数据。Null 与 Empty 不同,后者指出变量未经初始化。Null 与零长度字符串 ("") 也不同,零长度字符串往往指的是空串。

现有以下几个问题:
(1)Null 值指出变量不包含有效数据,什么是其所谓的有效数据
(2)Empty 变量未经初始化,什么是变量的初始化,根据什么判断此变量是否初始化。
(3)零长度字符串与NULL到底有什么区别。

...全文
601 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
bcrun 2010-03-03
  • 打赏
  • 举报
回复
引用 25 楼 ershiniwo 的回复:
看来这两种方式是达不到判断RST.FIELDS("姓名")是否为""的目的,
(1)是不是可以是if RST.FIELDS("姓名")=""来判断,
(2)为什么看好多资料都是用ISNULL(RST.FIELDS("姓名"))或ISEMPTY(RST.FIELDS("姓名"))来判断呢。
 


(1)看来楼主还是不习惯封装函数哦,我说的那个函数AsString 就是封装了,供你在做这种编码时用的啊:
if (Len(AsString(RST.FIELDS("姓名")) = 0) then '直接判断长度快些
if (AsString(RST.FIELDS("姓名")) = vbNullString) then
if (AsString(RST.FIELDS("姓名")) ="") then '要分配一个空字符串,慢些
当然,我的AsString是通过赋值加异常处理实现的,你用ISNULL,ISEMPTY,TypeName等综合处理也是可以的

(2)不清楚别人只用ISNULL,ISEMPTY一类在他那个功能的实际需求中是否够用,但这世界上没写正确的代码很多的,也无需奇怪:)
白云飘飘飘 2010-03-03
  • 打赏
  • 举报
回复
你用这个测试一下:
MsgBox TypeName(RST.FIELDS("姓名"))
king06 2010-03-03
  • 打赏
  • 举报
回复
1.公司里有水,但是没杯子,那么水对你来说是"无效的"
2.dim a 就是没初始化,默认是variant类型
dim a as string 就是已初始化为字符串类型
3.零长度和null <--> 有张白纸和什么都没有.

A=ISNULL(RST.FIELDS("姓名")) 'A=FALSE
A=ISEMPTY(RST.FIELDS("姓名")) 'A=FALSE
这样才正常,你的数据库中那个值是"",不是null.
要判断是否为"",先判断是否为null.
先判断你是否有张白纸,再判断纸上是否有内容.
Tiger_Zhao 2010-03-03
  • 打赏
  • 举报
回复
程序逻辑要与数据一致。
就像有的餐馆桌子上放醋有的放辣酱,没有定例。
ershiniwo 2010-03-03
  • 打赏
  • 举报
回复
谢谢。bcrun。

我刚刚试了一下,当RST.FIELDS("姓名")为空时,即姓名字段没有数据时,
DIM A AS BOOLEAN
A=ISNULL(RST.FIELDS("姓名")) 'A=FALSE
A=ISEMPTY(RST.FIELDS("姓名")) 'A=FALSE

看来这两种方式是达不到判断RST.FIELDS("姓名")是否为""的目的,
(1)是不是可以是if RST.FIELDS("姓名")=""来判断,
(2)为什么看好多资料都是用ISNULL(RST.FIELDS("姓名"))或ISEMPTY(RST.FIELDS("姓名"))来判断呢。
yeahscnd 2010-03-03
  • 打赏
  • 举报
回复
引用 30 楼 lhcwjy 的回复:
楼主,你的房间号字段是文本还是数值?

文本
bcrun 2010-03-03
  • 打赏
  • 举报
回复
说了行啊,原因19楼已经说了
"Null和Empty均只对Variant数据类型有效"


Property Value As Variant
ADODB.Field20 的缺省成员
ershiniwo 2010-03-03
  • 打赏
  • 举报
回复
谢谢。大家。

还是请再回答一下:

再请问一下,这个ISNULL到底可不可以用到比如RST.FIELDS("姓名")这种数据类型上,也就是ISNULL(RST.FIELDS("姓名"))这种用法对是不对。
bcrun 2010-03-03
  • 打赏
  • 举报
回复
引用 18 楼 ershiniwo 的回复:
再请问一下,这个ISNULL到底可不可以用到比如RST.FIELDS("姓名")这种数据类型上,也就是ISNULL(RST.FIELDS("姓名"))这种用法对是不对。


行,可以这样写
guoshaoning 2010-03-03
  • 打赏
  • 举报
回复
晕呐,看来我知道的简直真的太皮毛了!~学习~~
Tiger_Zhao 2010-03-03
  • 打赏
  • 举报
回复
只有19楼是对的。
VB(或者说 COM)中的 Null 和 Empty 都是通过 Variant 结构体的类型指示符来标记的,不要将 VB 的 Null 和 C 中的 NULL 指针搞混了。

当然 Deciaml 类型的 Variant 数据域有 12 字节,不总是固定 8 字节,不过这不影响其他描述的正确性。
lyserver 2010-03-03
  • 打赏
  • 举报
回复
引用楼主 ershiniwo 的回复:
(1)Null 值指出变量不包含有效数据,什么是其所谓的有效数据
(2)Empty 变量未经初始化,什么是变量的初始化,根据什么判断此变量是否初始化。
(3)零长度字符串与NULL到底有什么区别。

首先需要明确的是,Null和Empty均只对Variant数据类型有效,而Variant数据类型在内存中占16个字节,其中前两个字节表示Variant数据类型的实际类型,中间6个字节保留,最后8个字节为数据域,为指针或实际数据的联合体。
(1)当Variant变量值为Null时,它表示Variant变量的实际类型为VT_NULL(常量1),数据域的指针指向的无效区域(指针值可能为0也可能不为0),经常用来与表示数据表包含Null的字段值。IsNull函数实际检测Variant变量的前2个字节,即Variant结构体中的VT成员。
(2)当Variant变量为Empty时,它表示Variant结构体中的前2个字节(即VT成员)值为VT_EMPTY(常量0),即Variant结构体的16个字节均为0,以此作为变量是否被赋值或初始化的依据。
(3)至于VB的字节串,与标准C的CHAR字符串不一样的是,它是一个自包含串长度的WCHAR类型的字符串,假设有以下代码:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Sub main()
Dim s As String
Dim nLen As Long

s = "abcd"
CopyMemory nLen, ByVal StrPtr(s) - 4, 4
Debug.Print nLen
End Sub
运行后可以看出,nLen值为8。为什么是8呢,因为VB字符串为WCHAR字符串嘛,即不管中英文,所有字符均用两个字节表示。
实际上,VB字符串在内存中的布局可以用以下结构体包含:
Type BSTR
Length As Long
Text(Length - 1) As Byte
End Type
而字符串变量实际上是一个指针,它指向的地址不是Length,而是Text,当指针值为vbNullString时,表示字符串变量没有申请和指向任何内存,当变量值为""时,表示字符串变量申请了内存,但该内存中的Length成员为0,Text为空。因此,vbNullString表示空指针,其StrPtr值为0,而0长度字符串的StrPtr值不为0。
ershiniwo 2010-03-03
  • 打赏
  • 举报
回复
再请问一下,这个ISNULL到底可不可以用到比如RST.FIELDS("姓名")这种数据类型上,也就是ISNULL(RST.FIELDS("姓名"))这种用法对是不对。
of123 2010-03-03
  • 打赏
  • 举报
回复

从最底层来解释就容易明白了。

这三个概念的区别在有指针时才有效:

你可以字符串为例,简单地想象,它组成如下:

指针(指向实际内存中的起始地址)| 初始化标志 | 字符串长度 | 实际的字符串值(在分配的内存中)

NuLL - 指针是 0,也就是还没有分配存储空间。也就是尚未实例化。
Empty - 指针已经赋值,但分配的空间还没有进行初始化。实际上是标志还没有写。
零长度串 - 指针已经赋值,分配的空间也进行了初始化。但长度域是 0。
bcrun 2010-03-03
  • 打赏
  • 举报
回复
引用 15 楼 liguicd 的回复:
引用 1 楼 lhcwjy 的回复:...当我们声量了一个字符串变量并且未对它赋值之前,它是Null。...

是这样的么?可是我怎么记得字符串变量声明后初始值是空字符串呢?


你综合看下(宏景工作室) 的发言,其实这一点他是承认的,但他说主要想强调的是,VB对这个空字符串初值不是以相当于str = ""这样的方式实现的,因为这样实现的话,StrPtr(str)<>0,说明分配了相应的内存. VB是以相当于str = vbNullString 这样的方式实现的,StrPtr(str)=0,说明是零"字符串指针".
关键在于,VB在字符串运算包括逻辑运算时,会把零"字符串指针"和空字符串""做等价处理.
注意,这种相当于str = ""实现的赋值,会有StrPtr(str)<>0,是对字符串值本身分配了内存的,具体来说,分配了的内存中包含了UNICODE编码的双字节的结束字符(编码为0).而零"字符串指针"vbNullString就不存在这种分配.

如果你要了解VB6中字符串实现的细节,可参看Mattew Curland的<高级Visual Basic>编程,至少看三遍:)
白云飘飘飘 2010-03-03
  • 打赏
  • 举报
回复
楼主,你的房间号字段是文本还是数值?
liguicd 2010-03-02
  • 打赏
  • 举报
回复
引用 1 楼 lhcwjy 的回复:
...当我们声量了一个字符串变量并且未对它赋值之前,它是Null。...


是这样的么?可是我怎么记得字符串变量声明后初始值是空字符串呢?

变量声明: 显式声明 隐式声明

显示声明:在变量使用之间用dim、 staic、 public、 private 语句声明

dim 可一次声明多个变量,声明后VB会自动为该变量赋初值。

若变量是数据型,则赋初值为 0

若变量是字符型,则赋初值为 空字符串

若未定义数据类型,则缺省为Variant变体型

隐式声明:在使用一个变量之前不声明,而是用一个特殊的类型符号加在变量名后面来说明数据类型

% 表示 integer ! 表示 single

& 表示 Long # 表示 Double

$ 表示 String @ 表示 Currency

隐式说明如果未含类型符号,则表示为Variant 类型

强制声明:Option Explicit 语句 强制变量在使用前声明
liguicd 2010-03-02
  • 打赏
  • 举报
回复
引用 1 楼 lhcwjy 的回复:
VB中的IsNull和IsEmpty用于Variant变量时才有意义,不过Null和空也经常与字符串变量用在一起。
先说字符串:当我们声量了一个字符串变量并且未对它赋值之前,它是Null。在VB中字符串变量实质上是一个指针变量。也就是说这时候指针为零。对于已经赋值的字符串,也可以把它变成Null,如str=VBNullString.当我们这样赋值时:str="",它就是“空”了。这时时候,指针已经不是零了,它已经指向了一个数据区,但这个数据区没有包含字符。大体上可以这样理解。

再说Variant.当我们声量了一个,如var as Variant;这是它是Empty(未初始化),用IsEmpty测试是true;当我们为它赋值以后,var="abc";这时它非empty非null.如果我们不想要这个字符串了,可以这样:var=null.这就叫做Null(未含有有效数据)。

是这样的么?可是我怎么记得字符串变量声明后初始值是空字符串呢?

变量声明: 显式声明 隐式声明

显示声明:在变量使用之间用dim、 staic、 public、 private 语句声明

dim 可一次声明多个变量,声明后VB会自动为该变量赋初值。

若变量是数据型,则赋初值为 0

若变量是字符型,则赋初值为 空字符串

若未定义数据类型,则缺省为Variant变体型

隐式声明:在使用一个变量之前不声明,而是用一个特殊的类型符号加在变量名后面来说明数据类型

% 表示 integer ! 表示 single

& 表示 Long # 表示 Double

$ 表示 String @ 表示 Currency

隐式说明如果未含类型符号,则表示为Variant 类型

强制声明:Option Explicit 语句 强制变量在使用前声明
gukuang78 2010-03-02
  • 打赏
  • 举报
回复
俺是来围观细节的……
贝隆 2010-03-02
  • 打赏
  • 举报
回复
IsEmpty 函数


返回 Boolean 值,指出变量是否已经初始化。

语法

IsEmpty(expression)

必要的 expression 参数是一个 Variant,包含一个数值或字符串表达式。但是,因为 IsEmpty 被用来确定个别变量是否已初始化,所以 expression 参数通常是单一变量名。

说明

如果变量未初始化或已明确设置为 Empty,则 IsEmpty 返回 True;否则返回 False。如果 expression 含有多个变量,则 IsEmpty 总是返回 False。IsEmpty 只返回对 variant 表达式有意义的信息。
加载更多回复(11)

1,502

社区成员

发帖
与我相关
我的任务
社区描述
VB 网络编程
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧