
正文
vb.net空指针 空指针null以及void指针
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
vb.net如何读写二进制文件? 有各种类型的变量
open函数用来打开一个文件,其调用的一般形式为:
文件指针名=fopen(文件名,使用文件方式);
其中,
“文件指针名”必须是被说明为FILE
类型的指针变量;
“文件名”是被打开文件的文件名;
“使用文件方式”是指文件的类型和操作要求。
“文件名”是字符串常量或字符串数组。
例如:
FILE
*fp;
fp=("file
a","r");
其意义是在当前目录下打开文件file
a,只允许进行“读”操作,并使fp指向该文件。
又如:
FILE
*fphzk
fphzk=("c:\\hzk16","rb")
其意义是打开C驱动器磁盘的根目录下的文件hzk16,这是一个二进制文件,只允许按二进制方式进行读操作。两个反斜线“\\
”中的第一个表示转义字符,第二个表示根目录。
使用文件的方式共有12种,下面给出了它们的符号和意义。
文件使用方式
意义
“rt”
只读打开一个文本文件,只允许读数据
“wt”
只写打开或建立一个文本文件,只允许写数据
“at”
追加打开一个文本文件,并在文件末尾写数据
“rb”
只读打开一个二进制文件,只允许读数据
“wb”
只写打开或建立一个二进制文件,只允许写数据
“ab”
追加打开一个二进制文件,并在文件末尾写数据
“rt+”
读写打开一个文本文件,允许读和写
“wt+”
读写打开或建立一个文本文件,允许读写
“at+”
读写打开一个文本文件,允许读,或在文件末追加数据
“rb+”
读写打开一个二进制文件,允许读和写
“wb+”
读写打开或建立一个二进制文件,允许读和写
“ab+”
读写打开一个二进制文件,允许读,或在文件末追加数据
对于文件使用方式有以下几点说明:
1)
文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:
r(read):
读
w(write):
写
a(append):
追加
t(text):
文本文件,可省略不写
b(banary):
二进制文件
+:
读和写
2)
凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。
3)
用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。
4)
若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。但此时该文件必须是存在的,否则将会出错。
5)
在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。因此常用以下程序段打开文件:
6)
if((fp=fopen("c:\\hzk16","rb")==NULL)
{
printf("\nerror
on
open
c:\\hzk16
file
相关问答
Q1: vb.net 中 nothing和“”空的字符串 有什么区别吗?我查了一下没看懂他们说的什么意思。。。
在VB.NET里vb.net空指针,给变量赋值NoThingvb.net空指针,其结果将对该变量赋予初始值vb.net空指针;
而对于字符串变量初始值就是“”,数值变量初始值为0,布尔变量初始值为False。
所以对于字符串变量,赋予NoThing与赋予""是相同vb.net空指针的。
Q2: 什么是多线程技术?在VB 中如何使用?
vb6可以实现多线程,不过比较麻烦,vb.net完全支持多线程,请参见msdn.
至于vb6实现多线程请看CreateThread这个API函数.以下有详细方案:
用VB写多线程程序用到的第一个API函数是CreateThread,这个函数的声明如下vb.net空指针:
Private Declare Function CreateThread Lib "kernel32" (ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long)As Long
这个函数的返回值是线程的句柄,它的参数含义如下vb.net空指针:
1.lpThreadAttributes:这个参数表明函数的返回句柄是否可被子进程继承,如果可被继承,则指向一个SECURITY_ATTRIBUTES的结构,否则设为vbnull。
2.dwStackSize:这个参数设置线程的堆栈大小。
3.lpStartAddress:这个参数指明这个线程函数的起始地址。
4.lpParameter:这个参数是传给线程函数的参数。
5.dwCreationFlags:这个参数设置当线程创建时的初始状态,挂起,运行等等。
6.lpThreadId:这个参数是待创建线程的ID号。
假设创建一个管理线程的类clsThreads,用类的一个公用函数Initialize来初始化线程,用ResumeThread和SuspendThread函数来激活线程,实现代码如下:
Private Type udtThread
Handle As Long
Enabled As Boolean
End Type
Private uThread As udtThread
Private Const CREATE_SUSPENDED As Long = H4
Private Declare Function CreateThread Lib "kernel32" (ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Private Declare Function ResumeThread Lib "kernel32" (ByVal hThread As Long) As Long
Private Declare Function SuspendThread Lib "kernel32" (ByVal hThread As Long) As Long
Private Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Public Sub Initialize(ByVal lpfnBasFunc As Long) '初始化线程
Dim lStackSize As Long, lCreationFlags As Long, lpThreadId As Long, lNull As Long
On Error Resume Next
lNull = 0 '创建一个空指针
lStackSize = 0 '0表示用exe的stack size
lCreationFlags = CREATE_SUSPENDED '表示初始化后先不激活,让别人来激活
uThread.Handle = CreateThread(lNull, lStackSize, lpfnBasFunc, lNull, lCreationFlags, lpThreadId)
If uThread.Handle = lNull Then MsgBox "Create thread failed!"
End Sub
Public Property Get Enabled() As Boolean
On Error Resume Next
Enabled = uThread.Enabled
End Property
Public Property Let Enabled(ByVal vNewValue As Boolean)
On Error Resume Next
If vNewValue And (Not uThread.Enabled) Then
ResumeThread uThread.Handle '激活线程
uThread.Enabled = True
ElseIf uThread.Enabled Then
SuspendThread uThread.Handle
uThread.Enabled = False
End If
End Property
Private Sub Class_Terminate() '终止线程
On Error Resume Next
Call TerminateThread(uThread.Handle, 0)
End Sub
以上内容在类模块clsThreads中,有vb.net空指针了它就可以在窗体中实现多线程vb.net空指针了。下面以一个简单的例子来说明如何创建多线程(以2个线程为例)。
在form1中添加picture1和picture2两个图片框,以及一个command1按钮,在工程中添加一个bas模块,该模块的代码如下:
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Public Sub FlickerTop()
Static BgColor As Long
Dim lTick As Long, lCounter As Long
On Error Resume Next
For lCounter = 0 To 60000
BgColor = lCounter Mod 256
Form1.Picture1.BackColor = RGB(BgColor, 0, 0) '变化图片框的颜色
lTick = GetTickCount
While GetTickCount - lTick 10 '延迟10个毫秒时间
Wend
Next
End Sub
Public Sub FlickerBottom()
Static BgColor As Long
Dim lTick As Long, lCounter As Long
On Error Resume Next
For lCounter = 0 To 60000
BgColor = lCounter Mod 256
Form1.Picture2.BackColor = RGB(0, BgColor, 0)
lTick = GetTickCount
While GetTickCount - lTick 10
Wend
Next
End Sub
最后在form1中用下面的代码来创建两个线程,
Option Explicit
Public myThreadTop As New clsThreads, myThreadBottom As New clsThreads
Private Sub Command1_Click()
On Error Resume Next
With myThreadTop
.Initialize AddressOf FlickerTop
.Enabled = True
End With
With myThreadBottom
.Initialize AddressOf FlickerBottom
.Enabled = True
End With
MsgBox "看看会有什么..."
Set myThreadTop = Nothing
Set myThreadBottom = Nothing
End Sub
Q3: vb.net用指针或变量调用函数
指针是c语言的概念,VB、VB.NET没有指针,除了指针以外也很少有人能玩到vb.net空指针你的编程深度,关键看不懂呢。
vb.net空指针?vb.net空指针??就是子程序的名称,比如每次点击c后就自动调动相对应的子程序,如子程序是
Private Sub my_do ()
........
End Sub
相应的AddHandler c.Click, AddressOf my_do
实际上是个委托
Q4: 用最简单的代码介绍一下指针在VB.net里面的用法?
例1:以下程序我们申请几个指向不同类型的指针:
’使用StructLayout(LayoutKind.Sequential)属性告诉net编译器:结构的元素在内存中按其出现的顺序排列
StructLayout(LayoutKind.Sequential) _
Public Structure DEFUDT_Test
Public bytb As Byte
Public i32a As Int32
End Structure
Public Function fnGetIntptr1() As IntPtr
’取得一个4字节数组指针
Dim tabytTest(3) As Byte
’以下语句告诉net垃圾回收进程不对tabytTest进行处理,也就是说tabytTest占用的内存区域固定不变。
Dim thObject As GCHandle = GCHandle.Alloc(tabytTest, GCHandleType.Pinned)
Dim tpObject As IntPtr = thObject.AddrOfPinnedObject() ’取得指向字节数组的指针
’取得一个指向32位内存数据的指针,
’由于使用gchandle取指针的方法只能对引用的对象有效,
’所以对如int32等值类型必须使用将其封装成为一个对象的方法以变为引用类型
Dim ti32Test As Object = Convert.ToInt32(0)
’以下语句告诉net垃圾回收进程不对ti32test进行处理,也就是说ti32Test的内存位置固定不变。
Dim thObject1 As GCHandle = GCHandle.Alloc(ti32Test, GCHandleType.Pinned)
Dim tpObject1 As IntPtr = thObject1.AddrOfPinnedObject() ’取得ti32Test的首地址
Dim tudtTest1 As DEFUDT_Test
’由于结构是一种值类型变量,为保证指针申请方便,我们申请
’取得一个和结构tudtTest1大小一致的字节数组指针,只要空间占用长度和结构一样就可以了
’由于net在结构封装中会插入额外的数据位,所以一定要用sizeof方法得到结构在非托管使用时的实际大小
Dim tudtTest(Marshal.SizeOf(tudtTest1)) As Byte
Dim thObject2 As GCHandle = GCHandle.Alloc(tudtTest, GCHandleType.Pinned)
Dim tpObject2 As IntPtr = thObject2.AddrOfPinnedObject() ’取得指向结构的指针
’在这儿你可以写对指针处理的任意代码(在例2中会给予补充)……
’在使用完毕后一定要释放指针指向的内存块,让垃圾回收器可对这个内存块回收处理
If thObject.IsAllocated Then
thObject.Free()
End If
If thObject1.IsAllocated Then
thObject1.Free()
End If
If thObject2.IsAllocated Then
thObject2.Free()
End If
End Function
上例中指针流程处理可以归纳为:
1、 定义一个具有合适内存长度的引用变量(关于引用变量和值变量的差异可以参观VB.NET的书籍)
2、使用GCHandle.Alloc方法将变量的内存区域固定下来。
3、使用GCHandle对象的AddrOfPinnedObject取得该内存区域的首地址并赋值给指针变量.
4、对指针进行操作
5、使用GCHandle对象的free方法释放指针指向的内存区域以便net垃圾回收器可以回收这个内存空间
2、指针所指向数据的存取
在.net中,对指针指向数据的存储函数都封装在marshal类中,主要的函数包括:Copy、PtrToStringUni 、PtrToStructure 、OffsetOf、WriteXXX,RreadXXX等,其中WriteXXX的表示向指针所表示的地址中写入XXX类型的数据,而ReadXXX中作用就是将指针所在地址的数据以XXX类型方式读出。看例程2,我们使用这些方法演示对例1那几个指向不同类型数据的指针作数据存/取操作。
例2:演示向例1申请得到的几个指针执行写入及读取数据的操作.
Marshal.WriteInt32(tpObject1, 0, Convert.ToInt32(77)) ’向ti32Test变量指向的地址写入32位整数77
MsgBox("现在ti32Test的值为:" ti32Test) ’因为变量存储地址的数据已改为77,所以显示为77
’以下这句之所以可行,因为ti32Test是32位整数,而tpObject指向的tabytTest数组刚好有4个元素
’而每一个byte元素都占用8位,合起来就是32位,和ti32Test占用的空间一样。这就印证了前面提’
’到的net中指针没有指向类型的说明。
Marshal.WriteInt32(tpObject, 0, ti32Test)
’以下代码再将tabytTest字节数组的内容理解为一个int32整数,
’并将值赋值给tudtTest结构中的int32元素
’我们使用Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32以取得i32a元素在结构中的内存偏移位置
’所以New IntPtr(tpObject2.ToInt32 + Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32)就临时产生了
’一个指针并指向i32a所在的内存地址(, 这个方法也说明了指针可以以字节为单位进行加减计算以指向合适的变量。
’Marshal.ReadInt32的作用是从指针中读取一个32整数。
Marshal.WriteInt32(New IntPtr(tpObject2.ToInt32 + Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32), _
0, Marshal.ReadInt32(tpObject))
’这儿可以将字节数组的内容复制到真正的结构中
MsgBox(Marshal.OffsetOf(tudtTest1.GetType, "i32a").ToInt32)
tudtTest1 = CType(Marshal.PtrToStructure(tpObject2, GetType(DEFUDT_Test)), DEFUDT_Test)
MsgBox("结构tidtTest1中i32a元素的值为:" tudtTest1.i32a) ’此处将显示刚赋的值77
关于vb.net空指针和空指针null以及void指针的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。







