Форум сайта python.su
Да, неудобно. Не то, что после 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]".
Офлайн
Чтобы не путаться наверно.
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]
Офлайн
ShamanЕсли ты так матрицу напишешь и что-нибудь там в ней повычисляешь, то в этом коде никто не разберётся. Все же привыкли к нормальному написанию, которое одинаковое во всех языках.
Непривычно, но логично, если вдуматься.
Отредактировано py.user.next (Май 5, 2017 12:16:32)
Офлайн
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];
}
}
Офлайн
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)
Офлайн
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;
}
Офлайн
ShamanЕсли надо передать массив, пакуй его в структуру и передавай её. Но даже структуры, которые можно так передавать, никто не передаёт (жрётся время) и делают точно так же на указателях. Передача массива, как правило, происходит с передачей указателя на первый элемент и размера рядом. Сегодня писал функции преобразования эндианства переменных (для сохранения на носитель всего в big-endian на любой системе), так это просто сводится к передаче указателя на void и длины этой цепочки байт.
В C нет разницы между массивом и указателем, он съест
и не подавится.
/* 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)
Офлайн
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;
}
Офлайн
ShamanА зачем она нужна, эта передача по ссылке? Массив-то всё равно не будет передаваться целиком (копия не создаётся). Так что это просто лишняя хрень какая-то, которой в C++ дофига. Я вот в C++ вообще ею не пользуюсь, потому что она мне не нужна и ничего не даёт. Фактически там это указатель без звёздочки, но это только путаницу вносит. С указателями внутри функции понятно, что ты что-то меняешь, а со ссылками ты этого не можешь сказать - толи меняешь за пределами функции что-то, толи это локальные изменения. Да и указатель можно переставить: сначала на начало массива, потом на середину, а потом в конец, а потом вообще на другой массив. А ссылку ты создал и всё. Указатель я взял, поиграл с ним, переставил на другое место - и вот он уже обозначает что-то другое.
Про разницу в передаче по ссылке и по значению даже C++ знает.
ShamanВ Erlang'е есть гарды, но они там реально необходимы, потому что он рекурсивный (многое не проверишь на ходу, как в других языках). Может, пример здесь неудачный, но тут это можно одной функцией написать. А с другой стороны, если ты привыкнешь так писать, то как ты будешь писать всё то же самое, но на других языках, где этого нет?void foo(uint D)(const ref int[D] arr) if (D > 5)
Отредактировано py.user.next (Май 6, 2017 14:36:54)
Офлайн
В 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");
}
}
Отредактировано Shaman (Май 6, 2017 15:25:59)
Офлайн