манипулирование массивами по адресу - PullRequest
2 голосов
/ 15 января 2012

Помогите мне с этой частью кода:

class Ooo
 attr_accessor :class_array
end

def func(ctx)
 local_array = ctx.class_array
 local_array = [4,3,5,5,6]
 return
end

aaa = Ooo.new
func(aaa)
aaa.class_array => not [4,3,5,5,6] :-(

Я предположил, что ruby ​​использует адреса, когда работает с массивами ... Почему этот код не работает?Я хочу сделать это (в C):

struct ctx
{
uint class_array[10000]
}

void func(struct *ctx)
{
 uint* local_array = &ctx->class_array
 local_array[0] = 4;
 ctx->class_array[0] => 4
}

Ответы [ 4 ]

1 голос
/ 15 января 2012

В вашем случае экземпляр ctx содержит ссылку на объект массива в переменной экземпляра @class_array.В методе func новая ссылка на этот же объект создается и присваивается локальной переменной local_array.

Когда вы присваиваете [4,3,5,5,6] для local_array, вы не перезаписываете объект, на который ссылаетсяна ctx вы перезаписываете ссылку, хранящуюся в local_array, делая ее ссылкой на новый массив.

С точки зрения указателей то, что вы делаете, аналогично этому:

int array[]     = { 1, 2, 3, 4, 5 };
int new_array[] = { 4, 3, 5, 5, 6 };

int * ctx_array   = array;
int * local_array = ctx_array;

local_array = new_array; // ctx_array still points to array[0]

Я думаю, что вы хотите достичь, это:

int ** local_array = &ctx_array;
*local_array = new_array; // ctx_array now points to the new array

Этот тип косвенного обращения невозможен в Ruby.Вы можете изменить объект, только вызвав методы для него.

Однако перевод вашего C-фрагмента в Ruby дает полностью функциональный код:

def func(ctx)
  local_array = ctx.class_array
  local_array[0] = 4
end

ctx.class_array[0]
 => 4

Это работает, потому что local_array ссылается на то же самоеобъект как ctx.class_array.

1 голос
/ 15 января 2012

Проблема с этой частью кода:

local_array = ctx.class_array
local_array = [4,3,5,5,6]

Это не делает то, что вы думаете, что делает.Вторая строка создает новый список и присваивает его локальной переменной, заменяя ссылку на ctx.class_array.Это будет не касаться ctx.class_array.Эквивалентный фрагмент кода C будет работать точно так же, поэтому я думаю, что у вас проблема не только с Ruby.

В C вы можете использовать указатели для решения этой проблемы.В Ruby вы, вероятно, захотите:

local_array = ctx.class_array
local_array.replace [4,3,5,5,6]

или просто (намного лучше!)

ctx.class_array = [4,3,5,5,6]

Кстати, прямой перевод вашей C-программы также будет работать:

def func(ctx)
  local_array = ctx.class_array
  local_array[4] = 4
end
0 голосов
/ 15 января 2012

это можно сделать, просто изменив порядок:

def func(ctx)
 local_array = [4,3,5,5,6]
 ctx.class_array = local_array
 return
end
0 голосов
/ 15 января 2012

Почему бы вам не пропустить первую строку вашей функции и просто напрямую назначить так:

def func(ctx)
   ctx.class_array = [1, 2, 3, 4]
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...