Верно ли, что указатели в Си аналогичны ссылочным типам в C#?
Хотел было докоментировать ответ andreycha, но потом подумал что лучше запостить отдельный ответ.
Начнем с того что понятием указателя(pointer) в С/С++ является адрес обьекта в оперативной памяти и представляет собой следующий синтаксис:
int x;
int *y = &x; // От любой переменной можно взять адрес при помощи операции взятия адреса "&". Эта операция возвращает указатель
int z = *y; // Указатель можно разыменовать при помощи операции разыменовывания "*". Это операция возвращает тот объект, на который указывает указатель
то есть перед названием стоит звездочка.
Так же есть ссылка (reference)
int x;
int &y = x;
int z = y;
Ссылки — это +- то же самое, что и указатели, но с другим синтаксисом и некоторыми другими важными отличиями. Они там работают вместе и дополняют друг друга: через указатель можно узнать значение по ссылке в С/С++.
В C# есть так же указатели и ссылки. Синтаксис указателя это такая же звездочка и применяется точно так же как и в Си/Си++ (это считается небезопасным кодом и нужно в настройках проэкта поставить галочку "Allow unsafe code" и использовать модификатор метода unsafe). И так же возможна неявная передача ссылки с использованием ключевого слова ref
, вместо &. Хотя ref в целом используется несколько по-другому в шарпе, чем & в С++ и в реализации, соответственно, отличается.
пример использования ref
в шарпе:
public void SomeMethod(ref int a)
{
a = 5;
//здесь а==5 как внутри метода так и извне
}
var a =1;
SomeMethod(ref a);
Я бы не сказал бы, что указатели/ссылки в Си являются аналогом ссылочного типа в C#. Появление понятия ссылочных типов -- это просто следствие выбранной реализации, но не аналог. Прямыми аналогами же являются лишь перечисленные выше способы задвать указатели/референсы.
А бездумное использование ссылочных типов напрямую как аналог -- это плохая практика. Например, если ты знаешь что в методе будет изменятся переданный параметр List<T> someList
-- тебе нужно обязательно дописать ref List<T> someList
, даже, не смотря на то, что это и так ссылочный тип и передавать ссылку на ссылочный тип, вроде как, безсмысленно. Но это имеет смысл, ведь ты можешь нечаянно обмануть другого программиста или же самого себя в будущем.
А во всем остальном я согласен с ответом andreycha и дополнением VladDа. То есть:
Концептуально -- да. Они решают задачу указания на объект. Но есть различия в реализации.
Указатели содержат адрес. Ссылки -- это, по сути, абстракция, которая ничего не говорит о своем значении (хотя по факту, CLR в них тоже помещает адрес).
Cсылка в C# всегда ссылается на валидный объект или равна null
, указатель же может указывать в случайную область памяти. (спасибо за комментарий @VladD)
Кроме того, указатели С "статичны", а объект в дотнете может быть перемещен сборщиком мусора, т.е. ссылки изменяют свое значение.
Из этого факта вытекает еще одно отличие: в случае с указателями возможно безопасно делать арифметику (например, обращаться к i-му элементу массива, имея указатель на массив и зная размер элемента), в случае со ссылками -- нет.
В C# также существуют указатели. Они эквивалентны указателям в С.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Всем доброго времени сутокВопрос заключается в том что в одной из n-страниц есть кнопки с названием цвет, и мне необходимо что бы при нажатии...
Доброго времени суток, понадобилось мне загрузить аудио в вк, нашел апи https://vkcom/dev/audio