Есть несколько вещей, которые не соответствуют этому коду.
[indent=4]
init
var carray = repeatc ('A', 3)
for i in carray do stdout.printf ("%c, ", i)
// A, A, A
Фактически, он печатает «A, A, A» (обратите внимание на конечную запятую и пробел). Есть много способов исправить это, самым простым было бы сделать что-то вроде stdout.puts (string.joinv (", ", sarray))
.
def repeatc (e: char, n: int): array of char
var a = new array of char[n]
Memory.copy (a, &e, sizeof (char))
Используя Memory.copy (а.к.а. тетсру в C), чтобы скопировать один байт является больше, чем немного глупо. Нет абсолютно никакой причины не просто делать здесь a[0] = e
. Это проще и будет работать лучше.
Memory.copy (&a[1], a, sizeof (char) * (n - 1)) // gcc
Это очень неправильно. Вы сообщаете ему скопировать sizeof (char) * (n - 1)
байт из местоположения a
в 1 байт после a
. Это очень отличается от того, что вы намерены намереваться, чтобы заполнить остальную часть a значением первого байта в массиве. В действительности вы не должны использовать Memory.copy
, вы должны использовать Memory.set
: Memory.set (a, e, n)
может заменить оба эти Memory.copy
строк.
Это, скорее всего, то, что вы действительно хотите, это строка, а не массив символов. Если это так, вы можете заменить эту целую функцию и просто позвонить string.nfill (3, 'A')
.
def repeats (e: string, n: int): array of string
var a = new array of string[n]
// WORKS: for var i = 0 to (n - 1) do a[i] = e
// Memory.copy HOW TO?
Вам по-прежнему нужен цикл. После того, как вы начнете пытаться использовать функции Memory.*
, вы работаете с указателями, поэтому вам нужно понять, как выкладывается память. Строки - это действительно массивы символов, а массивы - только указатели на первый элемент массива. Когда вы создаете массив строк, то, что у вас есть, является указателем на указатель (в C, gchar**
), а не на указатель на большой смежный блок, в который вы можете начать копировать свои данные символов.
Я думаю, вы пытаетесь использовать Memory.copy
вместо цикла и простого назначения для повышения производительности; единственное, что действительно плохо для производительности здесь, состоит в том, что простое назначение вызовет g_strdup
, которое вызовет strlen
, так что вы закончите сканирование своей строки ввода N раз, чтобы вычислить длину вместо одного раза. Лучшее, что вы собираетесь получить, вероятно, что-то вроде:
var elen = e.length
for var i = 0 to (n - 1)
a[i] = (string) Memory.dup (e, (uint) elen);
Если вы действительно заботитесь о производительности, что вы хотели бы сделать, это возвращает массив строк, не имеющих владельца указывают на то же место в памяти.Или, если вас интересует действительно объединенная строка, а не массив, просто сделайте что-нибудь вроде
def repeatwithsep (e: string, n: int, separator: string): string
var elen = e.length;
var slen = separator.length;
var a = new StringBuilder.sized ((elen * n) + (slen * (n - 1)) + 1);
for var i = 0 to (n - 1)
if i != 0
a.append_len (separator, slen)
a.append_len (e, elen)
return (owned) a.str;
Привет, меня очень интересует ваш код. прочитайте их и принесите мне больше вопросов. 1: вы можете показать код: ** вернуть массив неизмененных строк, которые все указывают на одно и то же местоположение ** 2: почему вы добавляете ** (принадлежит) ** в конце ** repeatwithsep * * функция? ** var a ** - локальная переменная, когда она оставлена этой функцией, она будет уничтожена? –
Это действительно должно быть совершенно новые вопросы, каждый вопрос о стековом потоке должен быть как можно более атомарным, чтобы сделать его многоразовым для будущих ссылок. –
yor являются правильными. Я отправляю 2 новых вопроса –