Чем отличаются глобальные и локальные параметры в процедурах и функциях?
В программировании чаще говорят о глобальных и локальных переменных, а параметры функции обычно являются локальными именами внутри этой функции. Вопрос можно понимать так: чем отличаются данные, доступные всей программе, от данных, доступных только внутри подпрограммы.
Локальные параметры и переменные
Параметры функции существуют внутри вызова этой функции. Они доступны только в ее теле.
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 с.