Чем отличаются глобальные и локальные параметры в процедурах и функциях?

В программировании чаще говорят о глобальных и локальных переменных, а параметры функции обычно являются локальными именами внутри этой функции. Вопрос можно понимать так: чем отличаются данные, доступные всей программе, от данных, доступных только внутри подпрограммы.

Локальные параметры и переменные

Параметры функции существуют внутри вызова этой функции. Они доступны только в ее теле.

function square(x) {
  return x * x;
}
function square(x: number): number {
  return x * x;
}
func square(x int) int {
  return x * x
}
public class Example {
  static int square(int x) {
    return x * x;
  }
}
def square(x):
  return x * x

Здесь x — параметр. Он существует только внутри square.

Локальные переменные также создаются внутри функции.

function sum(a, b) {
  const result = a + b;

  return result;
}
function sum(a: number, b: number): number {
  const result = a + b;

  return result;
}
func sum(a int, b int) int {
  result := a + b

  return result
}
public class Example {
  static int sum(int a, int b) {
    int result = a + b;

    return result;
  }
}
def sum(a, b):
  result = a + b

  return result

Переменная result недоступна снаружи функции.

Глобальные переменные

Глобальная переменная объявлена вне функций и доступна многим частям программы.

let counter = 0;

function increment() {
  counter++;
}
let counter = 0;

function increment(): void {
  counter++;
}
var counter = 0

func increment() {
  counter++
}
public class Example {
  static int counter = 0;

  static void increment() {
    counter++;
  }
}
counter = 0

def increment():
  counter += 1

Функция increment меняет внешнее состояние.

Разница по области видимости

Область видимости определяет, где имя доступно.

Локальные параметры и переменные доступны только внутри функции или блока.

Глобальные переменные доступны шире: в модуле, файле или во всей программе, в зависимости от языка.

Разница по времени жизни

Локальные параметры обычно создаются при вызове функции и исчезают после завершения вызова.

Глобальная переменная живет дольше: часто все время работы программы или модуля.

Преимущества локальных данных

Локальные параметры и переменные:

Риски глобальных данных

Глобальные переменные могут усложнять программу.

Проблемы:

Передача параметров

Правильнее передавать нужные значения через параметры, а результат возвращать явно.

Менее удачный вариант:

let total = 0;

function addToTotal(value) {
  total += value;
}
let total = 0;

function addToTotal(value: number): void {
  total += value;
}
var total = 0

func addToTotal(value int) {
  total += value
}
public class Example {
  static int total = 0;

  static void addToTotal(int value) {
    total += value;
  }
}
total = 0

def add_to_total(value):
  total += value

Более прозрачный вариант:

function add(total, value) {
  return total + value;
}
function add(total: number, value: number): number {
  return total + value;
}
func add(total int, value int) int {
  return total + value
}
public class Example {
  static int add(int total, int value) {
    return total + value;
  }
}
def add(total, value):
  return total + value

Когда глобальные данные допустимы

Глобальные или общие данные могут быть оправданы для:

Но доступ к ним лучше контролировать.

Пример локального и внешнего состояния

Первый вариант меняет внешнее состояние, второй явно получает данные через параметры.

let counter = 0;

function increment() {
  counter++;
}

function add(total, value) {
  return total + value;
}
let counter = 0;

function increment(): void {
  counter++;
}

function add(total: number, value: number): number {
  return total + value;
}
var counter = 0

func increment() {
  counter++
}

func add(total int, value int) int {
  return total + value
}
public class Example {
  static int counter = 0;

  static void increment() {
    counter++;
  }

  static int add(int total, int value) {
    return total + value;
  }
}
counter = 0

def increment():
  counter += 1

def add(total, value):
  return total + value

Вывод

локальные параметры и переменные принадлежат конкретной функции и делают код предсказуемым. Глобальные данные доступны шире, но повышают связность и риск ошибок, поэтому их следует использовать осторожно.

Источники

  • Семакин И.Г. Основы программирования и баз данных. Учебник. - М.: Академия, 2014. - 224 с.
  • Симонова Е.В. Структуры данных в C#. Линейные и нелинейные динамические структуры. - Лань, 2018. - 152 с.
  • Бертран Мейер. Почувствуй класс. Учимся программировать хорошо с объектами и контрактами. - М.: Национальный Открытый Университет "ИНТУИТ": БИНОМ. Лаборатория знаний, 2011. - 775 с.
  • Мэтт Вайсфельд. Объектно-ориентированное мышление. - СПб.: Питер, 2014. - 304 с.
  • Ривест Р., Штайн К., Лейзерсон Ч., Кормен Т. Алгоритмы: построение и анализ. - М.: Вильямс, 2007. - 1296 с.
  • Стивенс Род. Алгоритмы. Теория и практическое применение. - М.: Эксмо, 2017. - 544 с.
  • Рублев В.С. Основы теории алгоритмов. - 2-е издание, исправленное. - М.: Научный мир, 2008. - 128 с.
  • Гольдберг Г.Л. Основы алгоритмизации и программирования. - М.: Академия, 2012. - 384 с.
  • Лаврищева И.В. Технология программирования. - М.: Горячая линия - Телеком, 2011. - 400 с.
  • Сергеев И.С., Сухоруков А.И., Шестаков А.А. Программирование: учебник для вузов. - М.: БИНОМ. Лаборатория знаний, 2013. - 512 с.