简体   繁体   English

C#中的C指针

[英]C pointers in C#

Is this function declaration in C#: 这是C#中的函数声明:

void foo(string mystring)

the same as this one in C: 与C中的这个相同:

void foo(char *)

ie In C#, does the called function receive a pointer behind the scenes? 即在C#中,被调用函数是否在幕后接收指针?

In this specific instance, it is more like: 在这个特定的例子中,它更像是:

void foo(const char *);

.Net strings are immutable and passed by reference. .Net字符串是不可变的并通过引用传递。 However, in general C# receives a pointer or reference to an object behind the scenes. 但是,通常C#接收指向幕后对象的指针或引用。

There are pointers behind the scenes in C#, though they are more like C++'s smart pointers, so the raw pointers are encapsulated. C#中有幕后指针,虽然它们更像是C ++的智能指针,因此原始指针被封装起来。 A char* isn't really the same as System.String since a pointer to a char usually means the start of a character array, and a C# string is an object with a length field and a character array. char *与System.String实际上并不相同,因为指向char的指针通常表示字符数组的开头,而C#字符串是具有长度字段字符数组的对象。 The pointer points to the outer structure which points into something like a wchar_t array, so there's some indirection with a C# string and wider characters for Unicode support. 指针指向外部结构,指向类似于wchar_t数组的内容,因此存在一些带有C#字符串的间接和用于Unicode支持的更宽字符。

No. In C# (and all other .NET languages) the String is a first-class data type. 在C#(以及所有其他.NET语言)中,String是一流的数据类型。 It is not simply an array of characters. 它不仅仅是一个字符数组。 You can convert back and forth between them, but they do not behave the same. 您可以在它们之间来回转换,但它们的行为不一样。 There are a number of string manipulation methods (like "Substring()" and "StartsWith") that are available to the String class, which don't apply to arrays in general, which an array of characters is simply an instance of. String类中有许多字符串操作方法(如“Substring()”和“StartsWith”),它们通常不适用于数组,而字符数组只是一个实例。

Essentially, yes. 基本上,是的。 In C#, string (actually System.String) is a reference type, so when foo() is called, it receives a pointer to the string in the heap. 在C#中,string(实际上是System.String)是一个引用类型,因此当调用foo()时,它会收到指向堆中字符串的指针。

For value types (int, double, etc.), the function receives a copy of the value. 对于值类型(int,double等),函数接收值的副本。 For other objects, it's a reference pointing to the original object. 对于其他对象,它是指向原始对象的引用。

Strings are special because they are immutable. 字符串是特殊的,因为它们是不可变的。 Technically it means it will pass the reference, but in practice it will behave pretty much like a value type. 从技术上讲,这意味着它将传递引用,但实际上它的行为非常类似于值类型。

You can force value types to pass a reference by using the ref keyword: 您可以使用ref关键字强制值类型传递引用:

public void Foo(ref int value) { value = 12 }
public void Bar()
{
    int val = 3;
    Foo(ref val);
    // val == 12
}

no in c# string is unicode. c#string中的no是unicode。 in c# it is not called a pointer, but a reference. 在c#中,它不是一个指针,而是一个引用。

如果你的意思是 - 将允许该方法访问字符空间的内容,答案是肯定的。

Yes, because a string is of dynamic size, so there must be heap memory behind the scenes 是的,因为字符串是动态大小的,所以在幕后必须有堆内存

However they are NOT the same. 然而它们并不相同。

in c the pointer points to a string that may also be used elsewhere, so changing it will effect those other places. 在c中,指针指向一个也可以在别处使用的字符串,因此更改它将影响其他地方。

据我所知,C#中的所有类(不确定其他类)都是引用类型。

Anything that is not a "value type", which essentially covers enums, booleans, and built-in numeric types, will be passed "by reference", which is arguably the same as the C/C++ mechanism of passing by reference or pointer. 任何不是“值类型”的东西,基本上涵盖枚举,布尔值和内置数值类型,都将通过“引用”传递,这可以说与通过引用或指针传递的C / C ++机制相同。 Syntactically and semantically it is essentially identical to C/C++ passing by reference. 在语法和语义上,它基本上与通过引用传递的C / C ++相同。

Note, however, that in C# strings are immutable, so even though it is passed by reference you can't edit the string without creating a new one. 但请注意,在C#字符串中是不可变的,因此即使它是通过引用传递的,也不能在不创建新字符串的情况下编辑字符串。

Also note that you can't pass an argument as "const" in C#, regardless whether it is a value type or a reference type. 另请注意,无论是值类型还是引用类型,都无法在C#中将参数作为“const”传递。

While those are indeed equivalent in a semantic sense (ie the code is doing something with a string), C#, like Java, keeps pointers completely out of its everyday use, relegating them to areas such as transitions to native OS functions - even then, there are framework classes which wrap those up nicely, such as SafeFileHandle. 虽然那些在语义上确实是等价的(即代码用字符串做某事),但是像Java一样,C#使指针完全脱离其日常使用,将它们降级到诸如转换为本机OS函数之类的区域 - 即便如此,有一些框架类可以很好地包装它们,比如SafeFileHandle。

Long story short, don't go out of your way thinking of pointers in C#. 长话短说,不要在C#中思考指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM