Я перепробовал его здесь, чтобы улучшить ясность.
Определите эту структуру:
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
Добавьте в свой класс следующий метод extern
:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetSystemTime(ref SYSTEMTIME st);
Затем вызовите метод с экземпляром вашей структуры следующим образом:
SYSTEMTIME st = new SYSTEMTIME();
st.wYear = 2009; // must be short
st.wMonth = 1;
st.wDay = 1;
st.wHour = 0;
st.wMinute = 0;
st.wSecond = 0;
SetSystemTime(ref st); // invoke this method.
Хорошо помнить эти простые правила, и они применяются как к параметрам, так и к возвращаемым типам ...
Есть время и место для каждого, поэтому убедитесь, что вы узнаете их. Локальные переменные, как вы показали здесь, просто таковы, что они ограничены временем, когда они локально живы в области функций. В вашем примере с возвращаемым типом int*
и возвратом &i
было бы одинаково некорректно. Вам было бы лучше в этом случае сделать это ...
void func1(int& oValue)
{
oValue = 1;
}
Это приведет к прямому изменению значения вашего переданного параметра. В то время как этот код ...
void func1(int oValue)
{
oValue = 1;
}
не будет. Он просто изменит значение oValue
локально на вызов функции. Причина этого заключается в том, что вы фактически меняете только «локальную» копию oValue
, а не oValue
.
Локальная переменная - это память в стеке, эта память автоматически недействительна при выходе из области видимости. Из функции, более глубокой вложенной (выше в стеке в памяти), ее совершенно безопасно для доступа к этой памяти.
Как только функция возвращается и заканчивается, все становится опасным. Обычно память не удаляется или не перезаписывается, когда вы возвращаетесь, то есть память на этом адресе по-прежнему содержит ваши данные. Указатель кажется действительным.
Пока другая функция не построит стек и не перезапишет его. Вот почему это может сработать некоторое время - и затем внезапно перестает функционировать после того, как один особенно глубоко вложенный набор функций или функция с действительно огромными или многочисленными локальными объектами снова вернется к этой стеке.
Даже может случиться, что вы снова достигнете той же части программы и перезапишите свою старую локальную функциональную переменную с новой функциональной переменной. Все это очень опасно и должно быть сильно обескуражено. Не используйте указатели на локальные объекты!