Jump to content

    
Sign in to follow this  
psL

Указатели на строку в С

Recommended Posts

Если строки складываются без плюса, то я не сильно ошибся.

Да они вообще не складываются. Это строку так допустимо записывать.

 

Share this post


Link to post
Share on other sites

Тогда есть отличия с взятием адреса массива через амперсанд и взятием адреса строки. Имя массива амперсанд неявно не преобразует к адресу первого элемента, а к строке амперсанд делает неявное преобразование и создаёт или находит уже готовое lvalue, от которого и берёт адрес. Причём взятие адреса массива мне кажется естественным и явно аналогично взятию адреса любой переменной. А вот амперсанд со строкой до сих пор не видел в текстах, которые читал.

 

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

Признаю ошибку. Строка (в кавычках) в Си не есть обычное rvalue. Паскаль меня попутал.

Я копал не столько стандарт, сколько конфликты и обоснованность семантики. Тема реально похожа на разбор семантики слов и предложений обычного языка.

 

--------------

Видел где-то объявление массивов в аргументах функций при их вызове. Всё ли там чисто.

Edited by GetSmart

Share this post


Link to post
Share on other sites
Если речь идет о записи "строковый литерал"[индекс], то да - это чистый, как слеза Си. Строковый литерал неявно приводится к указателю на char const, а для указателя определены индексные операции, которые есть адресная арифметика. Отсюда в чистом как слеза Си возможно и такая запись: i["abcdef"].

Конец цитаты точно верный?

 

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

 

Т.к. неявное преобразование строки происходит в указатель на char, то таки одно неявное преобразование. Индексирование указателя на массив и указателя на другой не пустой тип происходит по-разному. Опять в свой огород закинул.

Edited by GetSmart

Share this post


Link to post
Share on other sites
Конец цитаты точно верный?
Точно. Зуб даю. Ну слегка опечатался: должно было быть "возможна".

 

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

 

A postfix expression followed by an expression in square brackets [] is a subscripted

designation of an element of an array object. The definition of the subscript operator []

is that E1[E2] is identical to (*((E1)+(E2))).

От перемены мест слагаемых сумма не меняется.

Share this post


Link to post
Share on other sites
От перемены мест слагаемых сумма не меняется.

По поводу выделенного в цитате. Если бы там вместо definition было "действие", то всё было бы корректно к асимметрии взятия элемента массива. Т.к. в предыдущем предложении она обозначена и наследуется следующим предложением. В таком виде как написано толковать его можно как допускающее перемену мест двух выражений у оператора [], если в описании оператора "+" не указана явно зависимость результата от перестановки слагаемых обсуждаемых типов. (насколько это определение старое? в нете коментарии о New C standard)

 

Касательно семантики идеального Си, без всяких плюшек и перегрузок Си++.

 

В сложении чисел перемена мест слагаемых унаследована из математики. Т.к. к указателю удобно применять сложение, то разрешив его логично и наследование правила перемены мест слагаемых, если какого-то альтернативного результата не может быть, например из-за (гипотетических) неявных преобразований указателя в число (или адрес или содержимое памяти) когда по соседству у него "третьим" (первые два - число и указатель) будет оператор или операнд, требующий данное неявное преобразование. У понятия взятия элемента массива обычно две составные части выражения исходно разнотипные и это действие семантически несимметричное. Например, как in в Паскале. Оснований делать его симметричным в Си не обозначено, а усложнение читабельности и искажение понятия налицо. Здесь асиметрия сильно увеличивает безопасность. В том же стандарте Си наверняка в разделе объявлений переменных (конкретно массивов) указано (например неявно), что нет никакой симметрии и имя массива всегда вне []. Без наличия оснований ввода в стандарт симметрии операндов оператора [] в разделе statement, стандарт будет кривым. Прямо в Си-стандарте, а не в стандарте "соседнего" языка.

Edited by GetSmart

Share this post


Link to post
Share on other sites
По поводу выделенного в цитате. Если бы там вместо definition было "действие",
definition = определение. То есть операция [] определяется и работает именно так, только так и никак иначе.

 

если какого-то альтернативного результата не может быть, например из-за (гипотетических) неявных преобразований указателя в число
Не надо гипотез. В стандарте все описано. И неявные преобразования, и коммуникативность сложения. Операция разыменования указателя ('*') определена только для указателей, значит результатом суммы должен быть указатель. Сумма дает указатель только если одно из слагаемых указатель, а второе - целое число. Порядок слагаемых не важен. Все описано и ничего выдумывать не нужно.

One of the expressions shall have type ‘‘pointer to object type’’, the other expression shall have integer type, and the result has type ‘‘type’’.
Все. "одно из выражений" и "другое выражение". Где из них какое - не сказано и значения не имеет, что следует из отцитированного выше определения (definition). И массив не нужен, нужен указатель.

 

У понятия взятия элемента массива
Нет такого понятия. Есть доступ по индексу.

В том же стандарте Си наверняка в разделе объявлений переменных (конкретно массивов) указано (например неявно), что нет никакой симметрии и имя массива всегда вне [].
Во-первых давайте без "наверняка". Найдите и покажите. Я за вас искать не буду. "Чтение документации из интернета вслух - 100 евро в час". Во-вторых, объявление массива и операция доступа по индексу - совершенно разные и никак не связанные между собой вещи.

 

На этом заканчиваю. Не имею желания опровергать ваши фантазии. Читайте стандарт самостоятельно, там есть ответы на все ваши вопросы.

 

Прямо в Си-стандарте, а не в стандарте "соседнего" языка.
Это вообще к чему?

Share this post


Link to post
Share on other sites
definition = определение. То есть операция [] определяется и работает именно так, только так и никак иначе.

Я так и понял. Весь остальной мой абзац корректен.

 

Это вообще к чему?

Предполагал некоторую связь с Си++. Например термин subscript не очень ясен. Слабо похож на русский "взятие элемента массива" или даже "индексирование".

 

Обобщая правила в Си, относящиеся к агрегатным типам, всегда операция взятия субэлемента сложного типа является асимметричной к типу операндов.

 

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

Edited by GetSmart

Share this post


Link to post
Share on other sites

Кабы авторы языка С в своё время были так же искусны во всех этих теориях то у них получился бы ещё один PL/1.

А так "маємо, що маємо".

Share this post


Link to post
Share on other sites
Предполагал некоторую связь с Си++.
В заголовке темы явно указан Си. Далее, вы сами писали о "чистом как слеза Си" и я вам отвечал именно о нем же, даже специально дважды повторил предлженное вами название.

Например термин subscript не очень ясен.
translate.google.com, технические словари вам в помощь.

 

Обобщая правила в Си,
Которых вы не читали. Выше добавил в сообщение еще одну цитату из стандарта.

Share this post


Link to post
Share on other sites
Которых вы не читали. Выше добавил в сообщение еще одну цитату из стандарта.

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

 

Гугл-транслейт может завести в такие дебри, что пожалеешь, что запустил :) Пользуюсь бумажным словарём. Хорошим и толстым.

Share this post


Link to post
Share on other sites
По конкретной теме обсуждения аргументирую конструктивно.
"возможно", "наверняка", "предполагал" - очень конструктивно, ага.

Читать весь стандарт нет смысла
Поиск по тексту работает.

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

 

Share this post


Link to post
Share on other sites
"возможно", "наверняка", "предполагал" - очень конструктивно, ага.

Нет такого понятия. Есть доступ по индексу.

То есть понятие массива есть. Понятие элемента массива тоже есть. А понятие взятия элемента - нет :)

Оно есть даже если о нём прямо не говорится в стандарте. Оно может быть объединено/обобщено в новый термин, если он описывает более общий оператор. Этот оператор, кстати, на массивы, указатели на массив и указатели на другой непустой тип действует по-разному. И при таком раскладе обобщённый термин может ввести в заблуждение, рассуждая и корректности терминологии вообще.

 

A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object.

Что-то здесь не так.

"Пост-выражение, идущее после выражения в квадратных скобках есть (термин - непонятные два слова) элемента массива".

Не видел такой конструкции в текстах.

 

Вряд ли автор хотел сказать, что "in square brackets" должно относиться к "postfix expression".

Если так, то это выражение не относится к взятию элемента массива. И не относится к взятию элемента по индексу, применённому к указателю на не массив.

Share this post


Link to post
Share on other sites
"Пост-выражение, идущее после выражения в квадратных скобках есть"
Постфиксное выражение, за которым следует выражение в квадратных скобках, является индексным обращением к элементу массива. "Обращением к элементу", а не "взятием элемента".

 

char Array[] = "abcdef';
char * Pointer = Array;
int Index = 5;

// все эти выражения эквивалентны
display(Array[Index]);     // неявное преобразование Array к (char *)&Array[0]
display(Pointer[Index]);
display(Index[Pointer]);
display(*(Index + Pointer));
display(*(pointer + Index));

Share this post


Link to post
Share on other sites
Постфиксное выражение, за которым следует выражение в квадратных скобках, является индексным обращением к элементу массива.

Постфиксным выражением не может быть имя главного объекта, которое указывается первым левым идентификатором/именем. Можно контр-пример?

 

"Обращением к элементу", а не "взятием элемента".

Напомнило "побочное действие присваивания есть присваивание".

В чём разница? В употреблённых мной контекстах. Если напишу так "Обобщая правила в Си, относящиеся к агрегатным типам, всегда операция обращения к его субэлементу является асимметричной к типу операндов."

 

Это понятие обобщает как минимум два более конкретных понятия: взятие адреса элемента и взятие содержимого элемента. Но в каких-то контекстах это обобщение корректно.

 

Во-вторых, объявление массива и операция доступа по индексу - совершенно разные и никак не связанные между собой вещи.

Это утверждение неверно. В обоих случаях есть (будет) объект массив и число (размер или индекс). Оба ключевых признака в тексте на месте. И их позиции относительно оператора [] должны быть одинаковы, если нет весомых оснований отходить от этого. Та выделенная формулировка в цитате необоснованно навязывает допустимости варианта "индекс наизнанку" с аналогией со сложением, хотя сложение с указателем есть особый случай сложения. Если это желание разработчика, то это его личное дело. А если есть глубокие причины такого навязывания, то они должны были быть обозначены.

Edited by GetSmart

Share this post


Link to post
Share on other sites
Постфиксным выражением не может быть имя главного объекта, которое указывается первым левым идентификатором/именем.

 

Ах! Поэзия! Посильнее "Фауста" Гете будет !

 

А вот что скажут теоретики программирования, пока, правда, не освоившие стандарт языка Ц на такое использование массивов ?

 

static char Foo1(uint32 aIdx)
{
   return "abcdefghijkl"[aIdx];
}

static char Foo2(uint32 aIdx)
{
   return aIdx["abcdefghijkl"];
}

 

... Это вам не про монадические типы рассуждать... :)

 

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this