Уведомления

Группа в Telegram: @pythonsu

#1 Май 4, 2017 15:58:31

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9746
Репутация: +  843  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

Да, неудобно. Не то, что после C, а просто непонятно, зачем так сделано

import std.stdio;

void main()
{
int[1][3] arr;

arr[0][0] = 1;
arr[1][0] = 2;
arr[2][0] = 3;

writeln(arr[0][0], arr[1][0], arr[2][0]);
}

Shaman
Поскольку тип пишется слева, запись означает
"4 массива типа int[3]".
Какая-то ерунда, заполняется-то оно всё равно прямо, зачем было делать это задом наперёд? Никаких причин для этого не вижу.



Офлайн

#2 Май 5, 2017 11:26:08

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

Чтобы не путаться наверно.

module main;

import std.stdio;

int[1][2][3] td;

int main()
{
writeln(typeof(td).stringof);
writeln(typeof(td[0]).stringof);
writeln(typeof(td[0][0]).stringof);
return 0;
}
Выдаёт
int[1][2][3]
int[1][2]
int[1]
Непривычно, но логично, если вдуматься.

Офлайн

#3 Май 5, 2017 12:16:17

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9746
Репутация: +  843  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

Shaman
Непривычно, но логично, если вдуматься.
Если ты так матрицу напишешь и что-нибудь там в ней повычисляешь, то в этом коде никто не разберётся. Все же привыкли к нормальному написанию, которое одинаковое во всех языках.



Отредактировано py.user.next (Май 5, 2017 12:16:32)

Офлайн

#4 Май 5, 2017 20:01:46

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

py.user.next
Если ты так матрицу напишешь и что-нибудь там в ней повычисляешь
Начало моей матрицы:
@trusted struct Matrix(Type, uint Dx=3, uint Dy=Dx)
if (isFloatingPoint!Type)
{
Type[Dx][Dy] data;

@nogc this(ref const Type[Dx][Dy] data_)
{
data = data_;
}

this(const Type[][] data_)
in
{
assert(data_.length == Dy);
foreach(ref row; data_)
assert(row.length == Dx);
}
body
{
for (uint y=0; y<Dy; ++y)
for (uint x=0; x<Dx; ++x)
data[y][x] = data_[y][x];
}

static if (Dy==1) {
@nogc this(ref const Type[Dx] data_)
{
for (uint i=0; i<Dx; ++i)
data[0][i] = data_[i];
}
}
Кажется тут всё должно быть понятным.

Офлайн

#5 Май 6, 2017 07:57:19

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

Shaman
Непривычно, но логично, если вдуматься.
Кроме привычек есть еще эргономичность.
Type[nroom][nbuild][nstret][nz] data;
....
data[iz][istret][ibuild][iroom]=1;
Я все проклял этот пример писать. Лично для меня уже этого одного достаточно чтобы от такого языка отказаться. Просто неудобно и проверять и писать программу.
Тогда логичнее сделать так
[nz][nstret][nbuild][nroom]Type data;

Кстати в С тоже логично что тип и модификаторы разделили там обычна конструкция:
some_useful_long_struct_type a, b, c, d[nd], gg[nd][nk];
Так что модификаторы к типу цеплять не всегда хорошая идея.



Отредактировано doza_and (Май 6, 2017 08:08:16)

Офлайн

#6 Май 6, 2017 09:32:29

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

doza_and
Я все проклял этот пример писать. Лично для меня уже этого одного достаточно чтобы от такого языка отказаться.
Да пожалуйста! ) Заодно от всего связанного с доменными именами можно отказаться.
doza_and
Кстати в С тоже логично что тип и модификаторы разделили там обычна конструкция
В C нет разницы между массивом и указателем, он съест
int *a, b[10];

void fa(int *arr) {}

void fb(int arr[]) {}

int main()
{
fa(a);
fb(a);
fa(b);
fb(b);
return 0;
}
и не подавится.
В более строго типизированных языках, знающих по полиморфизм, размер имеет значение.

Офлайн

#7 Май 6, 2017 09:55:25

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9746
Репутация: +  843  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

Shaman
В C нет разницы между массивом и указателем, он съест
и не подавится.
Если надо передать массив, пакуй его в структуру и передавай её. Но даже структуры, которые можно так передавать, никто не передаёт (жрётся время) и делают точно так же на указателях. Передача массива, как правило, происходит с передачей указателя на первый элемент и размера рядом. Сегодня писал функции преобразования эндианства переменных (для сохранения на носитель всего в big-endian на любой системе), так это просто сводится к передаче указателя на void и длины этой цепочки байт.

/* bytes_to_bigend: convert bytes to big-endian order
return converted bytes */
void *bytes_to_bigend(void *bytes, size_t size)
{
if (is_little_endian())
bytes_reverse(bytes, size);
return bytes;
}



Отредактировано py.user.next (Май 6, 2017 09:56:40)

Офлайн

#8 Май 6, 2017 10:38:46

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

py.user.next
Но даже структуры, которые можно так передавать, никто не передаёт (жрётся время) и делают точно так же на указателях. Передача массива, как правило, происходит с передачей указателя на первый элемент и размера рядом.
Про разницу в передаче по ссылке и по значению даже C++ знает. Указатели явно для этого применять не нужно.
module main;

import std.stdio;

void foo(uint D)(const ref int[D] arr) if (D > 5)
{
writeln("Red");
}

void foo(uint D)(const ref int[D] arr) if (D <= 5)
{
writeln("Blue");
}

int main()
{
int[3] a;
int[7] b;
int[5] c;
int[9] d;
foo(a);
foo(b);
foo(c);
foo(d);
return 0;
}
А динамические массивы в D - вообще отдельная песня.

Офлайн

#9 Май 6, 2017 14:19:55

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9746
Репутация: +  843  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

Shaman
Про разницу в передаче по ссылке и по значению даже C++ знает.
А зачем она нужна, эта передача по ссылке? Массив-то всё равно не будет передаваться целиком (копия не создаётся). Так что это просто лишняя хрень какая-то, которой в C++ дофига. Я вот в C++ вообще ею не пользуюсь, потому что она мне не нужна и ничего не даёт. Фактически там это указатель без звёздочки, но это только путаницу вносит. С указателями внутри функции понятно, что ты что-то меняешь, а со ссылками ты этого не можешь сказать - толи меняешь за пределами функции что-то, толи это локальные изменения. Да и указатель можно переставить: сначала на начало массива, потом на середину, а потом в конец, а потом вообще на другой массив. А ссылку ты создал и всё. Указатель я взял, поиграл с ним, переставил на другое место - и вот он уже обозначает что-то другое.

Shaman
void foo(uint D)(const ref int[D] arr) if (D > 5)
В Erlang'е есть гарды, но они там реально необходимы, потому что он рекурсивный (многое не проверишь на ходу, как в других языках). Может, пример здесь неудачный, но тут это можно одной функцией написать. А с другой стороны, если ты привыкнешь так писать, то как ты будешь писать всё то же самое, но на других языках, где этого нет?



Отредактировано py.user.next (Май 6, 2017 14:36:54)

Офлайн

#10 Май 6, 2017 15:09:30

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Прошу помощи. Супер сложное задание!

В C++ и в D использовать указатели никто не возбраняет.

py.user.next
а со ссылками ты этого не можешь сказать - толи меняешь за пределами функции что-то, толи это локальные изменения.
Если не const - меняет, иначе - нет.
py.user.next
Может, пример здесь неудачный, но тут это можно одной функцией написать.
Я так ниписал чтобы было более явно на что хочу обратить внимание. Специализация шаблона нужна не для проверок, а для упрощения решения прикладных задач.
Можно и
void foo(uint D)(in int[D] arr)
{
static if (D > 5) {
writeln("Red");
} else {
writeln("Blue");
}
}
В D статические массивы по умолчанию передаются по значению (но оптимизатор может выразить своё мнение).

Отредактировано Shaman (Май 6, 2017 15:25:59)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version