Скажем, у меня есть основная функция на C++ с объявленным вектором:
int main()
{
vector<int> arr (10, 5);
for (auto num : arr)
{
cout << num << endl;
}
}
Насколько я понимаю, переменная доступна в любом месте от того места, где она была определена, вплоть до закрывающей скобки среды, в которой она была определена. Итак, здесь arr доступен где угодно в main (), и, таким образом, он находится в области видимости цикл for.
Однако теперь скажем, что я определяю функцию и вызываю ее в main.
int main()
{
vector<int> arr (10, 5);
func();
}
void func()
{
arr.push_back(1);
}
Теперь arr не определен в func (). Я понимаю, почему это так, поскольку, строго говоря, массив нигде не определен в области действия функции func (). Я понимаю, что нам нужно передать arr в качестве параметра функции func (), чтобы это работало. Но это противоречит моему пониманию области видимости, определенной выше, где arr доступен где угодно в main, а поскольку func () вызывается в main, почему у него нет доступа к arr?
Дополнительно: я уже некоторое время занимаюсь разработкой на JS, поэтому я привык к этому шаблону вложенных функций:
function main() {
let a = 5;
function nested() {
console.info(a)
}
}
И здесь во вложенной функции доступен a.
Вы видите именно то, что есть прицел. arr известен в main и известен, когда вы вызываете func, но не в самом func. Вот почему вы должны передать его как аргумент функции func, как вы сами предложили.
В C++ есть похожая конструкция: auto nested = [&] { std::cout << a; };. Как видите, это не то же самое, что вызов функции, точно так же, как вложенные функции JS не совпадают с вызовами функций JS.
func не существует в main, поэтому не может видеть имена, определенные в main.
В Javascript, если вы вызываете функцию в main, переменные main также не будут доступны неявно в этой функции. Если вам нужна застежка, используйте ее.
Что касается вложенности, вы можете использовать глобальную переменную, которая достигнет того же самого, но не идите по этому пути, это плохая практика. javascript не является компилируемым языком и во всех отношениях отличается от C++. Не сравнивайте яблоки с грушами.
LOL есть много ответов на этот вопрос.
@CEPB LOL2 полные правила для неквалифицированного имени искать en.cppreference.com/w/cpp/language/unqualified_lookup
@RichardCritten спасибо за ссылку !!! Но этот вопрос: why I cannot access variable x, где x находится в основном, и они обращаются к нему в foo(), здесь настолько распространен, что это забавно !!!!





В C++ видимость переменной находится внутри {}, где она объявлена. Можно сделать глобальную переменную, но вам нужно объявить ее в верхней части файла. Если вы хотите написать функцию тела, вам нужно сначала сказать, что функция будет существовать.
void func();
vector<int> arr (10, 5);
int main()
{
func();
}
void func()
{
arr.push_back(1);
}
Редактировать:
Но это плохая практика, рекомендуется использовать ссылку.
void func(vector<int> &arr);
int main()
{
vector<int> arr (10, 5);
func(arr);
}
void func(vector<int> &arr)
{
arr.push_back(1);
}
Ош, только что узнал на днях, не делайте этого на C++, это плохая практика !!!! Прочтите это: rules.sonarsource.com/cpp/tag/pitfall/RSPEC-5421
@CEPB да, вы правы, но я думаю, что новичку легче сделать глобально и изучить основы, чем использовать указатели, возможно, с первого дня кода
+1, надеюсь, вы не против, что я отредактирую ваш ответ. Параметр указателя - foo (int *a), ссылка - foo (int &a). Основное различие между ними в том, что вы можете изменить адрес *a, а не &a.
arr. И фрагмент javascript не имеет значения, потому что он использует совершенно другую языковую функцию, вложенную функцию, а не вызываемую / вызываемую функцию.