Главная Обратная связь

Дисциплины:

Архитектура (936)
Биология (6393)
География (744)
История (25)
Компьютеры (1497)
Кулинария (2184)
Культура (3938)
Литература (5778)
Математика (5918)
Медицина (9278)
Механика (2776)
Образование (13883)
Политика (26404)
Правоведение (321)
Психология (56518)
Религия (1833)
Социология (23400)
Спорт (2350)
Строительство (17942)
Технология (5741)
Транспорт (14634)
Физика (1043)
Философия (440)
Финансы (17336)
Химия (4931)
Экология (6055)
Экономика (9200)
Электроника (7621)






Передача параметра по ссылке



Передача параметра по ссылке означает что копируется не само значение, а адрес исходной переменной (как в случае передачи параметра по адресу), однако синтаксис используется такой, чтобы программисту не приходилось использовать операцию разыменования и он мог иметь дело непосредственно со значением, хранящимся по этому адресу (как в случае передачи параметра по значению).

Передача по ссылке позволяет избежать копирования всей информации, описывающей состояние объекта (а это может быть существенно больше чем sizeof(int)) и является необходимой для конструктора копирования.

Если функция возвращает значение по ссылке (например в виде "return *this;"), то её вызов можно использовать слева от оператора присваивания (смотри также L-выражение).

В случае если передача по ссылке используется именно как средство увеличения быстродействия, но изменение параметра нежелательно, можно использовать передачу по ссылке константного объекта.

Таким образом можно ожидать, что примерная программа напечатает (если закоментировать ошибочную строку) "0010 022 233 333".

Некоторые языки (или их диалекты) не поддерживают передачу по ссылке, некоторые наоборот - передают параметры исключительно по ссылке, что порождает риск непреднамеренного изменения контекста вызывающей функции.

Объявление вида:<Type> & <Name>, где <Type> — тип и <Name> — идентификатор, указывают идентификатор, чьим типом является ссылка на <Type>.

Примеры:

int A = 5; int& rA = A;

extern int& rB; int& foo ();

void bar (int& rP);

class MyClass { int& m_b; /* ... */ };

int funcX() { return 42 ; }; int (&xFunc)() = funcX;

Здесь, rA и rB являются типами «ссылок на int», foo() — функция, возвращающая ссылку на int, bar() — функция с ссылкой в качестве параметра, которая ссылается на int, MyClass — класс (class) с членом, ссылающимся на int, funcX() — функция, возвращающая int, xFunc() — псевдоним для funcX.Типы, относящиеся к «ссылка на <Type>», иногда называются ссылочными типами. Идентификаторы ссылочного типа называются ссылочными переменными. Вызывать их переменную фактически будет неправильно (показано дальше).

 

  1. Передача структур в функции. Создание массива структур.

В следующем примере показано определение структур Point и Rect в управляемом коде и передача типов в качестве параметра функции PtInRect в файле библиотеки User32.dll. Для функции PtInRect используется следующая неуправляемая сигнатура:



BOOL PtInRect(const RECT *lprc, POINT pt);

Обратите внимание, что структуру Rect следует передавать по ссылке, так как функция должна получить указатель на тип RECT.

using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)]public struct Point { public int x; public int y;} [StructLayout(LayoutKind.Explicit)]public struct Rect { [FieldOffset(0)] public int left; [FieldOffset(4)] public int top; [FieldOffset(8)] public int right; [FieldOffset(12)] public int bottom;} class Win32API { [DllImport("User32.dll")] public static extern bool PtInRect(ref Rect r, Point p);}

Если для класса используется фиксированное размещение членов, их можно передавать в неуправляемую функцию DLL,. В следующем примере демонстрируется передача последовательно упорядоченных в определении членов класса MySystemTime в функцию GetSystemTime в файле User32.dll.Для функции GetSystemTime используется следующая неуправляемая сигнатура:

void GetSystemTime(SYSTEMTIME* SystemTime);

В отличие от типов значений для классов всегда используется, по крайней мере, один уровень косвенного обращения.

[StructLayout(LayoutKind.Sequential)]public class MySystemTime { public ushort wYear; public ushort wMonth; public ushort wDayOfWeek; public ushort wDay; public ushort wHour; public ushort wMinute; public ushort wSecond; public ushort wMilliseconds; }class Win32API { [DllImport("Kernel32.dll")] public static extern void GetSystemTime(MySystemTime st); [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int MessageBox(IntPtr hWnd, string text, string caption, int options);} public class TestPlatformInvoke{ public static void Main() { MySystemTime sysTime = new MySystemTime(); Win32API.GetSystemTime(sysTime); string dt; dt = "System time is: \n" + "Year: " + sysTime.wYear + "\n" + "Month: " + sysTime.wMonth + "\n" + "DayOfWeek: " + sysTime.wDayOfWeek + "\n" + "Day: " + sysTime.wDay; Win32API.MessageBox(IntPtr.Zero, dt, "Platform Invoke Sample", 0); }}

У объекта ArrayList есть метод Add, позволяющий добавлять в него элементы.



Динамический массив

ArrayList spisok = new ArrayList();
elem myElem = new elem();
myElem.isn = 2387683;
myElem.type = "someType";
myElem.name = "someName";
spisok.Add(myElem);

Фиксированной длины

elem [] elemArray = new elem[5]; //например, возьмем длину массива = 5
elem myElem = new elem();
myElem.isn = 2387683;
myElem.type = "someType";
myElem.name = "someName";
elemArray[0] = myElem;

 

 


Эта страница нарушает авторские права

allrefrs.ru - 2019 год. Все права принадлежат их авторам!