Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум разработчиков электроники ELECTRONIX.ru _ Программирование _ Инициализация структуры

Автор: Jenya7 Jul 20 2018, 12:25

Хотел немного схитрить, ну так, с краешку. Создал структуру

Код
typedef struct
{
    uint32_t menu_id;
    char *menu_text;
}MENU_ITEM;

typedef struct
{
    MENU_ITEM main_menu;
    MENU_ITEM *submenu;
}MENU;
Инициализирую
Код
MENU menu[] =
{
    {  { 1, "MENU1"},
       { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } }
    }
};
Компилятор ругается на уровне ворнинга
Цитата
(near initialization for 'menu[1].submenu') [enabled by default]
braces around scalar initializer [enabled by default]
excess elements in scalar initializer [enabled by default]
initialization makes pointer from integer without a cast [enabled by default]

причем если убираю скобки ругается на уровне ошибки.

Не хочет видеть как указатель на массив. Все так плохо или можно что то сделать?

Автор: AlexRayne Jul 20 2018, 12:32

Цитата(Jenya7 @ Jul 20 2018, 15:25) *
Не хочет видеть как указатель на массив. Все так плохо или можно что то сделать?

все имено так плохо
делайте { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } } - отдельной константой.
код станет чуть менее красивым, но по моему - не сильно ухудшится. терпимо будет.

Автор: Jenya7 Jul 20 2018, 12:38

Цитата(AlexRayne @ Jul 20 2018, 18:32) *
все имено так плохо
делайте { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } } - отдельной константой.
код станет чуть менее красивым, но по моему - не сильно ухудшится. терпимо будет.


я хотел чтоб это был единый объект.

отдельно он тоже не принимает как массив структур. только если определяю статический массив.

ну разве что так?
Код
MENU_ITEM subm[]= { {0,"SUBMENU1"}, {1,"SUBMENU2"} , {2,"SUBMENU2"}, {3,"SUBMENU3"} };
MENU menu[5];

menu[0].main_menu.menu_id = 1;
menu[0].main_menu.menu_text = "MENU1";
menu[0].submenu= subm;

Автор: jcxz Jul 20 2018, 13:57

Цитата(Jenya7 @ Jul 20 2018, 15:25) *
Код
MENU menu[] =
{
    {  { 1, "MENU1"},
       { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } }
    }
};

И на кой на это тратить ОЗУ??? wacko.gif

Автор: Arlleex Jul 20 2018, 14:14

Цитата(Jenya7 @ Jul 20 2018, 16:25) *
причем если убираю скобки ругается на уровне ошибки.

Как Вы собираетесь объявить массив, содержащий указатель на объект, который еще не объявлен? Вот и весь ответ на вопрос о возможности так схитрить.
Код
typedef struct
{
    uint32_t menu_id;
    char *menu_text;
}MENU_ITEM;

typedef struct
{
    MENU_ITEM main_menu;
    MENU_ITEM *submenu;
}MENU;

int main(void)
{
    MENU_ITEM item[3] = {{0, "SUBMENU1"}, {1, "SUBMENU2"}, {2, "SUBMENU3"}};
    
    MENU menu[] = {{{1, "MENU1"}, &item[0]}, {{1, "MENU1"}, &item[1]}, {{1, "MENU1"}, &item[2]}};
    
    return 0;
}

Автор: Jenya7 Jul 20 2018, 15:21

Цитата(Arlleex @ Jul 20 2018, 20:14) *
Как Вы собираетесь объявить массив, содержащий указатель на объект, который еще не объявлен? Вот и весь ответ на вопрос о возможности так схитрить.
Но инициализируя я же его объявляю. я передаю реальные адреса.

получается промежуточный массив. а что компилятор не достаточно умный чтоб сделать подстановку?

Автор: Arlleex Jul 20 2018, 15:32

Цитата(Jenya7 @ Jul 20 2018, 18:21) *
Но инициализируя я же его объявляю. я передаю реальные адреса.

Да ну? Где это Вы реальные адреса там передаете, не подскажете?

Цитата(Jenya7 @ Jul 20 2018, 18:21) *
получается промежуточный массив. а что компилятор не достаточно умный чтоб сделать подстановку?

Какой еще промежуточный массив? Компилятор не достаточно умный? Где-то я подобное смелое утверждение слышал уже. И вроде от Вас biggrin.gif

Автор: krux Jul 20 2018, 17:00

динамика....
в меню....
наибессмысленнейшее решение.

нет, я всё понимаю, если бы у вас был фронтенд-бэкенд с джаваскриптом, node.js и танцовщицами, но нет же, это тупо голый Си!

Автор: Serge V Iz Jul 20 2018, 18:03

Попробуйте встать на место компилятора. Инициализатор из двух фигурных скобок внутри объемлющей фигурной скобки - это что? Лично я считаю, что это структура, полями которой являются составные типы )

В записи просто недостаточно информации, чтобы вывести тип. Компилятор не сможет корректно такое обработать )

Автор: x893 Jul 20 2018, 18:33

Всё будет во флэш, инициализация не нужна.

Код
typedef struct
{
    const uint32_t menu_id;
    const char *menu_text;
} MENU_ITEM;

typedef struct
{
    const MENU_ITEM main_menu;
    const MENU_ITEM *submenu;
} MENU;

const MENU_ITEM submenu1[] = { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } };
const MENU_ITEM submenu2[] = { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } };
const MENU menu[] =
{
    { { 1, "MENU1"}, submenu1 },
    { { 2, "MENU2"}, submenu2 }
};

Автор: Jenya7 Jul 21 2018, 05:41

Цитата(x893 @ Jul 21 2018, 00:33) *
Всё будет во флэш, инициализация не нужна.
Код
typedef struct
{
     const uint32_t menu_id;
     const char *menu_text;
} MENU_ITEM;

typedef struct
{
     const MENU_ITEM main_menu;
     const MENU_ITEM *submenu;
} MENU;

const MENU_ITEM submenu1[] = { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } };
const MENU_ITEM submenu2[] = { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } };
const MENU menu[] =
{
     { { 1, "MENU1"}, submenu1 },
     { { 2, "MENU2"}, submenu2 }
};

ну а если я записал
Код
{ { 1, "MENU1"},  { {0, "SUBMENU1" }, { 1, "SUBMENU2" }, { 2, "SUBMENU3" } } },

какая разница компилятору. в чем его трудности. это не одно и то же?

Автор: x893 Jul 21 2018, 06:08

Это надо у компилятора спрашивать.

Автор: jcxz Jul 21 2018, 09:05

Цитата(Jenya7 @ Jul 21 2018, 08:41) *
какая разница компилятору. в чем его трудности. это не одно и то же?

Я думаю у него трудностей нет, только у вас. Так как не он пишет в форум, а вы. biggrin.gif

Автор: XVR Jul 23 2018, 12:33

Janya7 - вы случайно не состоите в родстве с Гастингсом?

Цитата
— Ну что вы, Пуаро, — пробормотал я. — Мне очень лестно… Вероятно, я так или иначе научился чему-то от вас…
Он отрицательно покачал головой.
— Mais поп, ce n'est pas ca¹. Вы ничему не научились.
— Как? — изумленно спросил я.
— Не удивляйтесь. Все правильно. Никто ни у кого не должен учиться. Каждый человек должен развивать до предела свои возможности, а не копировать кого-то другого. Я не хочу, чтобы вы стали ухудшенным Пуаро. Я хочу, чтобы вы были непревзойденным Гастингсом! Впрочем, вы и есть непревзойденный Гастингс. Вы классически, совершенно нормальны.

Автор: GetSmart Jul 23 2018, 23:32

Цитата(Jenya7 @ Jul 21 2018, 09:41) *
какая разница компилятору. в чем его трудности. это не одно и то же?

Как откровенничал когда-то (кажется) zltigo: одно дело - стандарт, и немного другое дело - секретные инструкции компиляторописателям.
Жаль, таких зачотных бесед уже давно не наблюдается.

Если бы была очевидна и проста однозначность толкования при разборе текста, (без опережающего анализа, возвратов и прочих излишеств, которых не было в ранних компиляторах), то наиболее вероятно, что так и сделали бы. А потом большой вес уже приобретала обратная совместимость.

Представьте:
Допустим указатель был на структуру1, в которой первым членом идёт структура2. Компилятор, спускаясь/шагая по дереву/структуре опознанного типа, при заполнении содержимого типа <указатель на структуру1> увидев две открывающиеся фигурные скобки без какого-либо подвоха подумает, что вторая скобка есть вход в структуру2. А Jenya7 будет думать, что он первой скобкой создаёт массив структур1, а после второй заполняет первый член структуры1. Можно предположить, что во избежание гемороя/неоднозначностей, первая скобка, при указателе на структуру/юнион трактуется как начало данных этой структуры/юниона. А не гадание на кофейной гуще - захотел ли кодописатель организовать массив и сколько в этом массиве измерений (не элементов!). А может быть ещё и не раз захотел, в подуровнях членов. И полный вынос мозга: массив указателей на массив указателей на массив с типом любых чисел. Компилятор, где-то после 3-ей открытой скобки встретит 0 и не поймёт, что это: нулевой указатель или край иерархии - значение с типом любого числа. Плюс к этому, блок данных (между фигурными скобками) не обязательно заполнять до конца. Можно сразу после нуля поставить закрывающую скобку.

Имхо, самый близкий к желаемому вариант был в 10-ом посте. Грех жаловаться.

Автор: XVR Jul 24 2018, 07:49

Цитата(Jenya7 @ Jul 21 2018, 08:41) *
какая разница компилятору. в чем его трудности. это не одно и то же?
Нет, это не одно и тоже.
В языке С при инициализации структур и массивов происходит именно ИНИЦИАЛИЗАЦИЯ. Компилятор не может вдруг прервать инициализацию, сделать анонимный массив, что бы инициализировать указатель. Если требуется указатель, то и должен быть передан указатель.
Вопреки распространённому мнению в С указатели и массив НЕ ОДНО И ТОЖЕ! Хотя часто можно использовать идентификатор массива как указатель, наоборот использовать нельзя (указатель вместо массива).


Автор: GetSmart Jul 26 2018, 01:22

Апосля подумалось. Идея смысла текста топикстартера из первого поста интуитивно понятна (= наиболее проста и очевидна: для указателя агрегатного типа допускать ввод сразу данных агрегатного типа). Только если в стандарте (года?) этот способ не указан, то никаких гарантий, что все компиляторы это будут понимать и делать. Строка не в счёт, она не агрегатный тип.

Пустые скобки при объявлении функции без параметров тоже интуитивно понятны. Хотя некоторым компиляторам очень хочется (приказали?) засунуть туда таракана. А интуитивно непонятно, почему структуры копировать присвоением a=b можно, а массивы (хотя бы с константным размером) - нельзя. И там, и там - агрегатный тип и всё казалось бы корректно, но хрен там. И с приоритетами операций там какая-то алогичность. И что-то ещё было, уже не вспомню.

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

Автор: jcxz Jul 26 2018, 08:21

Цитата(GetSmart @ Jul 26 2018, 04:22) *
В си оказывается меняли синтаксис. Существует вариант объявления функций по старому стилю, в котором в скобках только имена, а перед открытием стартового блока функции - объявления этих имён с типами.

Ну так это - общеизвестно.
А ещё в конструкторах класса можно члены класса инициализировать до тела функции конструктора с помощью доп. символа ':':
Код
COscWFileDlg::COscWFileDlg(COscDlg *dlg, char const *path, HANDLE h) :
  fname(path), hfile(h), rawNVmax(dlg->rawNVmax), oscRaw(dlg->oscRaw), CDialog(COscWFileDlg::IDD), RThread(NULL)
{
...
}

что я часто и применяю rolleyes.gif

Автор: AlexRayne Jul 26 2018, 09:16

Цитата(GetSmart @ Jul 26 2018, 04:22) *
А интуитивно непонятно, почему структуры копировать присвоением a=b можно, а массивы (хотя бы с константным размером) - нельзя. И там, и там - агрегатный тип и всё казалось бы корректно, но хрен там. И с приоритетами операций там какая-то алогичность. И что-то ещё было, уже не вспомню.

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

Автор: aiwa Jul 26 2018, 09:16

Цитата(XVR @ Jul 24 2018, 10:49) *
Вопреки распространённому мнению в С указатели и массив НЕ ОДНО И ТОЖЕ! Хотя часто можно использовать идентификатор массива как указатель, наоборот использовать нельзя (указатель вместо массива).

Почему же нельзя?

void fun(int* point)
{
point[3]=4; // использование указателя как массив
}

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

int array[10];
for(int ind=0;ind<10;ind++)
{
ind[array] = ind;
}

Автор: Arlleex Jul 26 2018, 10:35

Это все известные вещи.
Но, как было правильно отмечено выше, указатель и имя массива, хотя и являются похожими, являются принципиально разными объектами.

Автор: andrew_b Jul 26 2018, 10:54

Цитата(AlexRayne @ Jul 26 2018, 12:16) *
в с компировать структуры низя
Да ладно.

Автор: Arlleex Jul 26 2018, 11:03

Цитата(AlexRayne @ Jul 26 2018, 13:16) *
в с компировать структуры низя...

Можно. Массивы тоже можно, но на основе структур:
Код
struct
{
    int data[100];
}Array1, Array 2;
...
Array1 = Array2;

Автор: XVR Jul 26 2018, 12:32

Цитата(aiwa @ Jul 26 2018, 12:16) *
Почему же нельзя?

void fun(int* point)
{
point[3]=4; // использование указателя как массив
}
Потому что это не массив, а индексация. И применяется она (СЮРПРИЗ!) к указателям
А массив - это некий объект в памяти, а не набор операций.


Автор: aiwa Jul 27 2018, 09:09

Цитата(XVR @ Jul 26 2018, 15:32) *
Потому что это не массив, а индексация. И применяется она (СЮРПРИЗ!) к указателям

Никакого сюрприза, просто имя массива - является указателем на первый элемент массива.
По сути доступ к массиву в стандартной нотификации получается как доступ через указатель.

Цитата
6.5.2.1 Array subscripting
Constraints
1
One of the expressions shall have type ‘‘pointer to complete object type ’’, the other expression shall have integer type, and the result has type ‘‘type’’.


Т.е. в "array[index]" array - это ‘‘pointer to complete object type ’’, index - integer type, array[index] - это the result has type ‘‘type’’.

Аналогично с index[array].

Автор: XVR Jul 27 2018, 09:19

Цитата(aiwa @ Jul 27 2018, 12:09) *
Никакого сюрприза, просто имя массива - является указателем на первый элемент массива.
Не является, а автоматически приводится в нужных случаях. Сравните:

Код
char* pointer;
char array[100];

printf("%d/%d\n", sizeof(pointer), sizeof(array));
Если бы 'имя массива - является указателем на первый элемент массива' то мы получили бы 4/4 (предположим что указатель 4х байтоый). А получим мы 4/100

Честно говоря уже не хочется это разжёвывать - мульён раз об этом писалось, и каждый раз получается портянка на десяток страниц заказчивающаяся каким нибудь холиваром sad.gif

Автор: GetSmart Jul 28 2018, 15:36

+5 копеек:
индексация указателя не контролирует индекс, а индексация (имени) массива будет, при возможности, проверять индекс на допустимый диапазон.

ЗЫ
Кстати, index[array] какой-то обкуренный товарищ придумал. Любопытно было бы узнать исторические предпосылки или адекватную логическую аргументацию этого кошмара. (а не тупой отсыл к тексту стандарта, в котором не обязана быть аргументация)

Хотелось бы удостовериться, что все интуитивно непонятные места в Си существуют для обхода (старых и новых) граблей или для увеличения концентрации смысла на еденицу текста. Но с минимизацией ущерба общекомпьютерным категориям и терминам, которыми мыслят и на которых общаются разработчики, например, широкого профиля.

Автор: Arlleex Jul 28 2018, 16:51

Цитата(GetSmart @ Jul 28 2018, 18:36) *
+5 копеек:
индексация указателя не контролирует индекс, а индексация (имени) массива будет, при возможности, проверять индекс на допустимый диапазон.

ЗЫ
Кстати, index[array] какой-то обкуренный товарищ придумал.

Выход да пределы индексации массива может быть проверен только на этапе компиляции, и то не утвердительно всегда.
А фокус с перестановкой имени и индекса следует из того, что перед компиляцией выражение вида a[i] заменяется на *(a + i). Поэтому все логично.

Автор: GetSmart Jul 28 2018, 17:01

Цитата(Arlleex @ Jul 28 2018, 20:51) *
А фокус с перестановкой имени и индекса следует из того, что перед компиляцией выражение вида a[i] заменяется на *(a + i). Поэтому все логично.

Для начала - спасибо за подсказку. Но не преувеличивайте. То, что кто-то допустим узнал, откуда появился (void) в списке аргументов функции, логичности этому таракану не добавило. Это криво и будет интуитивно непонятно новичкам. А высший пилотаж при разработке языка, в дополнение ко всем достоинствам языка, - когда новичкам без подсказок понятны многие конструкции. Чем меньше им потребуется читать стандарт, хотя бы на начальном этапе, тем качественнее можно оценить работу разработчиков.

Уже теплее и теплее ощущается, что "ТЗ от шефа" было (зачем-то?) в усложнении правил разбора текста компилятору. У массивов, видимо, куча правил перемешалась и вылезла пара грыж.

Автор: aiwa Jul 29 2018, 00:25

Цитата(GetSmart @ Jul 28 2018, 18:36) *
Кстати, index[array] какой-то обкуренный товарищ придумал. Любопытно было бы узнать исторические предпосылки или адекватную логическую аргументацию этого кошмара. (а не тупой отсыл к тексту стандарта, в котором не обязана быть аргументация)

Не обкуренный товарищ, а группа обкуренных товарищей (WG14). "6.5.2.1 Array subscripting".
Из второго пункта: "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))."
И далее объяснение - потому что "E1 is an array object (equivalently, a pointer to the initial element of an array object)".

Для примера с sizeof: "6.5.3.4 The sizeof and _Alignof operators", разъясняет, что от sizeof(E1) не стоит ожидать физического размера указателя ибо
sizeof "yields the size of the adjusted (pointer) type".

Автор: GetSmart Jul 29 2018, 05:43

Цитата(aiwa @ Jul 29 2018, 04:25) *
Из второго пункта: "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))."

Явно не обозначена аргументация, зачем превращать (классическую) индексацию массива в выражение со сложением. И чем не понравился вариант, когда два (три) оператора (+/-, []) могут быть применимы к массиву. Не обозначены веские причины для того, чтобы массив стал исключением из общих правил нисходящего перемещения по агрегатным типам, когда в тексте левая часть выражения указывает на более массивный агрегатный тип. При этом массивный агр. тип является источником имён и прочей инфы для нисхождения. Для массива это правило интуитивно оптимально при обращениях к многомерным массивам. Здесь же "E1[E2] is identical to (*((E1)+(E2)))" контроль диапазонов многомерия либо невозможен, либо возможен только контроль суммарного размера массива. Плюс, все операторы ".", "->" являются ассиметричными к операндам, аналогично "[]" в большинстве ЯП, изучаемых в образовательных учреждениях. Это правило делает и работу компилятора и читабельность текста проще.

С таким стандартом руки чешутся писать E1[E2]E3[E4] и прочую ерунду. Опять же, ++E1[E2] , где E2 - массив, E1 - integer lvalue, - выносит мозг конкретно. Хочется инкрементнуть элемент массива, но читается по естественным правилам это как увеличение индекса. Плюс: E1++[E2]++. Если ещё покопать, то можно мумию Тутанхамона выкопать.

Автор: andrew_b Jul 29 2018, 07:14

Цитата(GetSmart @ Jul 29 2018, 08:43) *
Плюс, все операторы ".", "->" являются ассиметричными к операндам, аналогично "[]" в большинстве ЯП, изучаемых в образовательных учреждениях. Это правило делает и работу компилятора и читабельность текста проще.
Когда содавался язык Си, никаких
Цитата
ЯП, изучаемых в образовательных учреждениях
не было.

Автор: aiwa Jul 29 2018, 08:38

Цитата(GetSmart @ Jul 29 2018, 08:43) *
Явно не обозначена аргументация, зачем превращать (классическую) индексацию массива в выражение со сложением.

Смотря что считать классической моделью. Имхо, в С и есть классическая модель - непосредственное использование индексной адресации машинного кода.

Цитата(GetSmart @ Jul 29 2018, 08:43) *
Здесь же "E1[E2] is identical to (*((E1)+(E2)))" контроль диапазонов многомерия либо невозможен, либо возможен только контроль суммарного размера массива.

По сути "E1[E2] is identical to (*((E1)+(E2)))" - это лишь выражение идеи. Для полной идентичности целое E2 должно быть умножено на типоразмер E1.
Идея состоит в том, что имя массива страдает дуализмом: оно указывает на первый элемент массива но не является указателем в нормативном смысле.
Отсюда естественно вытекает определение многомерных массивов: показывает на элемент, который является массив меньшей размерности.
Поэтому контроль диапазонов вполне возможен и, в принципе, легко реализуем, но, к всеобщему счастью, априори не предусмотрен в С.

Цитата(GetSmart @ Jul 29 2018, 08:43) *
С таким стандартом руки чешутся писать E1[E2]E3[E4] и прочую ерунду. Опять же, ++E1[E2] , где E2 - массив, E1 - integer lvalue, - выносит мозг конкретно. Хочется инкрементнуть элемент массива, но читается по естественным правилам это как увеличение индекса. Плюс: E1++[E2]++. Если ещё покопать, то можно мумию Тутанхамона выкопать.

++E1[E2] - это и есть по естественным правилам инкрементация элемента массива E1[E2].
А вот E1++[E2]++ не сработает. Нужно писать (E1+1)[E2]++;
E1[E2]E3[E4], понятное дело не имеет смысла как и написанные слитно два имени переменных.

Автор: GetSmart Aug 2 2018, 02:41

Цитата(andrew_b @ Jul 29 2018, 11:14) *
Когда содавался язык Си, никаких {ЯП, изучаемых в образовательных учреждениях} не было.

Да, но тогда переформулируя, в большинстве ЯП высокого уровня того времени.

----------------
Как сказал один мой необкуренный коллега: Что-то у вас тут недоработано ©

Ещё, надеюсь, в стандарте кто-нибудь догадался однозначно указать, что в разделе кода точка с запятой после закрытия непустого блока (}) выражением не считается. (из-за которого предыдущие IF потеряют возможность иметь ELSE)

Upd. И это, разумеется, не касается блока инициализатора. Ещё лучше так: ... указать, что точка с запятой, интерпретируемая первым оператором после закрытия непустого блока кода (закр. фиг. скобки), - выражением не считается.

Отпуск на носу. Отложу раскопки на потом.

Автор: andrew_b Aug 2 2018, 04:51

Цитата(GetSmart @ Aug 2 2018, 05:41) *
Да, но тогда переформулируя, в большинстве ЯП высокого уровня того времени.
А много ли их тогда было вообще?
Цитата(GetSmart @ Aug 2 2018, 05:41) *
Ещё, надеюсь, в стандарте кто-нибудь догадался однозначно указать, что в разделе кода точка с запятой после закрытия блока (}) выражением не считается. (из-за которого предыдущие IF потеряют возможность иметь ELSE)
А с чего бы? Это пустой оператор. Он тоже подчиняется всем правилам.

Автор: GetSmart Aug 2 2018, 05:39

Цитата(andrew_b @ Aug 2 2018, 08:51) *
А с чего бы? Это пустой оператор. Он тоже подчиняется всем правилам.

Это удобно для макросов, кои были задуманы сразу же на заре Си. Чтобы не требовалась (ужжасная) обёртка do...while(0).

ps
в пред пост вставил <непустого>, т.к. часто видел и даже сам раньше употреблял {}; в чём-то вроде while (...) {};

Автор: andrew_b Aug 2 2018, 06:53

При чём тут непустой блок? Пустой оператор -- это ;. Для всех операторов правила общие.

Автор: GetSmart Aug 2 2018, 12:04

Там немного обновил.

Отвечу так: одной из важнейших целей правил является компактность и ясность программы. Если это требует маленького исключения/особенности, то ничего плохого в этом нет. Которые там и так есть. Это точно менее кошмарно, чем index[array] и мутный do {...} while (0) в макросе. Кроме того, предельная простота совсем не гарантирует однозначности (толкования).


Цитата(aiwa @ Jul 29 2018, 12:38) *
По сути "E1[E2] is identical to (*((E1)+(E2)))" - это лишь выражение идеи. Для полной идентичности целое E2 должно быть умножено на типоразмер E1.
Идея состоит в том, что имя массива страдает дуализмом: оно указывает на первый элемент массива но не является указателем в нормативном смысле.
Отсюда естественно вытекает определение многомерных массивов: показывает на элемент, который является массив меньшей размерности.
Поэтому контроль диапазонов вполне возможен и, в принципе, легко реализуем, но, к всеобщему счастью, априори не предусмотрен в С.

Подскажите тогда, какой тип будут иметь вполне корректные выражения: (при E2=array, E1=index, для одномерного и многомерного массивов)
1: ((E1)+(E2))
2: ((E1)+(E2)+5)
3: ((E1)+5+(E2))
И, если можете, дайте определение/цитату или ссыль на упомянутый термин <типоразмер E1> в тексте <целое E2 должно быть умножено на типоразмер E1>. Это размер элемента ниже по иерархии от имени или размер элемента "на самом дне массива"? Или даже размер целого массива, на который указывает имя? (<типоразмер short> я буквально понимаю как 2 байта {например в Keil for ARMv4..ARMv7}. Типоразмер E5, где E5=структура, я склонен толковать как размер всей структуры, и по этой причине типоразмер E1 (ака массива) - как всего массива целиком. Для версии <имя массива в какой-то мере адрес> считать типоразмером E1 размер адреса - в обсуждаемом контексте вообще маловероятно).

Автор: aiwa Aug 2 2018, 14:00

Цитата(GetSmart @ Aug 2 2018, 15:04) *
Подскажите тогда, какой тип будут иметь вполне корректные выражения: (при E2=array, E1=index, для одномерного и многомерного массивов)
1: ((E1)+(E2))
2: ((E1)+(E2)+5)
3: ((E1)+5+(E2))


1. указатель на E1-й элемент массива E2.
2. и 3. указатель на (E1+5)-й элемент массива E2.

В случае многомерности E2 элементом будет выступать массив размерности меньшей на единицу, чем E2 .

Когда я говорил про типоразмеры я имел ввиду упомянутые выше ассемблерные команды.
Компилятор С сложение в этих выражениях понимает в смысле арифметики указателей и все получается корректным.




Автор: GetSmart Aug 2 2018, 14:17

Цитата(aiwa @ Aug 2 2018, 18:00) *
1. указатель на E1-й элемент массива E2.
2. и 3. указатель на (E1+5)-й элемент массива E2.

В случае многомерности E2 элементом будет выступать массив размерности меньшей на единицу, чем E2 .

В стандарте пример подобный описан или какие-то комментарии разработчиков прилагаются?

Мне непонятно, для массива определены особые правила вычисления выражений? По стандартным/общим правилам для варианта 2 будет сперва выполнено (E1)+(E2) и результатом будет (как заявлено в цитате из стандарта) - адрес элемента массива. При многомерном массиве - адрес массива <размерности меньшей на единицу, чем E2>. И уже когда к этому аргументу будет приплюсовываться число 5, то оно, проще говоря, должно быть (наиболее вероятно по вышеобозначенной инфе) индексом следующей (второй) размерности. Однако, если массив одномерный, то добавление числа к адресу, указывающему не на массив, истолкуется как добавление числа к указателю такого типа. И результат для одномерного массива будет действительно похож на <2. и 3. указатель на (E1+5)-й элемент массива E2.>

Автор: aiwa Aug 2 2018, 14:50

Цитата(GetSmart @ Aug 2 2018, 17:17) *
Мне непонятно, для массива определены особые правила вычисления выражений? По стандартным/общим правилам для варианта 2 будет сперва выполнено (E1)+(E2) и ....


Так все это E2+E1 и подобные выражения не являются исходным для применения правил, они лишь объясняют использование "array subscripting".

Грубо говоря, они помогают понимать как компилятор должен обходиться с выражениями вида expr1[expr2] и подобными.

Если E2 - многомерный массив, например E2[10][20][30][40][50]
2. и 3. варианты подходят к случаю E2[E1+5], результатом которого будет (E1+5)-й подмассив типа ()[20][30][40][50];
Для E2[E1][5] выражение будет композицией вышеупомянутого правила: сначала получается из "E2[E1]" (E1)-й подмассив типа ()[20][30][40][50] - грубо говоря к адресу E2 прибавляется E1*типоразмер ()[20][30][40][50], и затем к полученному результату правило применяют повторно для [5] - здесь уже арифметика указателей должна прибавлять пять типоразмеров меньшей размерности ()[30][40][50].

Под типразмером я имею ввиду физический размер с учетом выравнивания.

В стандарте, наверное, нет никаких типоразмеров, он оперирует "элементами массива", вводя многомерность по рекурсии.







Автор: GetSmart Aug 2 2018, 15:00

Цитата(aiwa @ Aug 2 2018, 18:50) *
Так все это E2+E1 и подобные выражения не являются исходным для применения правил, они лишь объясняют использование "array subscripting".

Грубо говоря, они помогают понимать как компилятор должен обходиться с выражениями вида expr1[expr2] и подобными.

В вышеобсуждаемой цитата из стандарта явно указано, что такое выражение разрешено стандартом (сложение чисел с именем массива). При неуказании особых правил этого "изврата" применяются стандартные правила приоритетов и ассоциативности. Без оговорок и комментариев на уровне стандарта иначе это нельзя истолковать.


Лучше даже уточнить:
Цитата
По стандартным/общим правилам для варианта 2 будет сперва выполнено (E1)+(E2) и результатом будет (как заявлено в цитате из стандарта) - адрес элемента массива. При многомерном массиве - адрес массива <размерности меньшей на единицу, чем E2>. И уже когда к этому аргументу будет приплюсовываться число 5, то оно, проще говоря, должно быть (наиболее вероятно по вышеобозначенной инфе) индексом следующей (второй) размерности. Однако, если массив одномерный, то добавление числа к адресу, указывающему не на массив, истолкуется как добавление числа к указателю такого типа.

<Адрес> точнее будет заменить на <что-то> (неуказанное в стандарте), содержащее адрес, указывающий на вышеобозначенный тип. (пример: <сперва выполнено (E1)+(E2) и результатом будет {как заявлено в цитате из стандарта} - адрес элемента массива.> ==> <что-то> с адресом элемента массива) И к этому <что-то> применим оператор *. К указателю он тоже применим, но их идентичность это не доказывает, без документального подтверждения.

Свой пред пост дополнил.

Автор: aiwa Aug 2 2018, 15:53

Цитата(GetSmart @ Aug 2 2018, 18:00) *
В вышеобсуждаемой цитата из стандарта явно указано, что такое выражение разрешено стандартом (сложение чисел с именем массива).


Если уж быть корректным, то сложение чисел не с именем массива, а с указателем (на тип элементов из которых состоит массив), в качестве которого выступает имя массива и равным алресу его "инициирующего элемента".




Цитата(GetSmart @ Aug 2 2018, 18:00) *
<Адрес> точнее будет заменить на <что-то> (неуказанное в стандарте), содержащее адрес, указывающий на вышеобозначенный тип. (пример: <сперва выполнено (E1)+(E2) и результатом будет {как заявлено в цитате из стандарта} - адрес элемента массива.> ==> <что-то> с адресом элемента массива) И к этому <что-то> применим оператор *.


В стандарте в качестве этого <что-то> употребляют термин "роinter". Это к тому, из-за чего весь сыр-бор пошел.

Автор: GetSmart Aug 2 2018, 16:49

Цитата(aiwa @ Aug 2 2018, 19:53) *
В стандарте в качестве этого <что-то> употребляют термин "роinter". Это к тому, из-за чего весь сыр-бор пошел.

Туда же добавил
<К указателю он тоже применим, но их идентичность это не доказывает, без документального подтверждения.>

Цитата(aiwa)
Если уж быть корректным, то сложение чисел не с именем массива, а с указателем (на тип элементов из которых состоит массив), в качестве которого выступает имя массива и равным алресу его "инициирующего элемента".


Сложение с именем массива:
result = *(array+5)

Сложение с указателем (на тип элементов из которых состоит массив):
result = *(&array[0]+5)

В цитате было (буквально) сложение с именем массива.

Цитата
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))

Переводится как <Определением <subscript operator []> является то, что {неявно подразумевается: выражение} E1[E2] идентично {выражению} (*((E1)+(E2)))>
Цитата
И далее объяснение - потому что "E1 is an array object (equivalently, a pointer to the initial element of an array object)".

Из чего следует, что в текстах разрешено использовать выражения со сложениями целых чисел с именами массивов. Без оговорок на размерность массивов.

Upd: А ещё точнее: с такими же ограничениями как и для оператора [].
Всё это не исключает при сложениях и такой возможности: при невозможности к аргументу применить оператор [], могут быть применены другие правила (если они определены), как то: трансформация аргумента в указатель и сложение с этим указателем.

То, что в определении имя заключено в круглые скобки - сути не меняет, т.к. в этом выражении они являются оператором изменения очерёдности выполнения других операторов. (чорт его знает как скобки там дословно определили) И (array)[index] по смыслу исполнения равноценно array[index], когда внутри скобок нет операторов. {неявно подразумевая: в тексте после препроцессора}

-------------
http://electronix.ru/redirect.php?https://electronix.ru/forum/index.php?showtopic=133161&view=findpost&p=1398518
Цитата(Сергей Борщ)
От перемены мест слагаемых сумма не меняется.

Цитата
Не надо гипотез. В стандарте все описано. И неявные преобразования, и коммуникативность сложения.

Автор: andrew_b Aug 3 2018, 05:01

Цитата(GetSmart @ Aug 2 2018, 19:49) *
Туда же добавил
Вы это прекращайте. С постоянными правками предыдущих сообщений трудно следить за дискуссией.
Цитата
<К указателю он тоже применим, но их идентичность это не доказывает, без документального подтверждения.>
Почему бы вам самим взять и не почитать стандарт языка Си? hint: google://ansi_c.pdf

Автор: GetSmart Aug 3 2018, 06:25

Я пару раз добавил в конец предыдущих постов одно и два предложения. И один раз абзац с отметкой Upd. В последний раз даже не видел, что уже новый пост появился. Редактирование постов для уточнения мыслей и существует. Ничего криминального в этом нет.

Не удержался. Третий раз дополнил предыдущий пост.

Позже почитаю, после отпуска.

Автор: aiwa Aug 3 2018, 09:32

Цитата(GetSmart @ Aug 2 2018, 19:49) *
Сложение с именем массива:
result = *(array+5)

Сложение с указателем (на тип элементов из которых состоит массив):
result = *(&array[0]+5)

В цитате было (буквально) сложение с именем массива.


Не путайте терминологию: имя массива - это идентификатор, арифметические с которыми бессмыслены.

Приведенные Вами два примера отличаются лишь небольшой деталью.
Во втором Вы сами используете указатель, а в первом тот же указатель получается "implicitly" - согласно стандарту: "by converting an array name to a pointer".


Цитата(GetSmart @ Aug 2 2018, 19:49) *
Из чего следует, что в текстах разрешено использовать выражения со сложениями целых чисел с именами массивов. Без оговорок на размерность массивов.


Ну да, про коммутативность это понятно - побочный эффект.
Равно как по той же причине в массиве размерности 5x5 доступ к "последнему" элементу a[4][4] вполне может быть реализован как a[15][0] или a[0][15].


Автор: GetSmart Aug 3 2018, 12:09

Цитата(aiwa @ Aug 3 2018, 13:32) *
Не путайте терминологию: имя массива - это идентификатор, арифметические с которыми бессмыслены.

Приведенные Вами два примера отличаются лишь небольшой деталью.
Во втором Вы сами используете указатель, а в первом тот же указатель получается "implicitly" - согласно стандарту: "by converting an array name to a pointer".

Определение дано на текстовом примере. После этого запрещать описание словами текстовых конструкций языка бессмысленно. Кроме того, в данном контексте <имя массива> более однозначно описывает <инструкцию> писателя кода. Если я напишу <массив>, то сразу подменю обсуждаемую <инструкцию> до многих вариантов текстового представления. Поэтому такие формулировки имеют право быть. Добавлять везде <в тексте> излишне, это неявно контекстно подразумевается. Скорее будет важно: до препроцессора или после, всякие области видимости, наложения имён переменных, макросов и прочего. По-умолчанию в таких формулировках разумно считать, что интерпретация текста по стандарту в том тексте выявит однозначно: имя массива, оператор сложения и целое число 5. И оператор сложения будет выполнен до всех иных операторов.

Цитата(aiwa @ Aug 3 2018, 13:32) *
Равно как по той же причине в массиве размерности 5x5 доступ к "последнему" элементу a[4][4] вполне может быть реализован как a[15][0] или a[0][15].

Ерунда какая-то. 5*5=25

Автор: aiwa Aug 3 2018, 12:57

Цитата(GetSmart @ Aug 3 2018, 15:09) *
...Если я напишу <массив>, то сразу подменю обсуждаемую <инструкцию> до многих вариантов текстового представления. Поэтому такие формулировки имеют право быть.

В оригинале сказано именно массив, что эквивалентно указателю на первый элемент: "if E1 is an array object (equivalently, a pointer to the initial element of an array object)"
Но если массив или имя массива смотрятся как синонимы, то "прибавление к имени массива" как-то не комильфо.

Цитата(GetSmart @ Aug 3 2018, 15:09) *
Ерунда какая-то. 5*5=25

Ну да, отвлекся и написал для массива 4x4, правильно было бы а[0][24] и a[24][0]. Но не важно, - главное, что коммутативность арифметики с указателем приводит к такому побочному эффекту.
Поэтому не стоит это ставить во главу угла.

Автор: GetSmart Aug 3 2018, 13:58

Цитата(aiwa @ Aug 3 2018, 16:57) *
В оригинале сказано именно массив, что эквивалентно указателю на первый элемент: "if E1 is an array object (equivalently, a pointer to the initial element of an array object)"

<(equivalently, a pointer> в данном контексте переводится как: <(равно{значно} {допустимо}, если это указатель>
фигурными скобками выделил неявный смысл, который, при желании, можно не писать. В контексте этого абзаца <equivalently> не определяет, что везде в языке оба варианта равнозначны. Ещё, из этой цитаты не понять, какое действие вызывает оператор [], применимый к обычному указателю. Даже из всей главы <6.5.2.1 Array subscripting> непонятно, какое действие по стандарту выполняет применение [] к указателю на не массив (на не элемент массива). В её вступлении написали
Цитата
One of the expressions shall have type "pointer to
object type", the other expression shall have integer type,
and the result has type "type"

Далее везде "если это массив или указатель на начальный элемент массива то ...".
PS но я мельком прочитал эти три абзаца. Прошу опровергнуть, если я неправ.

Upd
Учитывая вступительную цитату, с которой я только что ознакомился моё утверждение <В цитате было (буквально) сложение с именем массива. >
правильнее заменить на <В цитате вполне допускалось сложение с именем массива.>

Автор: aiwa Aug 3 2018, 14:31

Цитата(GetSmart @ Aug 3 2018, 16:58) *
В контексте этого абзаца <equivalently> не определяет, что везде в языке оба варианта равнозначны.

Та там всего три абзаца, из которых следует вывод, что имя массива почти всегда (за исключением, например, sizeof правила для которого обговорены в отдельном пункте) преобразуется в указатель на первый элемент массива причем того же типа. С дальнейшими правилами действий для такого указателя.
Таким образом из выражений *((E2+5)+E1), ((E2)+5+(E1)) и подобных невозможно что-либо утверждать про размерности массива.

Цитата(GetSmart @ Aug 3 2018, 16:58) *
Даже из всей главы <6.5.2.1 Array subscripting> непонятно, какое действие по стандарту выполняет применение [] к указателю на не массив (на не элемент массива).


Никаких указателей на не массив и прочее.
Так название главы означает что оператор [] применим только для доступа к элементам массива.



Автор: GetSmart Aug 3 2018, 14:54

В стандарте есть явные определения логики интерпретации применения [] к указателю на не массив и на не элемент массива?

Цитата(aiwa @ Aug 3 2018, 18:31) *
Та там всего три абзаца, из которых следует вывод, что имя массива почти всегда (за исключением, например, sizeof правила для которого обговорены в отдельном пункте) преобразуется в указатель на первый элемент массива причем того же типа.

Никаких <почти всегда> оттуда не следует. Тем более, что что-то там преобразуется. Смысл написанного: <допускается писать такую конструкцию с такими-то вариантами, которая будет истолкована так...>

Автор: aiwa Aug 3 2018, 15:14

Цитата(GetSmart @ Aug 3 2018, 17:54) *
В стандарте есть явные определения логики интерпретации применения [] к указателю на не массив и на не элемент массива?

Нет. Оператор [] значится как postfix-operator и определен для "array subscripting". Это признак массива.



Цитата(GetSmart @ Aug 3 2018, 17:54) *
Никаких <почти всегда> оттуда не следует.

"Почти всегда" следует потому в случае оператора sizeof, согласно которому имя_массива преобразуется в тип "массив заданной размерности",
в остальных случаях имя_массива преобразуется в &имя_массива[0].

Автор: GetSmart Aug 3 2018, 17:45

Цитата
Ну да, отвлекся и написал для массива 4x4, правильно было бы а[0][24] и a[24][0]. Но не важно, - главное, что коммутативность арифметики с указателем приводит к такому побочному эффекту.

Это по шагам можете объяснить?
Мне понятны варианты когда а[0][24] идентичен a[1][19] и идентичен a[2][14] и т.д. Если не обращать внимание на варнинги компилятора. Но a[24][0] каким образом-то?

Цитата(aiwa @ Aug 2 2018, 18:00) *
2. и 3. указатель на (E1+5)-й элемент массива E2.

index1[index2][array_name] и index1[index2][index3][array_name] тоже разрешены? Если да, исходя из каких формулировок?

Цитата(aiwa @ Aug 3 2018, 19:14) *
Нет. Оператор [] значится как postfix-operator и определен для "array subscripting". Это признак массива.

То есть разрешение применения [] к любому указателю на непустой тип даёт именно первый абзац главы <6.5.2.1 Array subscripting> ? object type определён как любой, за исключением void? В стандарте есть суммарный раздел об авто-преобразованиях? Или надо шерстить весь стандарт чтобы откопать однозначность?

Видимо отсюда и растут ноги у названия "подписка". Страннейшего, для необкуренных мозгов. Обозвали бы "индексация" и уловка с авто-подменой была бы недоступна.

В посте 40 я ошибся, в цитате:
<И уже когда к этому аргументу будет приплюсовываться число 5, то оно, проще говоря, должно быть (наиболее вероятно по вышеобозначенной инфе) индексом следующей (второй) размерности.>
т.к. на следующую размерность не перейти, без применения оператора * в вариантах со сложением.


Цитата(aiwa)
"Почти всегда" следует потому в случае оператора sizeof, согласно которому имя_массива преобразуется в тип "массив заданной размерности",
в остальных случаях имя_массива преобразуется в &имя_массива[0].

Ну бред же. Для компилятора имя массива - это lvalue (кратко - объект в памяти). К нему можно применить амперсанд. &имя_массива[0] - это rvalue, к нему (здесь будет второй раз) амперсанд не применим. И для (простейше определённого) многомерного массива array_name[0] есть тоже lvalue. А, согласно этой цитаты, выражение &(array_name[0]) давало бы ошибку. Т.к. выражение в скобках, являющееся массивом авто-преобразовывалось бы в указатель. Хотя, корректней писать в <rvalue-указатель>. Всё это потверждает, что и rvalue с типом указатель на массив и lvalue с типом массив существуют без всякого sizeof, в них определена характеристика размера (для размерных), компиляторы поступают вполне разумно её проверяя на этапе компиляции, а что мешает копировать массивы выражениями вроде a=b - непонятно.

В языке должна быть ясность очерёдности исполнения авто-преобразований и операторов. Например: авто-преобразования применяются компилятором в самый последний момент исполнения операторов. И не должны менять приоритеты операторов при определении очерёдности их исполнения. Хотя, с таким неполным стандартом, если по нему ясность поведения будет не определена, то, наверное, судить придётся по каким-то ещё документам, например от выдумщика языка. А то появится несогласующийся с ранее написанными правилами футбол между операторами, операндами и авто-преобразованиями. (в этой ветке я ранее писал аргументов, но терминологически точнее, видимо, операндов для операторов и аргументов/параметров для функций)

Пытаясь как-то оправдать логику выдумщика и потом стандарта, когда на начальном этапе массив (array object по терминологии главы 6.5.2.1) казался избыточным и работу с массивами НАДО БЫЛО организовывать через указатели и операторы +-, которым был непринципиален порядок разношёрстных операндов, мне самому любопытно, на какой развилке не туда свернули)))
Упд. Именно такая историческая цепь прослеживается при чтении стандарта, когда оператор [] определяется текстовым примером через ранее определённые выражения.

Автор: aiwa Aug 4 2018, 08:09

Цитата(GetSmart @ Aug 3 2018, 20:45) *
index1[index2][array_name] и index1[index2][index3][array_name] тоже разрешены? Если да, исходя из каких формулировок?

Согласно 1-му пункту "подписки" это нелегально. Потому что в части выражения "index1[index2]..." один из этих индексов должен быть "pointer..."

Цитата(GetSmart @ Aug 3 2018, 20:45) *
Это по шагам можете объяснить?
Мне понятны варианты когда а[0][24] идентичен a[1][19] и идентичен a[2][14] и т.д. Если не обращать внимание на варнинги компилятора. Но a[24][0] каким образом-то?


Если по шагам, то этот пример я хотел привести намного раньше, когда Вы в ((E1)+(E2)+5) предлагали видеть в 5-ке индекс второй размерности.
Но я ошибочно начал тавтологию про типоразмеры. Но так как мне показалось, что мы толчем воду я его и привел с опозданием.

Вы правы, если продолжить ряд , то должны прийти к правильному решению похожему на a[24][-64].
Или сразу применить формулу, по которой добавляя число к первому индексу, мы должны отнимать это число, умноженное на 5 от второго. 5 и выступает в качестве типоразмера. Имхо, пример хорошо иллюстрирует рекурсивность правила для многомерных массивов.

Цитата(GetSmart @ Aug 3 2018, 20:45) *
То есть разрешение применения [] к любому указателю на непустой тип даёт именно первый абзац главы <6.5.2.1 Array subscripting> ? object type определён как юбой, за исключением void? В стандарте есть суммарный раздел об авто-преобразованиях? Или надо шерстить весь стандарт чтобы откопать однозначность?


Я не знаю стандарт достаточно хорошо. Помню в свое время всем отделом шерстили именно по указанной теме.
Но похоже, что действует принцип: "разрешено все, что не запрещено". Поэтому использование "подписки" для указателя вполне законно.

Только я не уверен, что термин в стандарте эквивалентен нашему пониманию "подписки".

Цитата(GetSmart @ Aug 3 2018, 20:45) *
Ну бред же. Для компилятора имя массива - это lvalue (кратко - объект в памяти). К нему можно применить амперсанд. &имя_массива[0] - это rvalue, к нему (здесь будет второй раз) амперсанд не применим. И для (простейше определённого) многомерного массива array_name[0] есть тоже lvalue.

Ну я условно, для краткости, чтобы не писать присутствующее в каждом посте "pointer to....".

Цитата(GetSmart @ Aug 3 2018, 20:45) *
Пытаясь как-то оправдать логику выдумщика и потом стандарта, когда на начальном этапе массив (array object по терминологии главы 6.5.2.1) казался избыточным и работу с массивами НАДО БЫЛО организовывать через указатели и операторы +-, которым был непринципиален порядок разношёрстных операндов, мне самому любопытно, на какой развилке не туда свернули)))


Но почему Вы считаете, что они свернули не туда? Они реализовали "ассемблерные возможности" на высоком уровне. И это есть хорошо.
И не дай бог они повернут туда: зачем нам третья java, или четвертый шарп?

Автор: XVR Aug 4 2018, 16:33

Пошла 4 страница трёпа вокруг массива/указателя... Ещё 6 страниц и можно ожидать переходы на личности и мерянье пиписьками sm.gif
Пошёл за попкорном salmari.gif

Автор: GetSmart Aug 5 2018, 02:46

Цитата(aiwa @ Aug 4 2018, 12:09) *
Но почему Вы считаете, что они свернули не туда?

Как буд-то родился "кошмар на улице си" index[array]. Не прочитав всю кучу документов точно и не разберёшься.

Полноценный перевод этого мутного термина я не знаю. В каких-то словарях компьютерных терминов его кастрируют до <индексация>. Но в общеупотребительном смысле это слово более многогранное. Со смыслами <одобрить>, <согласиться>. Пока (если лучше версию не увижу), наверное буду считать в Си "признать массивом и индексировать". Но у буржуев есть какой-то схожий термин "superscripting" (superscription-надпись, в общеупотребительном аглицком), которе вместе (теоретически наверно) могут как-то обозначать вариации индексаций "вглубь" (для массивов) или наружу (для указателей). Но с такими тонкостями толкования я пока не пересекался.

Мутность такая же, как при переводе термина bitwise (complement), о котором когда-то спорили.

Автор: aiwa Aug 8 2018, 20:53

Цитата(GetSmart @ Aug 5 2018, 05:46) *
Но у буржуев есть какой-то схожий термин "superscripting" (superscription-надпись, в общеупотребительном аглицком), которе вместе (теоретически наверно) могут как-то обозначать вариации индексаций "вглубь" (для массивов) или наружу (для указателей).

Так буквальный перевод subscript и означает индекс (нижний или верхний).

Автор: Arlleex Aug 9 2018, 04:54

Действительно какая-то пьянка вокруг массива и указателя. Не вижу принципиальной разницы как получать доступ к элементам памяти - через [] или через *(). Если присутствует многомерность памяти, определяю указатель на тип строки такого массива и также адресую - либо индексно, либо *().
Кстати, при объявлении массива можно полностью избавиться от его идентификатора (в C99) и присвоить его адрес указателю.

Автор: Herz Aug 9 2018, 08:20

Цитата(aiwa @ Aug 8 2018, 23:53) *
Так буквальный перевод subscript и означает индекс (нижний или верхний).

Не совсем. Верхний индекс принято называть именно superscript.

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)