Прежде всего, спасибо, что заявили, что вы пришли из Java. Это поможет нам много с точки зрения оказания вам помощи!
Теперь давайте проанализируем код
#include <iostream>
#include <string>
using namespace std;
В том числе некоторые заголовки, используя std
пространство имен (не рекомендуется, BTW), все в порядке здесь.
int x;
Вы объявляете переменную с именем x
типа int
в глобальном масштабе, с начальным значением, равным нулю (это относится только к объектам в глобальном масштабе!).
void test(int x) {
x += 3;
cout << x << endl;
}
Вы объявляете функцию test
, которая принимает параметр x
типа int
и возвращает void
(a.k.a: ничего). Функция увеличивает значение своей переменной intenral x
на 3, а затем печатает ее до стандартного вывода с помощью std::cout
. Чтобы быть понятным, как только вы объявите параметр int x
, он «скрывает» int x
в глобальной области видимости, поэтому, если вы хотите получить доступ к более поздней версии, вы должны использовать другой способ (см. Ниже).
int main() {
test(x);
cout << x << endl;
return 0;
}
Вы объявляете специальную main
функцию, не принимая никаких параметров и возвращение int
. Функция вызывает test
с глобальным аргументом int x
, а затем выводит значение глобального x
на стандартный вывод с помощью std::cout
и, наконец, return
с нулем, что указывает на успешное выполнение.
Теперь у вас есть большое заблуждение, которое можно отнести к дизайну однопарадигмы языка Java. В Java нет понятия «глобальных функций», даже не говоря о том, что «функций» вообще нет. У вас есть только «классы» с «методами».
В C++ это не тот случай. Язык C++ - это мульти-парадигма ; он позволяет выполнять императивное программирование, структурированное программирование, объектно-ориентированное программирование и даже функциональное программирование (вы не должны полностью понимать это последнее предложение)! Когда вы объявляете что-нибудь без указания области, оно, как говорят, лежит в глобальном scope. К глобальному охвату можно отнести что угодно, где угодно. В представленном примере нет связанных лиц!
В глобальном масштабе, что-то вроде void test(int)
является не метода, но функции. Нет класса, владеющего этой функцией; скажем, это «все»;). Функция - это всего лишь блок кода, который можно повторно использовать, предоставив ему аргументы, если функция имеет их вообще. В C++ вы используете классы для инкапсуляции данных и соответствующего кода в единый «упакованный» объект черного ящика, а не для, ну, ничего, как в Java.
Теперь, (это похоже на Java, но будьте осторожны!), Когда вы передаете «простой» объект, например, int
или что-то более напуганное и сложное, как std::
(вы не должны были это понимать .. .) к функции, эта функция получает копию этого объекта. int x
в test
- не то же, что и main
. Если вы назначаете его внутри test
, вы заметите, что main
«не видит разницы». В Java это тоже относится, но только к основным типам, например int
, но в C++ он предназначен для всех типов.
Если вы хотите изменить имеющуюся у вас переменную, просто используйте ссылки. Вы получаете ссылку любого типа T
, набрав T&
. Итак, если вы назначаете int& x
внутри теперь измененного test
, main
будет «видеть» все изменения.
Наконец, есть оператор ::
. Он используется для доступа к материалам в некоторых областях, а также в других областях. Он имеет форму namespace-or-class::stuff
. Так, например, std::cout
относится к идентификатору cout
в пространстве имен std
. Есть специальный случай: если левый операнд не указан, ::
обращается к глобальному охвату. Это полезно, когда вы «спрятали» что-то из глобальной области. Так, например, в test
вы можете сказать ::x
, и это будет относиться к x
в глобальной области!
void test(int x) {
// ...
::x += 123;
}
Edit: Если вам интересно, вы можете взглянуть на то, как классы в работе C++ с этим (я не буду объяснять это, потому что это не по теме) ...
#include <iostream>
int x = 0;
class MyClass {
private:
int x;
public:
MyClass() : x(0) {}
void test(int x) {
this->report(x);
std::cout << "Doing some magic...\n";
this->x += x;
this->report(x);
}
void report(int x) {
std::cout << "this->x = " << this->x << '\n';
std::cout << "x = " << x << '\n';
}
};
int main() {
MyClass c;
c.report();
x += 123;
c.test(x);
x += 456;
c.test(x);
c.report();
}
где «класс», о котором вы говорите? – Nandu
есть только функции и глобальная переменная. – Nandu
Возможно, вы захотите изучить параметры передачи по функциям по значению и по ссылке и увидеть разницу. Потому что я думаю, что это по сути то, что вам нужно. В этом примере нет класса. ;) – DeiDei