|
Указатели на строку в С |
|
|
|
Jan 24 2016, 08:04
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
В Си есть два способа определения строки: Код char str[] = "string"; void* p1= str; void* p2=&str; void* p3=&str[0];
printf("%p\n%p\n%p\n",p1,p2,p3);
$ a.out 0xbfaa14c5 0xbfaa14c5 0xbfaa14c5
char* str = "string"; void* p1= str; void* p2=&str; void* p3=&str[0];
printf("%p\n%p\n%p\n",p1,p2,p3);
$ a.out 0x80488bc 0xbfc25c78 0x80488bc В первом случае p1 равен p2. Почему так?
|
|
|
|
|
 |
Ответов
|
Jan 24 2016, 17:28
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 24 2016, 17:55)  Если речь идет о записи "строковый литерал"[индекс], то да - это чистый, как слеза Си. Строковый литерал неявно приводится к указателю на char const, а для указателя определены индексные операции, которые есть адресная арифметика. Отсюда в чистом как слеза Си возможно и такая запись: i["abcdef"]. Конец цитаты точно верный? В индексировании строки будет аж два подряд неявных преобразования. На этом стандарт должен акцентировать внимание. Сперва строка создаст lvalue и значение превратится в указатель, а потом указатель должен неявно превратиться переменную, к которой применим индекс. Т.к. такое выражение полнейшая экзотика, то какие-то компиляторописатели могли бы встать на грабли, если в стандарте нет подсказки. Т.к. неявное преобразование строки происходит в указатель на char, то таки одно неявное преобразование. Индексирование указателя на массив и указателя на другой не пустой тип происходит по-разному. Опять в свой огород закинул.
Сообщение отредактировал GetSmart - Jan 25 2016, 04:22
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 24 2016, 18:45
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 24 2016, 19:28)  Конец цитаты точно верный? Точно. Зуб даю. Ну слегка опечатался: должно было быть "возможна". Цитата(GetSmart @ Jan 24 2016, 19:28)  а потом указатель должен неявно превратиться переменную, к которой применим индекс. Откройте стандарт и почитайте, что делает оператор индекса. Стандарт легко гуглится. Цитата 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))). От перемены мест слагаемых сумма не меняется.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 03:21
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 24 2016, 22:45)  От перемены мест слагаемых сумма не меняется. По поводу выделенного в цитате. Если бы там вместо definition было "действие", то всё было бы корректно к асимметрии взятия элемента массива. Т.к. в предыдущем предложении она обозначена и наследуется следующим предложением. В таком виде как написано толковать его можно как допускающее перемену мест двух выражений у оператора [], если в описании оператора "+" не указана явно зависимость результата от перестановки слагаемых обсуждаемых типов. (насколько это определение старое? в нете коментарии о New C standard) Касательно семантики идеального Си, без всяких плюшек и перегрузок Си++. В сложении чисел перемена мест слагаемых унаследована из математики. Т.к. к указателю удобно применять сложение, то разрешив его логично и наследование правила перемены мест слагаемых, если какого-то альтернативного результата не может быть, например из-за (гипотетических) неявных преобразований указателя в число (или адрес или содержимое памяти) когда по соседству у него "третьим" (первые два - число и указатель) будет оператор или операнд, требующий данное неявное преобразование. У понятия взятия элемента массива обычно две составные части выражения исходно разнотипные и это действие семантически несимметричное. Например, как in в Паскале. Оснований делать его симметричным в Си не обозначено, а усложнение читабельности и искажение понятия налицо. Здесь асиметрия сильно увеличивает безопасность. В том же стандарте Си наверняка в разделе объявлений переменных (конкретно массивов) указано (например неявно), что нет никакой симметрии и имя массива всегда вне []. Без наличия оснований ввода в стандарт симметрии операндов оператора [] в разделе statement, стандарт будет кривым. Прямо в Си-стандарте, а не в стандарте "соседнего" языка.
Сообщение отредактировал GetSmart - Jan 25 2016, 07:53
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 07:43
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 05:21)  По поводу выделенного в цитате. Если бы там вместо definition было "действие", definition = определение. То есть операция [] определяется и работает именно так, только так и никак иначе. Цитата(GetSmart @ Jan 25 2016, 05:21)  если какого-то альтернативного результата не может быть, например из-за (гипотетических) неявных преобразований указателя в число Не надо гипотез. В стандарте все описано. И неявные преобразования, и коммуникативность сложения. Операция разыменования указателя ('*') определена только для указателей, значит результатом суммы должен быть указатель. Сумма дает указатель только если одно из слагаемых указатель, а второе - целое число. Порядок слагаемых не важен. Все описано и ничего выдумывать не нужно. Цитата 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). И массив не нужен, нужен указатель. Цитата(GetSmart @ Jan 25 2016, 05:21)  У понятия взятия элемента массива Нет такого понятия. Есть доступ по индексу. Цитата(GetSmart @ Jan 25 2016, 05:21)  В том же стандарте Си наверняка в разделе объявлений переменных (конкретно массивов) указано (например неявно), что нет никакой симметрии и имя массива всегда вне []. Во-первых давайте без "наверняка". Найдите и покажите. Я за вас искать не буду. "Чтение документации из интернета вслух - 100 евро в час". Во-вторых, объявление массива и операция доступа по индексу - совершенно разные и никак не связанные между собой вещи. На этом заканчиваю. Не имею желания опровергать ваши фантазии. Читайте стандарт самостоятельно, там есть ответы на все ваши вопросы. Цитата(GetSmart @ Jan 25 2016, 05:21)  Прямо в Си-стандарте, а не в стандарте "соседнего" языка. Это вообще к чему?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 07:56
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 11:43)  definition = определение. То есть операция [] определяется и работает именно так, только так и никак иначе. Я так и понял. Весь остальной мой абзац корректен. Цитата(Сергей Борщ @ Jan 25 2016, 11:43)  Это вообще к чему? Предполагал некоторую связь с Си++. Например термин subscript не очень ясен. Слабо похож на русский "взятие элемента массива" или даже "индексирование". Обобщая правила в Си, относящиеся к агрегатным типам, всегда операция взятия субэлемента сложного типа является асимметричной к типу операндов. Плюсование/минусование указателя удобно в языке, но происходит в особом порядке. Компилятор этот случай детектит специально. В этом случае у операций +/- могла быть разрешена симметрия, по желанию разработчиков, из-за симметрии с числовыми операндами. Но можно было бы и жёстко задать: указатель слева, числа справа.
Сообщение отредактировал GetSmart - Jan 25 2016, 08:11
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 08:08
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 09:56)  Предполагал некоторую связь с Си++. В заголовке темы явно указан Си. Далее, вы сами писали о "чистом как слеза Си" и я вам отвечал именно о нем же, даже специально дважды повторил предлженное вами название. Цитата(GetSmart @ Jan 25 2016, 09:56)  Например термин subscript не очень ясен. translate.google.com, технические словари вам в помощь. Цитата(GetSmart @ Jan 25 2016, 09:56)  Обобщая правила в Си, Которых вы не читали. Выше добавил в сообщение еще одну цитату из стандарта.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 08:16
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 12:08)  Которых вы не читали. Выше добавил в сообщение еще одну цитату из стандарта. Тут хитрость в том, что я не знаю в совершенстве аглицкий. Читать весь стандарт нет смысла. По конкретной теме обсуждения аргументирую конструктивно. Возразите, если есть чем. По поводу нарушения аналогий отношения к агрегатным типам. Гугл-транслейт может завести в такие дебри, что пожалеешь, что запустил  Пользуюсь бумажным словарём. Хорошим и толстым.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 08:54
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 10:16)  По конкретной теме обсуждения аргументирую конструктивно. "возможно", "наверняка", "предполагал" - очень конструктивно, ага. Цитата(GetSmart @ Jan 25 2016, 10:16)  Читать весь стандарт нет смысла Поиск по тексту работает. Цитата(GetSmart @ Jan 25 2016, 10:16)  Возразите, если есть чем. Ага, то есть языка не знаете вы, а возражать должен я? Нет уж, спасибо.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 10:01
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 12:54)  "возможно", "наверняка", "предполагал" - очень конструктивно, ага. Цитата(Сергей Борщ @ Jan 25 2016, 11:43)  Нет такого понятия. Есть доступ по индексу. То есть понятие массива есть. Понятие элемента массива тоже есть. А понятие взятия элемента - нет  Оно есть даже если о нём прямо не говорится в стандарте. Оно может быть объединено/обобщено в новый термин, если он описывает более общий оператор. Этот оператор, кстати, на массивы, указатели на массив и указатели на другой непустой тип действует по-разному. И при таком раскладе обобщённый термин может ввести в заблуждение, рассуждая и корректности терминологии вообще. Цитата 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". Если так, то это выражение не относится к взятию элемента массива. И не относится к взятию элемента по индексу, применённому к указателю на не массив.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 10:34
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 12:01)  "Пост-выражение, идущее после выражения в квадратных скобках есть" Постфиксное выражение, за которым следует выражение в квадратных скобках, является индексным обращением к элементу массива. "Обращением к элементу", а не "взятием элемента". Код 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));
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 10:50
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 14:34)  Постфиксное выражение, за которым следует выражение в квадратных скобках, является индексным обращением к элементу массива. Постфиксным выражением не может быть имя главного объекта, которое указывается первым левым идентификатором/именем. Можно контр-пример? Цитата(Сергей Борщ @ Jan 25 2016, 14:34)  "Обращением к элементу", а не "взятием элемента". Напомнило "побочное действие присваивания есть присваивание". В чём разница? В употреблённых мной контекстах. Если напишу так "Обобщая правила в Си, относящиеся к агрегатным типам, всегда операция обращения к его субэлементу является асимметричной к типу операндов." Это понятие обобщает как минимум два более конкретных понятия: взятие адреса элемента и взятие содержимого элемента. Но в каких-то контекстах это обобщение корректно. Цитата Во-вторых, объявление массива и операция доступа по индексу - совершенно разные и никак не связанные между собой вещи. Это утверждение неверно. В обоих случаях есть (будет) объект массив и число (размер или индекс). Оба ключевых признака в тексте на месте. И их позиции относительно оператора [] должны быть одинаковы, если нет весомых оснований отходить от этого. Та выделенная формулировка в цитате необоснованно навязывает допустимости варианта "индекс наизнанку" с аналогией со сложением, хотя сложение с указателем есть особый случай сложения. Если это желание разработчика, то это его личное дело. А если есть глубокие причины такого навязывания, то они должны были быть обозначены.
Сообщение отредактировал GetSmart - Jan 25 2016, 22:53
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 11:47
|

Местный
  
Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502

|
Цитата(GetSmart @ Jan 25 2016, 10:50)  Постфиксным выражением не может быть имя главного объекта, которое указывается первым левым идентификатором/именем. Ах! Поэзия! Посильнее "Фауста" Гете будет ! А вот что скажут теоретики программирования, пока, правда, не освоившие стандарт языка Ц на такое использование массивов ? CODE static char Foo1(uint32 aIdx) { return "abcdefghijkl"[aIdx]; }
static char Foo2(uint32 aIdx) { return aIdx["abcdefghijkl"]; }
... Это вам не про монадические типы рассуждать...
|
|
|
|
|
Jan 25 2016, 13:53
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(CrimsonPig @ Jan 25 2016, 15:47)  Ах! Поэзия! Посильнее "Фауста" Гете будет ! Писал вспешке под тот контекст. Уточняю. Обсуждаемый язык разбирает выражения слева направо. Постфиксным выражением не может быть первое левое lvalue. Если встречается непостфиксный оператор, то за ним (справо) первое lvalue снова считается главным объектом, который не входит в постфиксное выражение. Т.к. выражения не обязаны быть в виде присваивания, то допустимы оба варианта x = Array[index]; Array[index]; И классификация субэлементов выражения Array[index] в этих двух вариантах не должна отличаться. Упд Правило написано для области (места, позиции в тексте) исполняемого кода. В т.ч. в области деклараций при задании начального значения lvalue. В первой части объявления lvalue в декларациях, до задания значения, могут быть нюансы и. какие там основы в принятой терминологии не ясно.
Сообщение отредактировал GetSmart - Jan 25 2016, 23:49
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
Сообщений в этой теме
psL Указатели на строку в С Jan 24 2016, 08:04 amaora В первом случае нет переменных хранящих адрес масс... Jan 24 2016, 10:17 zltigo QUOTE (amaora @ Jan 24 2016, 12:17) В пер... Jan 24 2016, 10:35 Сергей Борщ Цитата(psL @ Jan 24 2016, 10:04) В Си ест... Jan 24 2016, 10:32 psL Цитата(Сергей Борщ @ Jan 24 2016, 13:32) ... Jan 24 2016, 11:26  zltigo QUOTE (psL @ Jan 24 2016, 13:26) Почему у... Jan 24 2016, 11:34   psL Цитата(zltigo @ Jan 24 2016, 14:34) В это... Jan 24 2016, 11:42  SSerge Цитата(psL @ Jan 24 2016, 18:26) чем отли... Jan 24 2016, 11:36  amaora Цитата(psL @ Jan 24 2016, 14:26) разве им... Jan 24 2016, 12:13 _Ivan_33 а почему 2?
а строковый литерал типа
#define MSG ... Jan 24 2016, 11:10 zltigo QUOTE (psL @ Jan 24 2016, 13:42) *
Без K&R обь... Jan 24 2016, 11:51 psL Цитата(zltigo @ Jan 24 2016, 14:51) Все т... Jan 24 2016, 12:46  gerber Цитата(psL @ Jan 24 2016, 15:46) Можете к... Jan 24 2016, 13:03 GetSmart Wow!
Индекс разрешили применять к rvalue?
Цит... Jan 24 2016, 12:54 Сергей Борщ Цитата(GetSmart @ Jan 24 2016, 14:54) Как... Jan 24 2016, 13:11 zltigo QUOTE (GetSmart @ Jan 24 2016, 15:17) То ... Jan 24 2016, 13:51  GetSmart Цитата(zltigo @ Jan 24 2016, 17:51) Смотр... Jan 24 2016, 14:05   krux Цитата(GetSmart @ Jan 24 2016, 17:05) Кла... Jan 24 2016, 14:20              Сергей Борщ Цитата(CrimsonPig @ Jan 25 2016, 13:47) А... Jan 25 2016, 12:21               GetSmart Цитата(Сергей Борщ @ Jan 25 2016, 16:21) ... Jan 25 2016, 12:40               GetSmart Цитата(Сергей Борщ @ Jan 25 2016, 16:21) ... Jan 25 2016, 13:08 gerber "ABCD" не является rvalue, строго говоря... Jan 24 2016, 14:16 GetSmart Цитата(gerber @ Jan 24 2016, 18:16) ... Jan 24 2016, 14:22  krux Цитата(GetSmart @ Jan 24 2016, 17:22) Цит... Jan 24 2016, 14:23  Сергей Борщ Цитата(GetSmart @ Jan 24 2016, 16:05) В с... Jan 24 2016, 14:43   GetSmart ЦитатаЭто как?
foo2( "ABCD" + "XYZ... Jan 24 2016, 15:02    zltigo QUOTE (GetSmart @ Jan 24 2016, 17:02) foo... Jan 24 2016, 15:24    Сергей Борщ Цитата(GetSmart @ Jan 24 2016, 17:02) foo... Jan 24 2016, 15:28 GetSmart Дополнил конец пред поста. Jan 24 2016, 14:27 krux Цитата(GetSmart @ Jan 24 2016, 17:22) Воо... Jan 24 2016, 14:38 GetSmart Если строки складываются без плюса, то я не сильно... Jan 24 2016, 15:30 zltigo QUOTE (GetSmart @ Jan 24 2016, 17:30) Есл... Jan 24 2016, 15:42 GetSmart Тогда есть отличия с взятием адреса массива через ... Jan 24 2016, 15:55 SSerge Кабы авторы языка С в своё время были так же искус... Jan 25 2016, 08:01 GetSmart Нашёл такую формулировку
ЦитатаA postfix expressio... Jan 25 2016, 12:19 Сергей Борщ Цитата(GetSmart @ Jan 25 2016, 14:19) В э... Jan 25 2016, 12:46  GetSmart Цитата(Сергей Борщ @ Jan 25 2016, 16:46) ... Jan 25 2016, 22:19   Сергей Борщ Цитата(GetSmart @ Jan 26 2016, 00:19) Пиш... Jan 25 2016, 23:06   zltigo QUOTE (GetSmart @ Jan 26 2016, 00:19) Я н... Jan 26 2016, 07:30    GetSmart Цитата(zltigo @ Jan 26 2016, 11:30) Как р... Jan 26 2016, 11:53 zltigo QUOTE (GetSmart @ Jan 25 2016, 14:19) Клю... Jan 25 2016, 13:15  gerber Цитата(zltigo @ Jan 25 2016, 16:15) 1) Я ... Jan 25 2016, 13:19   zltigo QUOTE (gerber @ Jan 25 2016, 15:19) И как... Jan 25 2016, 13:20    gerber Цитата(zltigo @ Jan 25 2016, 16:20) Как и... Jan 25 2016, 13:23     zltigo QUOTE (gerber @ Jan 25 2016, 15:23) Хм ..... Jan 25 2016, 13:27      gerber Цитата(zltigo @ Jan 25 2016, 16:27) Но во... Jan 25 2016, 15:02       zltigo QUOTE (gerber @ Jan 25 2016, 17:02) Как п... Jan 25 2016, 15:39  GetSmart Цитата(zltigo @ Jan 25 2016, 17:15) Это ф... Jan 25 2016, 13:19 gerber Стандарт стандартом, но за работу с элементами мас... Jan 25 2016, 13:12 GetSmart Цитата(Сергей Борщ @ Jan 26 2016, 03:06) ... Jan 25 2016, 23:46 Сергей Борщ Цитата(GetSmart @ Jan 26 2016, 01:46) С к... Jan 26 2016, 00:31  GetSmart Цитата(Сергей Борщ @ Jan 26 2016, 04:31) ... Jan 26 2016, 00:39   Сергей Борщ Цитата(GetSmart @ Jan 26 2016, 02:39) Нап... Jan 26 2016, 08:41 sigmaN Честно прочитал все сообщения. Так и не понял поче... Jan 26 2016, 16:30 Serg76 Цитата(sigmaN @ Jan 26 2016, 19:30) Вроде... Jan 26 2016, 21:16 smalcom Welcome to electronix )) Jan 26 2016, 20:05 GetSmart ЦитатаAn operator is called a Postfix Operator whe... Feb 5 2016, 20:41 sigmaN ЦитатаЕсли ерунда содержится в какой-то части стан... Feb 6 2016, 10:51 krux GetSmart
пока ваш 'компилятор' не может со... Feb 8 2016, 19:06 ar__systems Это тему больно читать....
А когда вы работать ус... Feb 9 2016, 14:24
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|