C указатели в C # - PullRequest
       85

C указатели в C #

4 голосов
/ 15 сентября 2008

Это объявление функции в C #:

void foo(string mystring)

так же, как этот в C:

void foo(char *)

т.е. В C # вызывает ли вызываемая функция указатель за кулисами?

Ответы [ 11 ]

11 голосов
/ 15 сентября 2008

В данном конкретном случае это больше похоже на:

void foo(const char *);

.Net строки являются неизменяемыми и передаются по ссылке. Однако в общем случае C # получает указатель или ссылку на объект за сценой.

4 голосов
/ 15 сентября 2008

Нет. В C # (и во всех других языках .NET) String - это тип данных первого класса. Это не просто массив символов. Вы можете конвертировать туда и обратно между ними, но они не ведут себя одинаково. Существует ряд методов манипулирования строками (например, «Substring ()» и «StartsWith»), которые доступны классу String, которые вообще не применяются к массивам, массив символов которых является просто экземпляром. 1001 *

4 голосов
/ 15 сентября 2008

За кулисами в C # есть указатели, хотя они больше похожи на умные указатели C ++, поэтому необработанные указатели инкапсулированы. Char * на самом деле не то же самое, что System.String, поскольку указатель на символ обычно означает начало массива символов, а строка C # - это объект с полем длины и массива символов. Указатель указывает на внешнюю структуру, которая указывает на что-то вроде массива wchar_t , поэтому имеется некоторая косвенность со строкой C # и более широкими символами для поддержки Unicode.

3 голосов
/ 15 сентября 2008

По сути, да. В C # строка (на самом деле System.String) является ссылочным типом, поэтому при вызове foo () она получает указатель на строку в куче.

2 голосов
/ 15 сентября 2008

Для типов значений (int, double и т. Д.) Функция получает копию значения. Для других объектов это ссылка, указывающая на исходный объект.

Строки являются особенными, потому что они неизменны. Технически это означает, что он пройдет ссылку, но на практике он будет вести себя почти как тип значения.

Вы можете заставить типы значений передавать ссылку, используя ключевое слово ref:

public void Foo(ref int value) { value = 12 }
public void Bar()
{
    int val = 3;
    Foo(ref val);
    // val == 12
}
0 голосов
/ 15 сентября 2008

Несмотря на то, что они действительно эквивалентны в семантическом смысле (т. Е. Код выполняет что-то со строкой), C #, как и Java, полностью исключает указатели из своего повседневного использования, откладывая их в такие области, как переходы к собственным функциям ОС - даже в этом случае существуют классы фреймворков, которые хорошо оборачивают их, такие как SafeFileHandle.

Короче говоря, не стесняйтесь думать об указателях в C #.

0 голосов
/ 15 сентября 2008

Все, что не является «типом значения», которое по существу охватывает перечисления, логические и встроенные числовые типы, будет передано «по ссылке», что, возможно, аналогично механизму передачи по ссылке в C / C ++ или указатель. Синтаксически и семантически он по существу идентичен C / C ++, передаваемому по ссылке.

Обратите внимание, однако, что в C # строки являются неизменяемыми, поэтому, даже если они передаются по ссылке, вы не можете редактировать строку без создания новой.

Также обратите внимание, что вы не можете передавать аргумент как "const" в C #, независимо от того, является ли он типом значения или ссылочным типом.

0 голосов
/ 15 сентября 2008

Насколько я знаю, все классы в C # (не уверен насчет других) являются ссылочными типами.

0 голосов
/ 15 сентября 2008

Да, потому что строка имеет динамический размер, поэтому за кулисами должна быть куча памяти

Однако они НЕ совпадают.

в c указатель указывает на строку, которая также может использоваться в другом месте, поэтому изменение этого параметра повлияет на другие места.

0 голосов
/ 15 сентября 2008

Если вы имеете в виду - разрешат ли методу доступ к содержимому символьного пространства, ответ - да.

...