`
ta8210
  • 浏览: 14936 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

[老文章转载]C#中使用指针

阅读更多
我想许多C程序员不愿意学习Java的原因就是Java不支持指针,但是现在类似于Java的C#却已经支持了指针,你可以使用unsafe关键字来告诉编译器下面的函数或者代码是不安全的。一旦你使用了unsafe,那么你就可以在unsafe区域中使用指针。

程序1
usingSystem;
classnish
...{
unsafestaticvoidIncrement(int*p)
...{
//incrementtheintpointedtobyp
*p=*p+1;
}

publicstaticvoidMain()
...{
inti=1;
//wepasstheaddressoftheinttothefunctionasitexpectsapointer
unsafeIncrement(&i);
//nowweprintoutthevalueofi
Console.WriteLine(i);
}

}


当你运行这个程序,你将会看到输出结果2。这是因为你已经将变量i的地址送给了函数Increment来处理。变量i建立于栈中,&i则表示它在栈中的地址。这样在函数Increment中,p就指向i的地址,当我们对*p加1时,实际上是对变量i进行增加。

程序2
下面的程序将会让你更清楚的了解:
usingSystem;
classnish
...{
unsafepublicstaticintMain()
...{
intj=100;
intk=100;
Console.WriteLine(
"addressofj={0}andaddressofk={1}",(int)&j,(int)&k);
Console.WriteLine(
"j={0}k={1}",j,k);
int*p;
p
=&j;
Console.WriteLine(
"pnowpointsto{0}",(int)p);
*p=200;
Console.WriteLine(
"j={0}k={1}",j,k);
p
=&k;
Console.WriteLine(
"pnowpointsto{0}",(int)p);
*p=300;
Console.WriteLine(
"j={0}k={1}",j,k);

return0;
}

}



当运行上面的程序,我们将得到下面的结果。你会看到一些你熟悉的东东,下面的输出结果将会清楚的看到程序执行的过程:

address of j=1244312 and address of k=1244308
j=100 k=100
p now points to 1244312
j=200 k=100
p now points to 1244308
j=200 k=300

首先将变量的j的地址赋给p,这样当我们改变*p时,j的值也将自动改变。接着我们将p指向变量k的地址,这时改变*p则是在改变k。

同样需要清楚的就是变量p也有自己的地址,下面的程序将会清楚的告诉您一切。

程序 3
usingSystem;
classnish
...{
publicstaticvoidMain()
...{
unsafe
...{
inta=100;
int*p;
p
=&a;
Console.WriteLine(
"addressofais{0}",(int)&a);
Console.WriteLine(
"pnowpointsto{0}",(int)p);
Console.WriteLine(
"addressofthepointervariablepis{0}",(int)&p);
}

}

}


一运行上面的代码,我们将获得下面显示的输出。你将同样获得一些类似的输出,注意这里unsafe关键字的使用。

address of a is 1244312
p now points to 1244312
address of the pointer variable p is 1244308

1244308是指针变量p的地址,而1244312则是指针p所指向的地址,我们使用*p来获得。

程序 4
Okey。在最后的一个程序中,我将向大家介绍如何使用指针来操作字符串。在这个程序中存在一个程序来将一段字符串通过异或运算进行编码解码的操作。如果您将一段字符串送入这个函数这个字符串将会被编码,如果您将一段已经编码的字符送入这个函数,这段字符串将会被解码。当这并不是一个安全的加密方法,我仅仅是想通过这个例子来演示一下指针的作用。
usingSystem;
classnish
...{
publicstaticvoidMain()
...{
strings="CodeProjectiscool";
Console.Write(
"theoriginalstring:");
Console.WriteLine(
"{0} ",s);

char[]b=newchar[100];
s.CopyTo(
0,b,0,20);

Console.Write(
"theencodedstring:");
unsafefixed(char*p=b)NEncodeDecode(p);
for(intt=0;t<20;t++)
Console.Write(b[t]);
Console.WriteLine(
" ");

Console.Write(
"thedecodedstring:");
unsafefixed(char*p=b)NEncodeDecode(p);
for(intt=0;t<20;t++)
Console.Write(b[t]);
Console.WriteLine();

}

unsafepublicstaticvoidNEncodeDecode(char*s)
...{
intw;
for(inty=0;y<20;y++)
...{
w
=(int)*(s+y);
w
=w^5;
*(s+y)=(char)w;
}

}



下面是我得到的输出,你也同样可以得到:

the original string : Code Project is cool

the encoded string : Fja`%Uwjo`fq%lv%fjji

the decoded string : Code Project is cool

本例中,你会发现一个新的关键字--fixed。当你在语句或函数之前使用fixed时,你是在告诉.Net平台的垃圾回收器,在这个语句或函数执行完毕前,不得回收其所占的内存空间。fixed关键字只能在不安全的代码中使用。本例中如果不使用fixed关键字,那么这段程序的执行的结果是不可预知的,因为垃圾回收器会不断的回收这些可控制代码的所占用的内存空间。幸运的是,编译器不会允许您指向可控制变量,除非您使用了fixed关键字。

在这个函数中,你看到我使用了*(s+y)表达式。s是指向字符串的地址(注意是首地址)。y则通过循环从0增加到19。这样*(s)给我们的地址是1000,*(s+1)则是1002,*(s+2)则是1004,以此类推。编译器知道我指向的是一个字符数据,因此第次就向前移动两个字节,因为char是16位的(这与c是不同的,c中char只占8位)。

结论
使用不安全代码时,必须十分小心,任何细小的错误,甚至是类型错误,都会导致输出结果的不可遇知,而且这种错误是很难调试发现。当然如果您是C/C++程序员,您已经对指针了解得十分透彻,那么当我的话没有说。呵呵,祝好运。
分享到:
评论

相关推荐

    C#中使用不安全代码(使用指针的代码)

    以下代码展示了如何在C#中使用指针快速复制字节数组: ```csharp // 使用 /unsafe 选项编译 using System; class Test { static unsafe void Copy(byte[] src, int srcIndex, byte[] dst, int dstIndex, int ...

    C#中使用指针

    ### C#中使用指针详解 #### 指针简介与基本使用 在C#语言中,虽然默认情况下为了安全性和内存管理的原因不支持指针,但为了满足某些特定场景的需求,C#还是提供了对指针的支持。使用指针可以让我们更加灵活地控制...

    C#结构体指针的定义及使用详解

    ### C#结构体指针的定义及使用详解 ...不过需要注意的是,使用指针时一定要小心,避免出现未定义行为或安全问题。在实际开发中,应该尽量避免不必要的非托管代码使用,以提高代码的安全性和可维护性。

    C#中使用指针源程序,我想许多C程序员不愿意学习Java的原因之一就是Java不支持指针

    C#中使用指针源程序,我想许多C程序员不愿意学习Java的原因就是Java不支持指针,但是现在类似于Java的C#却已经支持了指针,你可以使用unsafe关键字来告诉编译器下面的函数或者代码是不安全的。一旦你使用了unsafe,...

    C# csharp指针 案例

    在本篇案例中,我们将深入探讨C#中的指针及其用法。 首先,C#中的指针有三种类型:void*、T*(其中T是任何非引用类型)和固定缓冲区。void*类型的指针可以指向任何类型,但在C#中通常不推荐使用,因为它缺乏类型...

    C++ 与C#之间的指针参数传递传参参考

    C++ 与C#之间的指针参数传递,实现无限量数据的传递,轻松无压力,方便在C++里面获取或者从C#传递数据到C++的动态库调用内。

    C#中的指针和内存管理以及垃圾回收PPT

    在C#中,通过使用`unsafe`关键字,可以声明不安全代码块,从而允许使用指针。例如: ```csharp unsafe { int x = 10; int* ptr = &x; Console.WriteLine(*ptr); // 输出 10 } ``` #### 使用指针时的注意事项 ...

    c#指针偏移使用说明文档

    在C#中,默认情况下不允许使用指针,因为这可能导致程序不稳定或者产生安全隐患。为了能够使用指针,必须将方法标记为`unsafe`,这意味着编译器会允许指针操作,但同时也意味着程序员需要更加小心地编写代码以避免...

    教你C#里使用指针指针在C\C++里面可是一个好东西

    要在C#中使用指针,首先需要确保项目设置允许`unsafe`代码。这通常涉及到修改项目的编译选项,确保包含对不安全代码的支持。一旦完成这些设置,就可以使用`unsafe`关键字声明不安全的方法或类,并开始使用指针。 ##...

    C#指针 黑白虑镜效果

    虽然C#是一种安全的语言,通常避免直接使用指针来防止内存错误,但通过`unsafe`上下文,我们可以启用指针操作。在本教程中,我们将深入探讨如何使用C#指针实现黑白滤镜效果。 首先,让我们了解`unsafe`关键字。在C#...

    C# 调用C++DLL(函数参数包含指针)

    确保在C#中使用`Marshal`类的适当方法释放分配的内存。 6. **平台兼容性**:如果DLL是在64位环境下编译的,而C#应用程序是32位的,或者反之,可能会遇到“无法加载DLL”错误。确保编译的C#应用程序与DLL的平台兼容...

    c#实现指针时钟

    在C#中,实现这个功能需要利用Windows Presentation Foundation (WPF) 或 Windows Forms 库来创建图形用户界面,以及System.Timers命名空间中的Timer类来实现时间的更新。以下是关键知识点: 1. **图形用户界面**:...

    C#通过指针实现快速拷贝的方法

    在C#中,由于其安全性特性,通常不鼓励直接使用指针进行操作,因为这可能会引入潜在的安全风险和性能问题。然而,在某些情况下,如内存高效的数据操作或底层硬件交互时,指针的使用是必要的。本文将详细介绍如何在C#...

    LabVIEW to C#/C++ 指针读写

    指针在C++和C#中是内存地址的别名,它存储了一个变量在内存中的位置。在LabVIEW中,虽然没有直接的指针概念,但它提供了类似的数据结构,如“内存块”(Memory Array)和“内存指针”(Memory Pointer),用于处理...

    c#实现指针钟

    - 在C#中,我们不需要直接使用指针来处理时间或旋转图像。然而,如果要在更底层操作,比如直接画图时,可以使用Graphics的DrawImage方法配合unsafe代码块来提高性能。 代码示例: ```csharp using System; using ...

    C#_指针之美

    在 C# 中使用指针,需要在项目属性中选中“Allow unsafe code”,然后在使用指针的代码的上下文中使用 unsafe 关键字,表明这是一段unsafe 代码。可以用 unsafe { } 将代码围住,以便在编译时检查代码的安全性。 二...

    C#指针简单运用

    C#指针简单运用

    我用C#做的一个指针表盘控件

    标题中的“我用C#做的一个指针表盘控件”表明了这是一个使用C#编程语言开发的,专用于创建模拟指针式仪表盘的自定义控件。这种控件通常用于可视化显示如电压、电流、速度或温度等实时数据。在C#的标准工具箱中可能...

    c#指针图像处理图像处理图像处理

    根据给定的信息,本文将详细解释C#中的指针应用在图像处理中的具体实现方法,同时探讨代码片段中涉及的关键概念和技术。 ### C#指针与图像处理 #### 概述 C#作为一种广泛使用的面向对象编程语言,在.NET框架的支持...

    指针式仪表读数识别源代码(C#)

    在C#中实现这些功能,可以利用.NET Framework或.NET Core提供的丰富的图像处理库,比如AForge.NET、Emgu CV(OpenCV的C#接口)或者 Accord.NET。这些库提供了大量的图像处理和机器学习工具,可以帮助开发者快速构建...

Global site tag (gtag.js) - Google Analytics