проблема присвоения массивов

Почему C ++ не использует ., где он использует ::, потому что именно так определяется язык. Одна из правдоподобных причин - ссылаться на глобальное пространство имен, используя синтаксис ::a, как показано ниже:

int a = 10;
namespace M
{
    int a = 20;
    namespace N
    {
           int a = 30;
           void f()
           {
              int x = a; //a refers to the name inside N, same as M::N::a
              int y = M::a; //M::a refers to the name inside M
              int z = ::a; //::a refers to the name in the global namespace

              std::cout<< x <<","<< y <<","<< z <

Онлайн-демонстрация

Не знаю, как Java решает это. Я даже не знаю, есть ли в Java глобальное пространство имен. В C # вы ссылаетесь на глобальное имя, используя синтаксис global::a, что означает, что даже C # имеет оператор ::.


, но я не могу представить ни одной ситуации, в которой синтаксис

Кто сказал, что синтаксис, подобный a.b::c, не является законным?

Рассмотрим эти классы:

struct A
{
    void f() { std::cout << "A::f()" << std::endl; }
};

struct B : A
{
    void f(int) { std::cout << "B::f(int)" << std::endl; }
};

Теперь см. Это ( ideone ):

B b;
b.f(10); //ok
b.f();   //error - as the function is hidden

b.f() не может быть вызвано так, как функция скрыта, а GCC дает это сообщение об ошибке:

error: no matching function for call to ‘B::f()’

Для вызова b.f() (или, скорее, A::f()) вам нужен оператор разрешения области видимости:

b.A::f(); //ok - explicitly selecting the hidden function using scope resolution

Демо на идеоне

30
задан Sujan 17 June 2010 в 06:33
поделиться

1 ответ

На самом деле это не проблема; так работают массивы (и другие объекты) в Python.

Подумайте об этом так: массив, который вы создали в своем примере кода, - это объект, который находится в некотором месте в памяти. Но вы не можете использовать его в своей программе, указав Python, где его искать; вы должны дать ему имя. Когда вы пишете

a = np.array([[1,2],[3,4]])

, вы одновременно создаете массив и создаете имя a , которое ссылается на него. С этого момента Python знает, что a относится к «адресу памяти 0x123674283» (или какому-то другому). В среде выполнения Python есть внутренняя таблица (называемая «таблицей символов», если я правильно помню), которая содержит всю эту информацию, поэтому после выполнения указанной выше строки кода Python эта таблица будет содержать

...,
'a' : 0x123674283,
...

. переменную в другую, например

b = a

Python не копирует весь массив, потому что, если бы это был большой массив, это заняло бы много времени. Вместо этого он переходит в таблицу символов и копирует адрес памяти для a в новую строку в таблице для b . Итак, вы получаете

...,
'a' : 0x123674283,
...,
'b' : 0x123674283,
...

Итак, вы видите, a и b на самом деле относятся к одному и тому же месту в памяти, то есть к одному и тому же объекту. Любые изменения, внесенные вами в один, будут отражены в другом, поскольку это всего лишь два названия одного и того же объекта.

Если вы действительно хотите сделать копию массива, вы должны вызвать метод, чтобы сделать это явно.Массивы Numpy имеют метод copy , который вы можете использовать только для этой цели. Итак, если вы напишете

b = a.copy()

, тогда Python сначала фактически сделает копию массива, то есть выделит новую область памяти, скажем, по адресу 0x123904381, затем перейдет к адресу памяти 0x123674283 и скопирует все значения массив из последнего раздела памяти в первый. Таким образом, один и тот же контент находится в двух разных местах памяти.

...,
'a' : 0x123674283,
...,
'b' : 0x123904381,
...

Теперь, когда вы меняете один из элементов b , это изменение не будет отображаться в a , поскольку a и b больше не относятся к одному и тому же разделу памяти компьютера. Поскольку существует две независимые копии данных массива, вы можете изменить одну, не затрагивая другую.

64
ответ дан 27 November 2019 в 21:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: