0
arr=Array.new(3)
arr[0]=5
arr[1]=3
arr[2]=2

这些行应该调用这个函数,https://github.com/ruby/ruby/blob/trunk/array.c#L568根据这个,http://www.ruby-doc.org/core-1.9.3/数组.html

所以我在那里添加了几行来显示数组的值。但我没有得到预期的结果。

else {
    memfill(RARRAY_PTR(ary), len, val);
    ARY_SET_LEN(ary, len);
    int i;
    int result;
    result = 0;
    VALUE *s_arr = RARRAY_PTR(ary);
    for(i = 0; i < len; i++) {
        result = LONG2NUM(s_arr[i]);
        printf("r: %d\n",result);
    }
}

我得到这样的结果:

arr=Array.new(3)
arr[0]=5
arr[1]=3
arr[2]=2
r: 9
r: 9
r: 9

为什么是这个结果?为什么是9?

我已经按照这些来解决它:

任何人都可以帮助在 C 中显示/打印 Ruby 数组的值吗?

4

1 回答 1

0

这没有任何意义:

result = LONG2NUM(s_arr[i]);

LONG2NUM用于将 C 转换为包含数字long int的 Ruby ;已经是 a所以你正在有效地做类似的事情。被定义为一个包装器:VALUEs_arr[i]VALUEVALUE v = LONG2NUM((VALUE)5)LONG2NUMruby.h

#define LONG2NUM_internal(v) (FIXABLE(v) ? LONG2FIX(v) : rb_int2big(v))

如果v适合 aVALUE而没有将其转换为 bignum,那么您最终会使用它:

#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG))

因此,您基本上是在对指针进行一些争论,并想知道为什么它总是说9; 认为自己很幸运(或不幸)它没有说分段错误

您想将VALUE保存数字的 a 转换为 C 整数。您可能想使用FIX2LONG

#define FIX2LONG(x) (long)RSHIFT((SIGNED_VALUE)(x),1)

NUM2LONG

#define NUM2LONG_internal(x) ((long)(FIXNUM_P(x) ? FIX2LONG(x) : rb_num2long(x)))
#ifdef __GNUC__
#define NUM2LONG(x) \
    __extension__ ({VALUE num2long_x = (x); NUM2LONG_internal(num2long_x);})
#else
static inline long
NUM2LONG(VALUE x)
{
    return NUM2LONG_internal(x);
}
#endif

所以是这样的:

long result;
for(i = 0; i < len; i++) {
    result = NUM2LONG(s_arr[i]);
    printf("r: %ld\n", result);
}

请注意切换到,%ld因为我们现在使用longs 并且我们总是打开所有抱怨printf格式和参数不匹配的挑剔编译器标志。当然,这假设您确定数组包含适合 C 的数字long

于 2012-06-22T22:28:40.637 回答