|
|
|
Инициализация структуры |
|
|
|
Jul 26 2018, 01:22
|
.
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753
|
Апосля подумалось. Идея смысла текста топикстартера из первого поста интуитивно понятна (= наиболее проста и очевидна: для указателя агрегатного типа допускать ввод сразу данных агрегатного типа). Только если в стандарте (года?) этот способ не указан, то никаких гарантий, что все компиляторы это будут понимать и делать. Строка не в счёт, она не агрегатный тип.
Пустые скобки при объявлении функции без параметров тоже интуитивно понятны. Хотя некоторым компиляторам очень хочется (приказали?) засунуть туда таракана. А интуитивно непонятно, почему структуры копировать присвоением a=b можно, а массивы (хотя бы с константным размером) - нельзя. И там, и там - агрегатный тип и всё казалось бы корректно, но хрен там. И с приоритетами операций там какая-то алогичность. И что-то ещё было, уже не вспомню.
В си оказывается меняли синтаксис. Существует вариант объявления функций по старому стилю, в котором в скобках только имена, а перед открытием стартового блока функции - объявления этих имён с типами. Любопытно, прототип такой же был или тогда ещё не придумали. Наверное тогда и была та самая декларация независимости функции, из-за которой в новом стиле завели себе таракана. Ещё припоминаю как дизассемблил под досом досовские экзешники и в те времена вызыватель функции сам освобождал стек. Узнавая историю, можно откопать причинно-следственные связи кривизны.
Сообщение отредактировал GetSmart - Jul 26 2018, 06:01
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 26 2018, 08:21
|
Гуру
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713
|
Цитата(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) { ... } что я часто и применяю
|
|
|
|
|
Jul 26 2018, 09:16
|
Местный
Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877
|
Цитата(GetSmart @ Jul 26 2018, 04:22) А интуитивно непонятно, почему структуры копировать присвоением a=b можно, а массивы (хотя бы с константным размером) - нельзя. И там, и там - агрегатный тип и всё казалось бы корректно, но хрен там. И с приоритетами операций там какая-то алогичность. И что-то ещё было, уже не вспомню. в с компировать структуры низя, в плюсах можно. думаю в плюсах даже можно скопировать и массив константного размера, лиш бы тип до конца был определен. но массивы зачастую безразмерные, и в процедурах как правило используется переменная не массива, а указатель на элемент массива. точнее переменная массива используется в качестве указателя на элемент массива. поэтому копирование массива вобчето весьма небезопасно, именно потому что попутать легко - где указатель на корень массива, а где на элемент. со структурами все сильно проще и однозначнее.
|
|
|
|
|
Jul 26 2018, 09:16
|
Местный
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682
|
Цитата(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; }
|
|
|
|
|
Jul 26 2018, 10:35
|
Местный
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264
|
Это все известные вещи. Но, как было правильно отмечено выше, указатель и имя массива, хотя и являются похожими, являются принципиально разными объектами.
Сообщение отредактировал Herz - Jul 27 2018, 09:35
Причина редактирования: избыточное цитирование
|
|
|
|
|
Jul 26 2018, 11:03
|
Местный
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264
|
Цитата(AlexRayne @ Jul 26 2018, 13:16) в с компировать структуры низя... Можно. Массивы тоже можно, но на основе структур: Код struct { int data[100]; }Array1, Array 2; ... Array1 = Array2;
|
|
|
|
|
Jul 27 2018, 09:09
|
Местный
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682
|
Цитата(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].
Сообщение отредактировал aiwa - Jul 27 2018, 09:14
|
|
|
|
|
Jul 27 2018, 09:19
|
Гуру
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847
|
Цитата(aiwa @ Jul 27 2018, 12:09) Никакого сюрприза, просто имя массива - является указателем на первый элемент массива. Не является, а автоматически приводится в нужных случаях. Сравните: Код char* pointer; char array[100];
printf("%d/%d\n", sizeof(pointer), sizeof(array)); Если бы 'имя массива - является указателем на первый элемент массива' то мы получили бы 4/4 (предположим что указатель 4х байтоый). А получим мы 4/100 Честно говоря уже не хочется это разжёвывать - мульён раз об этом писалось, и каждый раз получается портянка на десяток страниц заказчивающаяся каким нибудь холиваром
|
|
|
|
|
Jul 28 2018, 15:36
|
.
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753
|
+5 копеек: индексация указателя не контролирует индекс, а индексация (имени) массива будет, при возможности, проверять индекс на допустимый диапазон.
ЗЫ Кстати, index[array] какой-то обкуренный товарищ придумал. Любопытно было бы узнать исторические предпосылки или адекватную логическую аргументацию этого кошмара. (а не тупой отсыл к тексту стандарта, в котором не обязана быть аргументация)
Хотелось бы удостовериться, что все интуитивно непонятные места в Си существуют для обхода (старых и новых) граблей или для увеличения концентрации смысла на еденицу текста. Но с минимизацией ущерба общекомпьютерным категориям и терминам, которыми мыслят и на которых общаются разработчики, например, широкого профиля.
Сообщение отредактировал GetSmart - Jul 28 2018, 17:22
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 28 2018, 16:51
|
Местный
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264
|
Цитата(GetSmart @ Jul 28 2018, 18:36) +5 копеек: индексация указателя не контролирует индекс, а индексация (имени) массива будет, при возможности, проверять индекс на допустимый диапазон.
ЗЫ Кстати, index[array] какой-то обкуренный товарищ придумал. Выход да пределы индексации массива может быть проверен только на этапе компиляции, и то не утвердительно всегда. А фокус с перестановкой имени и индекса следует из того, что перед компиляцией выражение вида a[i] заменяется на *(a + i). Поэтому все логично.
|
|
|
|
|
Jul 28 2018, 17:01
|
.
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753
|
Цитата(Arlleex @ Jul 28 2018, 20:51) А фокус с перестановкой имени и индекса следует из того, что перед компиляцией выражение вида a[i] заменяется на *(a + i). Поэтому все логично. Для начала - спасибо за подсказку. Но не преувеличивайте. То, что кто-то допустим узнал, откуда появился (void) в списке аргументов функции, логичности этому таракану не добавило. Это криво и будет интуитивно непонятно новичкам. А высший пилотаж при разработке языка, в дополнение ко всем достоинствам языка, - когда новичкам без подсказок понятны многие конструкции. Чем меньше им потребуется читать стандарт, хотя бы на начальном этапе, тем качественнее можно оценить работу разработчиков. Уже теплее и теплее ощущается, что "ТЗ от шефа" было (зачем-то?) в усложнении правил разбора текста компилятору. У массивов, видимо, куча правил перемешалась и вылезла пара грыж.
Сообщение отредактировал GetSmart - Jul 28 2018, 17:50
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 29 2018, 00:25
|
Местный
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682
|
Цитата(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".
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|