Глобальные и локальные переменные области действия (почему 2-я распечатка 28 здесь?) - PullRequest
0 голосов
/ 02 января 2019
#include <stdio.h>

int i = 3, j = 10;

int crypt(int j)
{
  return (i = i+j);
}

void decrypt(int x, int i)
{
  j += crypt(i);
}

int main(void)
{
  int i = 0;
  i = crypt(5);
  decrypt(i, j);
  printf("|%d %d|", i, j);
  return 0;
}

У меня проблемы с выяснением, почему он распечатывает | 8 28 |.

Часть "8", я понимаю, что на

i = crypt (5) -> j теперь 5 в этой функции -> i = i + j -> нет i, поэтому он использует глобальную переменную i = 3 -> i = 3 + 5 -> возвращает i = 8

Таким образом, i в главной функции становится 8.

А как насчет следующей распечатки? Почему 28 вместо 23?

То, как я это читал, было так

decrypt (i, j) -> decrypt (8, 10) -> x теперь 8 и i теперь 10 в этой функции -> j + = crypt (i) -> j + = crypt (10) - > j в этой функции теперь 10.

return (i = i + j), в этой функции нет i, поэтому i = 3 + 10 ... возвращает 13?

Так тогда j + = 13 - это 23?

Какую часть шага я испортил? Я читаю локальную / глобальную область онлайн и до сих пор не совсем понимаю, где я ошибся ... Такое ощущение, что я где-то испортил свою ценность.

PS: я извиняюсь за плохое форматирование, не совсем уверенный, как еще я могу выразиться аккуратно.

Ответы [ 4 ]

0 голосов
/ 02 января 2019

Рассмотрим следующую версию кода, где переменные были переименованы, чтобы избежать путаницы.

#include <stdio.h>

int iGlobal = 3, jGlobal = 10;

int crypt(int jParam)
{
  return (iGlobal = iGlobal+jParam);
}

void decrypt(int xUnused, int iParam)
{
  jGlobal += crypt(iParam);
}

int main(void)
{
  int iLocal = 0;
  iLocal = crypt(5);
  decrypt(iLocal, jGlobal);
  printf("|%d %d|", iLocal, jGlobal);
  return 0;
}

Теперь должно быть относительно легко объяснить, что происходит при выполнении кода:

  1. В main(), iLocal равно 0
  2. main звонки crypt(5)
  3. crypt оценивает iGlobal+jParam, то есть 3 + 5, и присваивает результат iGlobal, т.е. iGlobal равно 8
  4. crypt возвращает 8
  5. main присваивает возвращаемое значение от 8 до iLocal
  6. main звонки decrypt(8,10)
  7. decrypt звонки crypt(10)
  8. crypt оценивает iGlobal+jParam, то есть 8 + 10, и присваивает результат iGlobal, то есть iGlobal равен 18
  9. crypt возвращает 18
  10. decrypt добавляет возвращаемое значение 18 к jGlobal, то есть jGlobal равно 28
  11. printf печатает значения iLocal, 8 и jGlobal, 28

Сложная часть, если таковая имеется, - это знать, когда глобальные переменные заменяются (например, скрытыми или скрытыми) их локальными аналогами, причем ответом является «по возможности».

0 голосов
/ 02 января 2019

Здесь у вас есть глобальные i и j и локальный i var. В основном, когда вы ссылаетесь на i, он сначала проверяет вашу текущую область видимости - поэтому любые изменения там будут сделаны в вашем локальном i, а глобальный i не изменится. если вы попросите функцию вне main сделать что-то с i var, она сначала проверит собственную область видимости, а затем проверит глобальный i var. в этом случае изменения, которые будут сделаны, находятся в глобальном i.

Итак .. первый раз-

local i устанавливается в main и затем получает значение i = crypt (5); Другое дело, что в этой функции вы также присваиваете значение 8 глобальному i-> (i = i + j), прежде чем вернуть значение 8 локальному i.

вторая функция:

расшифровать (i, j); здесь вы отправляете локальный i (= 8) и глобальный j (= 10) функции, в ней у вас есть:

j + = crypt (i);
что дает вам j = j + ((глобально) i = 8 + 10): 10 + 8 + 10. а также установите свой глобальный i на 18.

0 голосов
/ 02 января 2019

Глобальные переменные объявляются вне любой функции и могут быть Доступ (используется) для любой функции в программе. Локальные переменные являются объявлен внутри функции и может использоваться только внутри этой функции. Можно иметь локальные переменные с одинаковыми именами в разных функции.

При первом вызове функции crypt (5); вы изменили значение глобальной переменной на

i = i + j ----> i = 3 + 5 ----> i = 8

И когда функция decrypt () вызывается, i = 8 Потому что я 8 j печатает 28 после добавления, которое является глобальной переменной.

Вы можете видеть, как выделяется память в C

0 голосов
/ 02 января 2019

Вы пишете:

return (i = i + j), в этой функции нет i, поэтому i = 3 + 10 ... возвращает 13?

Нет, i больше не 3. Ранее оно было изменено на 8, то есть здесь return (i = i+j); из-за первого вызова crypt

Когда вы пишете:

Таким образом, i в главной функции становится 8.

это правильно, но глобальный i также изменился.

...