Размер указателя и передача по ссылке против передачи по указателю

У меня есть два вопроса:

  1. Прав ли я, что в 4-битных системах указатель составляет 4 байта?

  2. "Передача по ссылке" и "Передача по указателю" - это одно и то же, просто разные формулировки?

3 ответа

Я прав, что в 4-битной системе размер указателя равен 4

Если ваша система имеет 1-битные байты, то это точно. (Но C не поддерживает платформы, где байты короче, чем 8 бит).

"Передача по ссылке" и "Передача по указателю" - это одно и то же, но разные формулировки?

Нет. Pass-by-pointer - это подход C для эмуляции передачи по ссылке. Концепция отличается.

Размер указателя не обязательно соотносится с собственным размером слова ЦП; Например, оригинальный Macintosh работал на 32-битном процессоре (Motorola 68000), который имел только 24 адресных строки, поэтому указатели были ограничены 24 битами. Значение указателя было сохранено в 32-битном слове, но верхние 8 бит не использовались. Некоторые предприимчивые программисты использовали эти старшие 8 бит для хранения других данных с указателем. Это вызвало некоторую изжогу, когда вышел 68020 с 32 адресными строками. Потребовалось некоторое время, чтобы переписать этот код, чтобы он стал "32-битным чистым".

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

На практике в любой современной настольной системе (читай: x86) все типы указателей будут иметь ширину 32 или 64 бита. Но не надейтесь, что это верно для всех архитектур.

Что касается передачи "передача по ссылке" и "передача по указателю", то нет, это не просто разные формулировки одного и того же понятия.

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

C234567890
      PROGRAM CALLSW
      INTEGER M, N

      M = 1
      N = 2

      WRITE(*,*) M, N
      CALL ISWAP(M, N)
      WRITE(*,*) M, N

      STOP
      END

C234567890
      SUBROUTINE ISWAP(A, B)
      INTEGER A, B
      INTEGER TMP

      TMP = A
      A = B
      B = TMP

      RETURN
      END

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

С передает все по значению; формальный параметр и фактический параметр всегда обозначают разные объекты в памяти, поэтому запись в один не влияет на другой. Когда мы хотим изменить объект в подпрограмме, мы должны явно передать его адрес, используя & оператор, а затем разыменовываете его в подпрограмме с * оператор:

void iswap(int *a, int *b)
{
  int tmp;

  tmp = *a;
  *a = *b;
  *b = tmp;
}

int main(void)
{
  int m, n;

  m = 1;
  n = 2;

  printf("m = %d, n = %d\n", m, n);
  iswap(&x, &y);
  printf("m = %d, n = %d\n", m, n);

  return 0;
}

Вместо прохождения m а также n в iswapПередаем результаты выражений &m а также &n, которые являются указателями на два объекта. Точно так же в iswap функция, мы не пишем a или же bмы пишем результаты выражений *a а также *b, a а также m ссылаются на два совершенно разных объекта в памяти, а также b а также n, Запись в a не повлияет m совсем.

Что касается передачи параметров в C, запись Википедии о C гласит:

Параметры функции всегда передаются по значению. Передача по ссылке моделируется в C путем явной передачи значений указателя.

Другие вопросы по тегам